lib/triangle.rb in gmath3D-0.2.0 vs lib/triangle.rb in gmath3D-0.2.1
- old
+ new
@@ -121,20 +121,28 @@
b[2] = 1.0 - b[0] - b[1];
return b;
end
# [Input]
- # _target_ shold be Vector3.
+ # _target_ shold be Vector3 or Line or Plane.
# [Output]
- # return "distance, point on triangle" as [Numeric, Vector3].
+ # [In case _target_ is Vector3]
+ # return "distance, point on triangle" as [Numeric, Vector3].
+ # [In case _target_ is Line]
+ # return "distance, point on tirangle, point on line, parameter on line" as [Numeric, Vector3, Vector3, Numeric].
+ # [In case _target_ is Plane]
+ # return "distance, intersect_line(or closet edge), point_on_triangle, point_on_plane" as [Numeric, Vector3, Vector3, Vector3].
def distance(target)
# with Point
if(target.kind_of?(Vector3))
return distance_to_point(target)
elsif(target.kind_of?(Line))
- #with Line
-# return distance_to_line(target)
+ #with Line
+ return distance_to_line(target)
+ elsif(target.kind_of?(Plane))
+ #with Plane
+ return distance_to_plane(target)
end
Util.raise_argurment_error(target)
end
# [Input]
@@ -162,8 +170,69 @@
end
#check distance to FiniteLines
finite_lines = self.edges
return FiniteLine.ary_distanc_to_point(finite_lines, target_point)
end
+
+ def distance_to_line(target_line)
+ plane = Plane.new( vertices[0], self.normal )
+ distance, point_on_plane, parameter_on_line = plane.distance( target_line )
+ if( point_on_plane == nil)
+ # parallel case
+ # check distance to FiniteLines
+ finite_lines = self.edges
+ distance, point_on_edge, point_on_target, param_on_finiteline, param_on_target =
+ FiniteLine.ary_distance_to_line(finite_lines, target_line)
+ return distance, nil, nil, nil
+ end
+ if( self.contains?(point_on_plane) )
+ return distance, point_on_plane, point_on_plane, parameter_on_line
+ end
+ # check distance to FiniteLines
+ finite_lines = self.edges
+ distance, point_on_edge, point_on_target, param_on_finiteline, param_on_target =
+ FiniteLine.ary_distance_to_line(finite_lines, target_line)
+ return distance, point_on_edge, point_on_target, param_on_target
+ end
+
+ def distance_to_plane(target_plane)
+ triangle_plane = Plane.new( vertices[0], self.normal )
+ distance, intersect_line_each_plane = triangle_plane.distance( target_plane )
+ if( intersect_line_each_plane == nil )
+ return distance, nil, nil, nil
+ end
+
+ # check distance from intersection and each edge.
+ distance_zero_count = 0
+ distance_info = Array.new(0)
+ prallel_edge_ary = Array.new(0)
+ self.edges.each do |edge|
+ distance, point_on_edge, point_on_line = edge.distance( intersect_line_each_plane)
+ if point_on_edge != nil && point_on_line != nil
+ distance_info.push([distance, point_on_edge, point_on_line])
+ if distance <= self.tolerance
+ distance_zero_count += 1
+ end
+ else
+ prallel_edge_ary.push( edge )
+ end
+ end
+ distance_info.sort!{|a,b| a[0] <=> b[0]}
+ # distance, intersect_line(or closet edge), point_on_triangle, point_on_plan
+ if (distance_zero_count == 2)
+ point1 = distance_info[0][1]
+ point2 = distance_info[1][1]
+ if point1.distance(point2) > self.tolerance
+ return 0.0, FiniteLine.new(point1, point2), nil, nil
+ end
+ return 0.0, nil, point1, point1
+ elsif (distance_zero_count == 0)
+ distance, closest_point_on_plane = target_plane.distance(distance_info[0][1])
+ if(distance_info[0][1] != distance_info[1][1])
+ return distance, FiniteLine.new(distance_info[0][1], distance_info[1][1]), nil, nil
+ end
+ return distance, nil, distance_info[0][1], closest_point_on_plane
+ end
+ return 0.0, nil, nil, nil
+ end
end
end
-