class GMath3D::FiniteLine

FiniteLine represents a finite line on 3D space.

Attributes

end_point[RW]
start_point[RW]

Public Class Methods

ary_distanc_to_point(finite_lines, target_point) click to toggle source
# File lib/finite_line.rb, line 111
def self.ary_distanc_to_point(finite_lines, target_point)
  Util3D.check_arg_type(::Array, finite_lines)
  Util3D.check_arg_type(Vector3, target_point)
  distance_ary = Array.new(0)
  points_ary   = Array.new(0)
  finite_lines.each do | item |
    distance, point = item.distance(target_point)
    distance_ary.push(distance);
    points_ary.push(point)
  end
  distance = distance_ary.min
  closest_point = points_ary[distance_ary.index(distance)]
  return distance, closest_point
end
ary_distance_to_line(finite_lines, target_line) click to toggle source
# File lib/finite_line.rb, line 126
def self.ary_distance_to_line(finite_lines, target_line)
  Util3D.check_arg_type(::Array, finite_lines)
  Util3D.check_arg_type(Line, target_line)
  distance_ary = Array.new(0)
  point_on_target_ary = Array.new(0)
  point_on_finite_line_ary = Array.new(0)
  param_on_target_ary = Array.new(0)
  param_on_finite_line_ary = Array.new(0)
  finite_lines.each do | item |
    distance, point_on_myself, point_on_target, parameter_on_myself, parameter_on_tatget = item.distance(target_line)
    distance_ary.push(distance)
    point_on_target_ary.push(point_on_target)
    point_on_finite_line_ary.push(point_on_myself)
    param_on_target_ary.push(parameter_on_tatget)
    param_on_finite_line_ary.push(parameter_on_myself)
  end
  distance = distance_ary.min
  point_on_finiteline = point_on_finite_line_ary[distance_ary.index(distance)]
  point_on_target = point_on_target_ary[distance_ary.index(distance)]
  param_on_finiteline = param_on_finite_line_ary[distance_ary.index(distance)]
  param_on_target = param_on_target_ary[distance_ary.index(distance)]
  return distance, point_on_finiteline, point_on_target, param_on_finiteline, param_on_target
end
new(start_point = Vector3.new(0,0,0), end_point = Vector3.new(1,0,0)) click to toggle source
Input

start_point and end_point should be Vector3.

Output

return new instance as FiniteLine

Calls superclass method
# File lib/finite_line.rb, line 18
def initialize(start_point = Vector3.new(0,0,0), end_point = Vector3.new(1,0,0))
  Util3D.check_arg_type(Vector3, start_point)
  Util3D.check_arg_type(Vector3, end_point)
  super()
  @start_point = start_point
  @end_point  = end_point
end

Public Instance Methods

==(rhs) click to toggle source
Input

rhs should be FiniteLine.

Output

return true if rhs equals myself.

# File lib/finite_line.rb, line 49
def ==(rhs)
  return false if rhs == nil
  return false if !rhs.kind_of?(FiniteLine)
  return false if( self.start_point != rhs.start_point)
  return false if( self.end_point != rhs.end_point)
  return true
end
direction() click to toggle source
Output

return direction as vector from start_point to end_point as Vector3

# File lib/finite_line.rb, line 65
def direction
  @end_point - @start_point
end
distance(target) click to toggle source

This function returns closest distance between FiniteLine and anothor element.

Input

target should be Vector3 or Line or FiniteLine

Output
in case target is Vector3

return “distance, closest point on myself, parameter on myself” as [Numeric, Vector3, Numeric]

in case target is Line or FiniteLine

return “distance, point on myself, point on target, parameter on myself, parameter on tatget” as [Numeric, Vector3, Vector3, Numeric, Numeric]

# File lib/finite_line.rb, line 97
def distance(target)
  # with Point
  if(target.kind_of?(Vector3))
    return distance_to_point(target)
    #with Line
  elsif(target.kind_of?(Line))
    return distance_to_line(target)
  #widh Finite Line
  elsif(target.kind_of?(FiniteLine))
    return distance_to_finite_line(target)
  end
  Util3D.raise_argurment_error(target)
end
initialize_copy( original_obj ) click to toggle source
# File lib/finite_line.rb, line 26
def initialize_copy( original_obj )
  @start_point = original_obj.start_point.dup
  @end_point = original_obj.end_point.dup
end
length() click to toggle source
Output

return length as Numeric

# File lib/finite_line.rb, line 83
def length
  @start_point.distance(@end_point)
end
point(parameter) click to toggle source
Input

parameter should be Numeric.

Output

return a point on line at input parameter position as Vector3

# File lib/finite_line.rb, line 73
def point(parameter)
  if(parameter < 0.0 or 1.0 < parameter)
    return nil
  else
    return @start_point * (1.0 - parameter) + @end_point * parameter
  end
end
rotate(mat) click to toggle source
Input

