class EasyGeometry::D2::Point
A point in a 2-dimensional Euclidean space.
Constants
- EQUITY_TOLERANCE
Attributes
Public Class Methods
The affine rank of a set of points is the dimension of the smallest affine space containing all the points.
For example, if the points lie on a line (and are not all the same) their affine rank is 1.
If the points lie on a plane but not a line, their affine rank is 2.
By convention, the empty set has affine rank -1.
# File lib/easy_geometry/d2/point.rb, line 51 def self.affine_rank(*points) raise TypeError, 'Args should be a Points' unless points.detect { |p| !p.is_a?(Point) }.nil? return -1 if points.length == 0 origin = points[0] points = points[1..-1].map {|p| p - origin} Matrix[*points.map {|p| [p.x, p.y]}].rank end
Returns:
true if there exists a line that contains `points`,
or if no points are given.
false otherwise.
# File lib/easy_geometry/d2/point.rb, line 39 def self.is_collinear?(*points) # raise TypeError, 'Args should be a Points' unless points.detect { |p| !p.is_a?(Point) }.nil? Point.affine_rank(*points.uniq) <= 1 end
# File lib/easy_geometry/d2/point.rb, line 9 def initialize(x, y) @x = x; @y = y validate! converting_to_rational! end
Project the point 'a' onto the line between the origin and point 'b' along the normal direction.
Parameters:
Point, Point
Returns:
Point
# File lib/easy_geometry/d2/point.rb, line 25 def self.project(a, b) unless a.is_a?(Point) && b.is_a?(Point) raise TypeError, "Project between #{ a.class } and #{ b.class } is not defined" end raise ArgumentError, "Cannot project to the zero vector" if b.zero? b * a.dot(b) / b.dot(b) end
Public Instance Methods
Multiplication of point and number.
# File lib/easy_geometry/d2/point.rb, line 91 def *(scalar) raise TypeError, "Multiplication between Point and #{ scalar.class } is not defined" unless scalar.is_a?(Numeric) Point.new(x * scalar, y * scalar) end
Addition of two points.
# File lib/easy_geometry/d2/point.rb, line 85 def +(other) raise TypeError, "Addition between Point and #{ other.class } is not defined" unless other.is_a?(Point) Point.new(self.x + other.x, self.y + other.y) end
Subtraction of two points.
# File lib/easy_geometry/d2/point.rb, line 79 def -(other) raise TypeError, "Subtract between Point and #{ other.class } is not defined" unless other.is_a?(Point) Point.new(self.x - other.x, self.y - other.y) end
Dividing of point and number.
# File lib/easy_geometry/d2/point.rb, line 97 def /(scalar) raise TypeError, "Dividing between Point and #{ scalar.class } is not defined" unless scalar.is_a?(Numeric) Point.new(x / scalar, y / scalar) end
# File lib/easy_geometry/d2/point.rb, line 102 def <=>(other) return self.y <=> other.y if self.x == other.x self.x <=> other.x end
Compare self and other Point
.
# File lib/easy_geometry/d2/point.rb, line 73 def ==(other) return false unless other.is_a?(Point) (x - other.x).abs < EQUITY_TOLERANCE && (y - other.y).abs < EQUITY_TOLERANCE end
Returns the distance between this point and the origin.
# File lib/easy_geometry/d2/point.rb, line 108 def abs self.distance(Point.new(0, 0)) end
Distance between self and another geometry entity.
Parameters:
geometry_entity
Returns:
int
# File lib/easy_geometry/d2/point.rb, line 120 def distance(other) if other.is_a?(Point) return distance_between_points(self, other) end if other.respond_to?(:distance) return other.distance(self) end raise TypeError, "Distance between Point and #{ other.class } is not defined" end
Dot product, also known as inner product or scalar product.
# File lib/easy_geometry/d2/point.rb, line 62 def dot(other) raise TypeError, "Scalar (dot) product between Point and #{ other.class } is not defined" unless other.is_a?(Point) x * other.x + y * other.y end
Intersection between point and another geometry entity.
Parameters:
geometry_entity
Returns:
Array of Points
# File lib/easy_geometry/d2/point.rb, line 140 def intersection(other) if other.is_a?(Point) return points_intersection(self, other) end if other.respond_to?(:intersection) return other.intersection(self) end raise TypeError, "Intersection between Point and #{ other.class } is not defined" end
The midpoint between self and another point.
Parameters:
Point
Returns:
Point
# File lib/easy_geometry/d2/point.rb, line 160 def midpoint(other) raise TypeError, "Midpoint between Point and #{ other.class } is not defined" unless other.is_a?(Point) Point.new( (self.x + other.x) / 2, (self.y + other.y) / 2 ) end
True if every coordinate is zero, False if any coordinate is not zero.
# File lib/easy_geometry/d2/point.rb, line 68 def zero? x.zero? && y.zero? end
Private Instance Methods
# File lib/easy_geometry/d2/point.rb, line 186 def converting_to_rational! @x = Rational(x.to_s) unless x.is_a?(Rational) @y = Rational(y.to_s) unless y.is_a?(Rational) end
# File lib/easy_geometry/d2/point.rb, line 176 def distance_between_points(p1, p2) # AB = √(x2 - x1)**2 + (y2 - y1)**2 Math.sqrt( (p2.x - p1.x)**2 + (p2.y - p1.y)**2 ) # Math.hypot((p2.x - p1.x), (p2.y - p1.y)) end
# File lib/easy_geometry/d2/point.rb, line 171 def points_intersection(p1, p2) return [p1] if p1 == p2 return [] end
# File lib/easy_geometry/d2/point.rb, line 182 def validate! raise TypeError, 'Coords should be numbers' if !x.is_a?(Numeric) || !y.is_a?(Numeric) end