Class: Sevgi::Geometry::Point

Inherits:
Data
  • Object
show all
Includes:
Comparable, Affinity
Defined in:
lib/sevgi/geometry/point.rb,
lib/sevgi/geometry/equation.rb

Overview

Immutable point in SVG/screen coordinates.

Use Point[x, y] to create a point from two coordinates.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Affinity

#reflect, #rotate, #scale, #skew, #skew_x, #skew_y, #translate

Constructor Details

#initialize(x:, y:) ⇒ void

Creates a point.

Parameters:

  • x (Numeric)

    x coordinate

  • y (Numeric)

    y coordinate



103
# File 'lib/sevgi/geometry/point.rb', line 103

def initialize(x:, y:) = super(x: x.to_f, y: y.to_f)

Instance Attribute Details

#xFloat (readonly)

Returns x coordinate.

Returns:

  • (Float)

    x coordinate



53
54
55
# File 'lib/sevgi/geometry/point.rb', line 53

def x
  @x
end

#yFloat (readonly)

Returns y coordinate.

Returns:

  • (Float)

    y coordinate



53
54
55
# File 'lib/sevgi/geometry/point.rb', line 53

def y
  @y
end

Class Method Details

.angle(starting, ending) ⇒ Float

Returns the screen-space angle from one point to another.

Parameters:

Returns:

  • (Float)

    clockwise angle in degrees

Raises:



67
68
69
70
# File 'lib/sevgi/geometry/point.rb', line 67

def self.angle(starting, ending)
  starting, ending = Tuples[Point, starting, ending]
  F.atan2(ending.y - starting.y, ending.x - starting.x)
end

.eq?(this, that, precision: nil) ⇒ Boolean

Compares two points with optional numeric precision.

Parameters:

  • this (Sevgi::Geometry::Point, Array<Numeric>)

    first point

  • that (Sevgi::Geometry::Point, Array<Numeric>)

    second point

  • precision (Integer, nil) (defaults to: nil)

    decimal precision, or nil for the current function default

Returns:

  • (Boolean)

Raises:



78
79
80
81
# File 'lib/sevgi/geometry/point.rb', line 78

def self.eq?(this, that, precision: nil)
  this, that = Tuples[self, this, that]
  F.eq?(this.x, that.x, precision:) && F.eq?(this.y, that.y, precision:)
end

.length(starting, ending) ⇒ Float

Returns the Euclidean distance between two points.

Parameters:

Returns:

  • (Float)

Raises:



88
89
90
91
# File 'lib/sevgi/geometry/point.rb', line 88

def self.length(starting, ending)
  starting, ending = Tuples[Point, starting, ending]
  ::Math.sqrt(((starting.y - ending.y) ** 2) + ((starting.x - ending.x) ** 2))
end

.originSevgi::Geometry::Point

Returns the origin point.



95
96
97
# File 'lib/sevgi/geometry/point.rb', line 95

def self.origin
  new(x: 0.0, y: 0.0)
end

Instance Method Details

#<=>(other) ⇒ Integer?

Compares points by x, then y.

Parameters:

Returns:

  • (Integer, nil)

Raises:



109
# File 'lib/sevgi/geometry/point.rb', line 109

def <=>(other) = (other = Tuple[Point, other]).nan? || nan? ? nil : deconstruct <=> other.deconstruct

#above?(other) ⇒ Boolean

Reports whether this point is at or above another point in screen coordinates.

Parameters:

Returns:

  • (Boolean)

Raises:



115
# File 'lib/sevgi/geometry/point.rb', line 115

def above?(other) = y <= Tuple[Point, other].y

#approx(precision = nil) ⇒ Sevgi::Geometry::Point

Returns a point rounded to precision.

Parameters:

  • precision (Integer, nil) (defaults to: nil)

    decimal precision, or nil for the current function default

Returns:



120
# File 'lib/sevgi/geometry/point.rb', line 120

def approx(precision = nil) = with(x: F.approx(x, precision), y: F.approx(y, precision))

#below?(other) ⇒ Boolean

Reports whether this point is at or below another point in screen coordinates.

Parameters:

Returns:

  • (Boolean)

Raises:



126
# File 'lib/sevgi/geometry/point.rb', line 126

def below?(other) = y >= Tuple[Point, other].y

#eq?(other, precision: nil) ⇒ Boolean

Compares this point with optional numeric precision.

Parameters:

  • other (Sevgi::Geometry::Point, Array<Numeric>)

    point to compare

  • precision (Integer, nil) (defaults to: nil)

    decimal precision, or nil for the current function default

Returns:

  • (Boolean)

Raises:



133
# File 'lib/sevgi/geometry/point.rb', line 133

def eq?(other, precision: nil) = self.class.eq?(self, other, precision:)

#eql?(other) ⇒ Boolean Also known as: ==

Reports strict point equality.

Parameters:

  • other (Object)

    object to compare

Returns:

  • (Boolean)


138
# File 'lib/sevgi/geometry/point.rb', line 138

def eql?(other) = self.class == other.class && deconstruct == other.deconstruct

#equation(angle) ⇒ Sevgi::Geometry::Equation::Linear

Returns the linear equation passing through this point at an angle.

Parameters:

  • angle (Numeric)

    clockwise angle in degrees

Returns:



94
95
96
97
98
99
# File 'lib/sevgi/geometry/equation.rb', line 94

def equation(angle)
  return Equation.horizontal(y) if F.zero?(angle % 180.0)
  return Equation.vertical(x) if F.zero?(angle % 90.0)

  Equation.diagonal(slope: (slope = F.tan(angle)), intercept: y - (slope * x))
end

#hashInteger

Returns a hash compatible with strict equality.

Returns:

  • (Integer)


142
# File 'lib/sevgi/geometry/point.rb', line 142

def hash = [self.class, *deconstruct].hash

#infinite?Boolean

Reports whether any coordinate is infinite.

Returns:

  • (Boolean)


146
# File 'lib/sevgi/geometry/point.rb', line 146

def infinite? = deconstruct.any?(&:infinite?)

#left?(other) ⇒ Boolean

Reports whether this point is at or left of another point.

Parameters:

Returns:

  • (Boolean)

Raises:



152
# File 'lib/sevgi/geometry/point.rb', line 152

def left?(other) = x <= Tuple[Point, other].x

#nan?Boolean

Reports whether any coordinate is NaN.

Returns:

  • (Boolean)


156
# File 'lib/sevgi/geometry/point.rb', line 156

def nan? = deconstruct.any?(&:nan?)

#right?(other) ⇒ Boolean

Reports whether this point is at or right of another point.

Parameters:

Returns:

  • (Boolean)

Raises:



162
# File 'lib/sevgi/geometry/point.rb', line 162

def right?(other) = x >= Tuple[Point, other].x

#to_csString

Formats point coordinates for SVG coordinate-list attributes.

Returns:

  • (String)


166
# File 'lib/sevgi/geometry/point.rb', line 166

def to_cs = "#{F.approx(x)},#{F.approx(y)}"

#to_sString

Formats the point for display.

Returns:

  • (String)


170
# File 'lib/sevgi/geometry/point.rb', line 170

def to_s = "(#{to_cs})"