class Cartesius::Ellipse
Public Class Methods
by_axes(major_axis:, minor_axis:)
click to toggle source
# File lib/cartesius/ellipse.rb, line 46 def self.by_axes(major_axis:, minor_axis:) if major_axis == minor_axis raise ArgumentError.new('Axes must be different!') end if major_axis.inclined? || minor_axis.inclined? raise ArgumentError.new('Axes must not be inclined!') end if major_axis.horizontal? && minor_axis.horizontal? raise ArgumentError.new('Axes can not be both horizontal!') end if major_axis.vertical? && minor_axis.vertical? raise ArgumentError.new('Axes can not be both vertical!') end if major_axis.mid != minor_axis.mid raise ArgumentError.new('Axes must be the same mid point!') end if major_axis.horizontal? a2 = Rational(major_axis.length, 2) ** 2 b2 = Rational(minor_axis.length, 2) ** 2 else a2 = Rational(minor_axis.length, 2) ** 2 b2 = Rational(major_axis.length, 2) ** 2 end center = major_axis.mid build_by(a2, b2, center) end
by_definition(focus1:, focus2:, distance:)
click to toggle source
# File lib/cartesius/ellipse.rb, line 18 def self.by_definition(focus1:, focus2:, distance:) if focus1 == focus2 raise ArgumentError.new('Focus points must be different!') end focal_axis = Segment.new(extreme1: focus1, extreme2: focus2) if focal_axis.inclined? raise ArgumentError.new('Focal axis must not be inclined!') end if distance <= focal_axis.length raise ArgumentError.new('Sum of distances must be greater than focal distance!') end c2 = Rational(focal_axis.length, 2) ** 2 if focal_axis.horizontal? a2 = Rational(distance, 2) ** 2 b2 = a2 - c2 else b2 = Rational(distance, 2) ** 2 a2 = b2 - c2 end center = focal_axis.mid build_by(a2, b2, center) end
by_points(center:, point1:, point2:)
click to toggle source
# File lib/cartesius/ellipse.rb, line 80 def self.by_points(center:, point1:, point2:) if center == point1 || center == point2 || point1 == point2 raise ArgumentError.new('Points must be different!') end shifted1 = Point.new(x: point1.x - center.x, y: point1.y - center.y) shifted2 = Point.new(x: point2.x - center.x, y: point2.y - center.y) begin alfa, beta = Cramer.solution2( [shifted1.x ** 2, shifted1.y ** 2], [shifted2.x ** 2, shifted2.y ** 2], [1, 1] ) rescue raise ArgumentError.new('Center and points are not valid!') end a2 = Rational(1, alfa) b2 = Rational(1, beta) build_by(a2, b2, center) end
new(x2:, y2:, x:, y:, k:)
click to toggle source
Conic Conic equation type: ax^2 + by^2 + dx + ey + f = 0
# File lib/cartesius/ellipse.rb, line 13 def initialize(x2:, y2:, x:, y:, k:) @x2_coeff, @y2_coeff, @x_coeff, @y_coeff, @k_coeff = normalize(x2, y2, x, y, k) validation end
Private Class Methods
build_by(a2, b2, center)
click to toggle source
# File lib/cartesius/ellipse.rb, line 163 def self.build_by(a2, b2, center) new(x2: b2, y2: a2, x: -2 * b2 * center.x, y: -2 * a2 * center.y, k: b2 * center.x ** 2 + a2 * center.y ** 2 - a2 * b2) end
Public Instance Methods
==(ellipse)
click to toggle source
# File lib/cartesius/ellipse.rb, line 158 def == (ellipse) ellipse.instance_of?(self.class) && ellipse.focus1 == focus1 && ellipse.focus2 == focus2 && ellipse.distance == distance end
congruent?(ellipse)
click to toggle source
# File lib/cartesius/ellipse.rb, line 153 def congruent?(ellipse) ellipse.instance_of?(self.class) && ellipse.eccentricity == eccentricity end
distance()
click to toggle source
# File lib/cartesius/ellipse.rb, line 118 def distance discriminating(lambda {2 * a}, lambda {2 * b}) end
eccentricity()
click to toggle source
# File lib/cartesius/ellipse.rb, line 149 def eccentricity Rational(focal_axis.length, major_axis.length) end
focal_axis()
click to toggle source
# File lib/cartesius/ellipse.rb, line 122 def focal_axis Segment.new(extreme1: focus1, extreme2: focus2) end
focus1()
click to toggle source
# File lib/cartesius/ellipse.rb, line 104 def focus1 discriminating( lambda {Point.new(x: center.x + cx, y: center.y)}, lambda {Point.new(x: center.x, y: center.y + cy)} ) end
focus2()
click to toggle source
# File lib/cartesius/ellipse.rb, line 111 def focus2 discriminating( lambda {Point.new(x: center.x - cx, y: center.y)}, lambda {Point.new(x: center.x, y: center.y - cy)} ) end
major_axis()
click to toggle source
# File lib/cartesius/ellipse.rb, line 126 def major_axis discriminating( lambda {Segment.new(extreme1: Point.new(x: center.x - a, y: center.y), extreme2: Point.new(x: center.x + a, y: center.y))}, lambda {Segment.new(extreme1: Point.new(x: center.x, y: center.y - b), extreme2: Point.new(x: center.x, y: center.y + b))}, ) end
minor_axis()
click to toggle source
# File lib/cartesius/ellipse.rb, line 133 def minor_axis discriminating( lambda {Segment.new(extreme1: Point.new(x: center.x, y: center.y - b), extreme2: Point.new(x: center.x, y: center.y + b))}, lambda {Segment.new(extreme1: Point.new(x: center.x - a, y: center.y), extreme2: Point.new(x: center.x + a, y: center.y))} ) end
vertices()
click to toggle source
# File lib/cartesius/ellipse.rb, line 140 def vertices [ Point.new(x: center.x + a, y: center.y), Point.new(x: center.x, y: center.y - b), Point.new(x: center.x - a, y: center.y), Point.new(x: center.x, y: center.y + b) ] end
Private Instance Methods
a()
click to toggle source
# File lib/cartesius/ellipse.rb, line 185 def a Math.sqrt(a2) end
b()
click to toggle source
# File lib/cartesius/ellipse.rb, line 189 def b Math.sqrt(b2) end
cx()
click to toggle source
# File lib/cartesius/ellipse.rb, line 193 def cx Math.sqrt(a2 - b2) end
cy()
click to toggle source
# File lib/cartesius/ellipse.rb, line 197 def cy Math.sqrt(b2 - a2) end
discriminating(horizontal_focus_type, vertical_focus_type)
click to toggle source
# File lib/cartesius/ellipse.rb, line 177 def discriminating(horizontal_focus_type, vertical_focus_type) if a2 > b2 horizontal_focus_type.call else vertical_focus_type.call end end
validation()
click to toggle source
# File lib/cartesius/ellipse.rb, line 171 def validation if @x2_coeff <= 0 || @y2_coeff <= 0 || @x2_coeff == @y2_coeff || determinator <= @k_coeff raise ArgumentError.new('Invalid coefficients!') end end