mat should be Matrix which row and col size are 3.

Output

return rotated FiniteLine.

# File lib/finite_line.rb, line 39
def rotate(mat)
  rot_start_point = mat*start_point
  rot_end_point = mat*end_point
  return FiniteLine.new(rot_start_point, rot_end_point)
end
to_s() click to toggle source
# File lib/finite_line.rb, line 31
def to_s
  "FiniteLine[from#{start_point.to_element_s}, to#{end_point.to_element_s}]"
end
vertices() click to toggle source
Output

return Array of start_point and end_point.

# File lib/finite_line.rb, line 59
def vertices
  return [start_point, end_point]
end

Private Instance Methods

distance_to_finite_line(target_finite_line) click to toggle source
# File lib/finite_line.rb, line 190
def distance_to_finite_line(target_finite_line)
  line1 = Line.new(self.start_point, self.direction)
  line2 = Line.new(target_finite_line.start_point, target_finite_line.direction)
  distance, point_myself, point_target, parameter_myself, parameter_target = line1.distance( line2 )
  if(point_myself == nil and point_target == nil)
    #prallel or including case
    point_pair = Array.new(4)
    point_pair[0] = Array.new([self.start_point, target_finite_line.start_point, 0, 0])
    point_pair[1] = Array.new([self.start_point, target_finite_line.end_point, 0,1])
    point_pair[2] = Array.new([self.end_point, target_finite_line.start_point, 1,0])
    point_pair[3] = Array.new([self.end_point, target_finite_line.end_point,1,1])

    distance_ary = Array.new(0)
    point_pair.each do |points|
      distance_ary << points[0].distance(points[1])
    end
    distance_min = distance_ary.min
    distance_min_ary = Array.new(0)
    distance_min_index = nil
    distance_ary.each do |item|
      if( item - tolerance < distance_min )
        distance_min_ary << item
        distance_min_index = distance_ary.index(item)
      end
    end
    if( distance_min_ary.size == 1)
      target_point_pair = point_pair[distance_min_index]
      distance = target_point_pair[0].distance(target_point_pair[1])
      return distance, target_point_pair[0], target_point_pair[1], target_point_pair[2], target_point_pair[3]
    else
      return distance, nil, nil, nil, nil
    end
  #out of range
  elsif( parameter_myself < 0 or 1 < parameter_myself or parameter_target < 0 or 1 < parameter_target )
    parameter_myself = [1, parameter_myself].min
    parameter_myself = [0, parameter_myself].max
    distance1, point_target, paramter_target_tmp = target_finite_line.distance(point_myself)

    parameter_target = [1, parameter_target].min
    parameter_target = [0, parameter_target].max
    distance2, point_myself, parameter_myself_tmp = self.distance(point_target)
    if(distance1 < distance2)
      parameter_target = paramter_target_tmp
    else
      parameter_myself = parameter_myself_tmp
    end
  end
  point_myself = line1.point(parameter_myself);
  point_target = line2.point(parameter_target);
  distance = point_myself.distance(point_target)
  return distance, point_myself, point_target, parameter_myself, parameter_target
end
distance_to_line(target_infinite_line) click to toggle source
# File lib/finite_line.rb, line 172
def distance_to_line(target_infinite_line)
  self_infinite_line = Line.new(self.start_point, self.direction)
  distance, point1, point2, parameter1, parameter2 = self_infinite_line.distance(target_infinite_line)
  #parallel
  return distance, nil, nil, nil, nil if( point1 == nil and point2 == nil)
  #parameter is in range
  return distance, point1, point2, parameter1, parameter2 if(0 < parameter1 and parameter1 < 1)
  distance_to_start_point, closest_point_to_start_point, parameter_to_start_point =
    target_infinite_line.distance(self.start_point)
  distance_to_end_point, closest_point_to_end_point, parameter_to_end_point =
    target_infinite_line.distance(self.end_point)
  if(distance_to_start_point < distance_to_end_point)
    return distance_to_start_point, self.start_point, closest_point_to_start_point, 0.0, parameter_to_start_point
  else
    return distance_to_end_point, self.end_point, closest_point_to_end_point, 1.0, parameter_to_end_point
  end
end
distance_to_point(target) click to toggle source
# File lib/finite_line.rb, line 150
def distance_to_point(target)
  # get distance using infinite line
  infinite_line = Line.new(self.start_point, self.direction)
  distance, closest_point, parameter = infinite_line.distance(target)
  if(0.0 <= parameter and parameter <= 1.0)
    return distance, closest_point, parameter
  end

  distance_to_start_point = @start_point.distance(target)
  distance_to_end_point   = @end_point.distance(target)
  if(distance_to_start_point < distance_to_end_point)
    distance = distance_to_start_point
    closest_point = @start_point
    parameter = 0.0
  else
    distance = distance_to_end_point
    closest_point = @end_point
    parameter = 1.0
  end
  return distance, closest_point, parameter
end