Module: TT::Point3d

Defined in:
TT_Lib2/point3d.rb

Overview

Collection of Point3d methods.

Since:

  • 2.0.0

Class Method Summary collapse

Class Method Details

.between?(a, b, c, on_point = true) ⇒ Boolean

Checks if point c is between point a and b.

Return true if c is on a or b.

Parameters:

  • a (Geom::Point3d)
  • b (Geom::Point3d)
  • c (Geom::Point3d)
  • on_point (Geom::Point3d) (defaults to: true)
    • When true, if point c is at the same

    position as a or b it is considered to be in between.

Returns:

  • (Boolean)

Since:

  • 2.0.0



28
29
30
31
32
33
34
35
36
37
38
# File 'TT_Lib2/point3d.rb', line 28

def self.between?(a, b, c, on_point = true)
  return false unless c.on_line?([a,b])
  v1 = c.vector_to(a)
  v2 = c.vector_to(b)
  if on_point
    return true  if !v1.valid? || !v2.valid?
  else
    return false if !v1.valid? || !v2.valid?
  end
  !v1.samedirection?(v2)
end

.douglas_peucker(points, epsilon) ⇒ Array<Geom::Point3d>

Parameters:

  • points (Array<Geom::Point3d>)

    Point set to be simplified. No Loop!

  • epsilon (Length)

    Maximin deviance from original curve.

Returns:

  • (Array<Geom::Point3d>)

Since:

  • 2.5.0



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'TT_Lib2/point3d.rb', line 51

def self.douglas_peucker(points, epsilon)
  return points if points.length < 3
  # Find the point with the maximum distance
  dmax = 0
  index = 0
  line = [points.first, points.last]
  1.upto(points.length - 2) { |i|
    d = points[i].distance_to_line(line)
    if d > dmax
      index = i
      dmax = d
    end
  }
  # If max distance is greater than epsilon, recursively simplify
  result = []
  if dmax >= epsilon
    # Recursive call
    recResults1 = self.douglas_peucker(points[0..index], epsilon)
    recResults2 = self.douglas_peucker(points[index...points.length], epsilon)
    # Build the result list
    result = recResults1[0...-1] + recResults2
  else
    result = [points.first, points.last]
  end
  return result
end

.extend_all(points) ⇒ Array<TT::Point3d_Ex>

Extends all the points (Geom::Point3d and Array in points) with the TT::Point3d_Ex mix-in module.

All Array objects that represent a 3d point will be converted into Geom::Point3d before being extended.

Parameters:

  • points (Array<Geom::Point3d>)

Returns:

  • (Array<TT::Point3d_Ex>)

    Geom::Point3d objects extended by TT::Point3d_Ex

Since:

  • 2.5.0



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'TT_Lib2/point3d.rb', line 89

def self.extend_all( points )
  extended_points = []
  for point in points
    if point.is_a?( Geom::Point3d )
      point_ex = point
    elsif point.is_a?( Array )
      next unless point.size == 3 && point.all? { |n| n.is_a?( Numeric ) }
      point_ex = Geom::Point3d.new( point.x, point.y, point.z )
    elsif point.respond_to?( :position )
      position = point.position
      point_ex = position if position.is_a?( Geom::Point3d )
    end
    point_ex.extend( TT::Point3d_Ex ) unless point_ex.is_a?( TT::Point3d_Ex )
    extended_points << point_ex
  end
  extended_points
end

.simplify_curve(points, epsilon) ⇒ Array<Geom::Point3d>

Wrapper of the Douglas-Peucker algorithm. Handles looping curves.

Parameters:

  • points (Array<Geom::Point3d>)

    Point set to be simplified. No Loop!

  • epsilon (Length)

    Maximin deviance from original curve.

Returns:

  • (Array<Geom::Point3d>)

Since:

  • 2.5.0



115
116
117
118
119
120
121
122
123
# File 'TT_Lib2/point3d.rb', line 115

def self.simplify_curve(points, epsilon)
  if points.first == points.last # Detect loop
    points.pop
    simplified_curve = self.douglas_peucker(points, epsilon)
    simplified_curve << points.first
  else
    simplified_curve = self.douglas_peucker(points, epsilon)
  end
end