sevgi-geometry 0.73.2 → 0.93.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/lib/sevgi/geometry/element.rb +211 -31
- data/lib/sevgi/geometry/elements/line.rb +47 -8
- data/lib/sevgi/geometry/elements/parallelogram.rb +59 -0
- data/lib/sevgi/geometry/elements/polygon.rb +7 -1
- data/lib/sevgi/geometry/elements/polyline.rb +7 -1
- data/lib/sevgi/geometry/elements/rect.rb +56 -8
- data/lib/sevgi/geometry/elements/triangle.rb +43 -0
- data/lib/sevgi/geometry/equation/linear.rb +147 -7
- data/lib/sevgi/geometry/equation/quadratic.rb +7 -1
- data/lib/sevgi/geometry/equation.rb +47 -9
- data/lib/sevgi/geometry/errors.rb +1 -0
- data/lib/sevgi/geometry/internal.rb +14 -0
- data/lib/sevgi/geometry/operation/align.rb +35 -9
- data/lib/sevgi/geometry/operation/sweep.rb +42 -5
- data/lib/sevgi/geometry/operation.rb +9 -0
- data/lib/sevgi/geometry/point.rb +103 -6
- data/lib/sevgi/geometry/segment.rb +87 -13
- data/lib/sevgi/geometry/version.rb +2 -1
- data/lib/sevgi/geometry.rb +9 -0
- metadata +5 -5
- data/lib/sevgi/geometry/elements/parm.rb +0 -37
- data/lib/sevgi/geometry/elements/tri.rb +0 -18
data/lib/sevgi/geometry/point.rb
CHANGED
|
@@ -2,80 +2,177 @@
|
|
|
2
2
|
|
|
3
3
|
module Sevgi
|
|
4
4
|
module Geometry
|
|
5
|
+
# Affine transforms shared by immutable geometry tuples.
|
|
5
6
|
module Affinity
|
|
7
|
+
# Reflects a point across the selected axes.
|
|
8
|
+
#
|
|
9
|
+
# `x:` controls reflection across the x-axis, which negates y. `y:`
|
|
10
|
+
# controls reflection across the y-axis, which negates x.
|
|
11
|
+
# @param x [Boolean] reflect across the x-axis
|
|
12
|
+
# @param y [Boolean] reflect across the y-axis
|
|
13
|
+
# @return [Sevgi::Geometry::Point]
|
|
6
14
|
def reflect(x: true, y: true) = with(x: (y ? -1 : 1) * self.x(), y: (x ? -1 : 1) * self.y())
|
|
7
15
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
# Rotates a point around the origin using screen-space degrees.
|
|
17
|
+
# @param a [Numeric] clockwise angle in degrees
|
|
18
|
+
# @return [Sevgi::Geometry::Point]
|
|
12
19
|
def rotate(a) = with(x: (x * F.cos(a)) - (y * F.sin(a)), y: (x * F.sin(a)) + (y * F.cos(a)))
|
|
13
20
|
|
|
21
|
+
# Scales a point from the origin.
|
|
22
|
+
# @param sx [Numeric] x scale factor
|
|
23
|
+
# @param sy [Numeric, Sevgi::Undefined] y scale factor, defaulting to sx
|
|
24
|
+
# @return [Sevgi::Geometry::Point]
|
|
14
25
|
def scale(sx, sy = Undefined) = with(x: sx * x, y: Undefined.default(sy, sx) * y)
|
|
15
26
|
|
|
16
|
-
|
|
27
|
+
# Skews a point from the origin.
|
|
28
|
+
# @param ax [Numeric] x-axis skew angle in degrees
|
|
29
|
+
# @param ay [Numeric, Sevgi::Undefined] y-axis skew angle in degrees, defaulting to ax
|
|
30
|
+
# @return [Sevgi::Geometry::Point]
|
|
31
|
+
def skew(ax, ay = Undefined) = with(x: x + (y * F.tan(ax)), y: y + (x * F.tan(Undefined.default(ay, ax))))
|
|
17
32
|
|
|
18
|
-
|
|
33
|
+
# Skews a point along x.
|
|
34
|
+
# @param a [Numeric] skew angle in degrees
|
|
35
|
+
# @return [Sevgi::Geometry::Point]
|
|
36
|
+
def skew_x(a) = with(x: x + (y * F.tan(a)))
|
|
19
37
|
|
|
38
|
+
# Skews a point along y.
|
|
39
|
+
# @param a [Numeric] skew angle in degrees
|
|
40
|
+
# @return [Sevgi::Geometry::Point]
|
|
20
41
|
def skew_y(a) = with(y: y + (x * F.tan(a)))
|
|
21
42
|
|
|
43
|
+
# Translates a point.
|
|
44
|
+
# @param dx [Numeric] x offset
|
|
45
|
+
# @param dy [Numeric, Sevgi::Undefined] y offset, defaulting to dx
|
|
46
|
+
# @return [Sevgi::Geometry::Point]
|
|
22
47
|
def translate(dx, dy = Undefined) = with(x: x + dx, y: y + Undefined.default(dy, dx))
|
|
23
48
|
end
|
|
24
49
|
|
|
50
|
+
# Immutable point in SVG/screen coordinates.
|
|
51
|
+
#
|
|
52
|
+
# Use `Point[x, y]` to create a point from two coordinates.
|
|
25
53
|
Point = Data.define(:x, :y) do
|
|
26
54
|
include Comparable
|
|
27
55
|
include Affinity
|
|
28
56
|
|
|
57
|
+
# @!attribute [r] x
|
|
58
|
+
# @return [Float] x coordinate
|
|
59
|
+
# @!attribute [r] y
|
|
60
|
+
# @return [Float] y coordinate
|
|
61
|
+
|
|
62
|
+
# Returns the screen-space angle from one point to another.
|
|
63
|
+
# @param starting [Sevgi::Geometry::Point, Array<Numeric>] start point
|
|
64
|
+
# @param ending [Sevgi::Geometry::Point, Array<Numeric>] end point
|
|
65
|
+
# @return [Float] clockwise angle in degrees
|
|
66
|
+
# @raise [Sevgi::Geometry::Error] when either point cannot be coerced
|
|
29
67
|
def self.angle(starting, ending)
|
|
30
68
|
starting, ending = Tuples[Point, starting, ending]
|
|
31
69
|
F.atan2(ending.y - starting.y, ending.x - starting.x)
|
|
32
70
|
end
|
|
33
71
|
|
|
72
|
+
# Compares two points with optional numeric precision.
|
|
73
|
+
# @param this [Sevgi::Geometry::Point, Array<Numeric>] first point
|
|
74
|
+
# @param that [Sevgi::Geometry::Point, Array<Numeric>] second point
|
|
75
|
+
# @param precision [Integer, nil] decimal precision, or nil for the current function default
|
|
76
|
+
# @return [Boolean]
|
|
77
|
+
# @raise [Sevgi::Geometry::Error] when either point cannot be coerced
|
|
34
78
|
def self.eq?(this, that, precision: nil)
|
|
35
79
|
this, that = Tuples[self, this, that]
|
|
36
80
|
F.eq?(this.x, that.x, precision:) && F.eq?(this.y, that.y, precision:)
|
|
37
81
|
end
|
|
38
82
|
|
|
83
|
+
# Returns the Euclidean distance between two points.
|
|
84
|
+
# @param starting [Sevgi::Geometry::Point, Array<Numeric>] start point
|
|
85
|
+
# @param ending [Sevgi::Geometry::Point, Array<Numeric>] end point
|
|
86
|
+
# @return [Float]
|
|
87
|
+
# @raise [Sevgi::Geometry::Error] when either point cannot be coerced
|
|
39
88
|
def self.length(starting, ending)
|
|
40
89
|
starting, ending = Tuples[Point, starting, ending]
|
|
41
90
|
::Math.sqrt(((starting.y - ending.y) ** 2) + ((starting.x - ending.x) ** 2))
|
|
42
91
|
end
|
|
43
92
|
|
|
93
|
+
# Returns the origin point.
|
|
94
|
+
# @return [Sevgi::Geometry::Point]
|
|
44
95
|
def self.origin
|
|
45
96
|
new(x: 0.0, y: 0.0)
|
|
46
97
|
end
|
|
47
98
|
|
|
99
|
+
# Creates a point.
|
|
100
|
+
# @param x [Numeric] x coordinate
|
|
101
|
+
# @param y [Numeric] y coordinate
|
|
102
|
+
# @return [void]
|
|
48
103
|
def initialize(x:, y:) = super(x: x.to_f, y: y.to_f)
|
|
49
104
|
|
|
105
|
+
# Compares points by x, then y.
|
|
106
|
+
# @param other [Sevgi::Geometry::Point, Array<Numeric>] point to compare
|
|
107
|
+
# @return [Integer, nil]
|
|
108
|
+
# @raise [Sevgi::Geometry::Error] when other cannot be coerced
|
|
50
109
|
def <=>(other) = (other = Tuple[Point, other]).nan? || nan? ? nil : deconstruct <=> other.deconstruct
|
|
51
110
|
|
|
111
|
+
# Reports whether this point is at or above another point in screen coordinates.
|
|
112
|
+
# @param other [Sevgi::Geometry::Point, Array<Numeric>] point to compare
|
|
113
|
+
# @return [Boolean]
|
|
114
|
+
# @raise [Sevgi::Geometry::Error] when other cannot be coerced
|
|
52
115
|
def above?(other) = y <= Tuple[Point, other].y
|
|
53
116
|
|
|
117
|
+
# Returns a point rounded to precision.
|
|
118
|
+
# @param precision [Integer, nil] decimal precision, or nil for the current function default
|
|
119
|
+
# @return [Sevgi::Geometry::Point]
|
|
54
120
|
def approx(precision = nil) = with(x: F.approx(x, precision), y: F.approx(y, precision))
|
|
55
121
|
|
|
122
|
+
# Reports whether this point is at or below another point in screen coordinates.
|
|
123
|
+
# @param other [Sevgi::Geometry::Point, Array<Numeric>] point to compare
|
|
124
|
+
# @return [Boolean]
|
|
125
|
+
# @raise [Sevgi::Geometry::Error] when other cannot be coerced
|
|
56
126
|
def below?(other) = y >= Tuple[Point, other].y
|
|
57
127
|
|
|
128
|
+
# Compares this point with optional numeric precision.
|
|
129
|
+
# @param other [Sevgi::Geometry::Point, Array<Numeric>] point to compare
|
|
130
|
+
# @param precision [Integer, nil] decimal precision, or nil for the current function default
|
|
131
|
+
# @return [Boolean]
|
|
132
|
+
# @raise [Sevgi::Geometry::Error] when other cannot be coerced
|
|
58
133
|
def eq?(other, precision: nil) = self.class.eq?(self, other, precision:)
|
|
59
134
|
|
|
135
|
+
# Reports strict point equality.
|
|
136
|
+
# @param other [Object] object to compare
|
|
137
|
+
# @return [Boolean]
|
|
60
138
|
def eql?(other) = self.class == other.class && deconstruct == other.deconstruct
|
|
61
139
|
|
|
140
|
+
# Returns a hash compatible with strict equality.
|
|
141
|
+
# @return [Integer]
|
|
62
142
|
def hash = [self.class, *deconstruct].hash
|
|
63
143
|
|
|
144
|
+
# Reports whether any coordinate is infinite.
|
|
145
|
+
# @return [Boolean]
|
|
64
146
|
def infinite? = deconstruct.any?(&:infinite?)
|
|
65
147
|
|
|
148
|
+
# Reports whether this point is at or left of another point.
|
|
149
|
+
# @param other [Sevgi::Geometry::Point, Array<Numeric>] point to compare
|
|
150
|
+
# @return [Boolean]
|
|
151
|
+
# @raise [Sevgi::Geometry::Error] when other cannot be coerced
|
|
66
152
|
def left?(other) = x <= Tuple[Point, other].x
|
|
67
153
|
|
|
154
|
+
# Reports whether any coordinate is NaN.
|
|
155
|
+
# @return [Boolean]
|
|
68
156
|
def nan? = deconstruct.any?(&:nan?)
|
|
69
157
|
|
|
158
|
+
# Reports whether this point is at or right of another point.
|
|
159
|
+
# @param other [Sevgi::Geometry::Point, Array<Numeric>] point to compare
|
|
160
|
+
# @return [Boolean]
|
|
161
|
+
# @raise [Sevgi::Geometry::Error] when other cannot be coerced
|
|
70
162
|
def right?(other) = x >= Tuple[Point, other].x
|
|
71
163
|
|
|
164
|
+
# Formats point coordinates for SVG coordinate-list attributes.
|
|
165
|
+
# @return [String]
|
|
72
166
|
def to_cs = "#{F.approx(x)},#{F.approx(y)}"
|
|
73
167
|
|
|
168
|
+
# Formats the point for display.
|
|
169
|
+
# @return [String]
|
|
74
170
|
def to_s = "(#{to_cs})"
|
|
75
171
|
|
|
76
172
|
alias_method :==, :eql?
|
|
77
173
|
end
|
|
78
174
|
|
|
175
|
+
# Origin point in SVG/screen coordinates.
|
|
79
176
|
Origin = Point.origin
|
|
80
177
|
end
|
|
81
178
|
end
|
|
@@ -2,59 +2,133 @@
|
|
|
2
2
|
|
|
3
3
|
module Sevgi
|
|
4
4
|
module Geometry
|
|
5
|
+
# Immutable polar segment in SVG/screen coordinates.
|
|
6
|
+
#
|
|
7
|
+
# `length` is a distance and `angle` is a clockwise angle in degrees.
|
|
8
|
+
# Use `Segment[length, angle]` to create a segment from polar components.
|
|
5
9
|
Segment = Data.define(:length, :angle) do
|
|
6
10
|
include Comparable
|
|
7
11
|
|
|
12
|
+
# @!attribute [r] length
|
|
13
|
+
# @return [Float] segment length
|
|
14
|
+
# @!attribute [r] angle
|
|
15
|
+
# @return [Float] clockwise angle in degrees
|
|
16
|
+
|
|
17
|
+
# Creates a segment from start and end points.
|
|
18
|
+
# @param starting [Sevgi::Geometry::Point, Array<Numeric>] start point
|
|
19
|
+
# @param ending [Sevgi::Geometry::Point, Array<Numeric>] end point
|
|
20
|
+
# @return [Sevgi::Geometry::Segment]
|
|
21
|
+
# @raise [Sevgi::Geometry::Error] when either point cannot be coerced
|
|
8
22
|
def self.call(starting, ending)
|
|
9
23
|
starting, ending = Tuples[Point, starting, ending]
|
|
10
24
|
self[Point.length(starting, ending), Point.angle(starting, ending)]
|
|
11
25
|
end
|
|
12
26
|
|
|
27
|
+
# Compares two segments with optional numeric precision.
|
|
28
|
+
# @param this [Sevgi::Geometry::Segment, Array<Numeric>] first segment
|
|
29
|
+
# @param that [Sevgi::Geometry::Segment, Array<Numeric>] second segment
|
|
30
|
+
# @param precision [Integer, nil] decimal precision, or nil for the current function default
|
|
31
|
+
# @return [Boolean]
|
|
32
|
+
# @raise [Sevgi::Geometry::Error] when either segment cannot be coerced
|
|
13
33
|
def self.eq?(this, that, precision: nil)
|
|
14
34
|
this, that = Tuples[self, this, that]
|
|
15
35
|
F.eq?(this.length, that.length, precision:) && F.eq?(this.angle, that.angle, precision:)
|
|
16
36
|
end
|
|
17
37
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def self.
|
|
38
|
+
# Returns a downward segment.
|
|
39
|
+
# @param length [Numeric] segment length
|
|
40
|
+
# @return [Sevgi::Geometry::Segment]
|
|
41
|
+
def self.downward(length) = self[length, 90.0]
|
|
42
|
+
|
|
43
|
+
# Returns a leftward segment.
|
|
44
|
+
# @param length [Numeric] segment length
|
|
45
|
+
# @return [Sevgi::Geometry::Segment]
|
|
46
|
+
def self.leftward(length) = self[length, 180.0]
|
|
47
|
+
|
|
48
|
+
# Returns a rightward segment.
|
|
49
|
+
# @param length [Numeric] segment length
|
|
50
|
+
# @return [Sevgi::Geometry::Segment]
|
|
51
|
+
def self.rightward(length) = self[length, 0.0]
|
|
52
|
+
|
|
53
|
+
# Returns an upward segment.
|
|
54
|
+
# @param length [Numeric] segment length
|
|
55
|
+
# @return [Sevgi::Geometry::Segment]
|
|
56
|
+
def self.upward(length) = self[length, -90.0]
|
|
57
|
+
|
|
58
|
+
class << self
|
|
59
|
+
# @return [Sevgi::Geometry::Segment]
|
|
60
|
+
alias_method :horizontal, :rightward
|
|
61
|
+
# @return [Sevgi::Geometry::Segment]
|
|
62
|
+
alias_method :vertical, :downward
|
|
63
|
+
end
|
|
22
64
|
|
|
65
|
+
# Creates a segment.
|
|
66
|
+
# @param length [Numeric] segment length
|
|
67
|
+
# @param angle [Numeric] clockwise angle in degrees
|
|
68
|
+
# @return [void]
|
|
23
69
|
def initialize(length:, angle:) = super(length: length.to_f, angle: angle.to_f)
|
|
24
70
|
|
|
71
|
+
# Compares segments by length.
|
|
72
|
+
# @param other [Sevgi::Geometry::Segment, Array<Numeric>] segment to compare
|
|
73
|
+
# @return [Integer, nil]
|
|
74
|
+
# @raise [Sevgi::Geometry::Error] when other cannot be coerced
|
|
25
75
|
def <=>(other) = (other = Tuple[Segment, other]).nan? || nan? ? nil : length <=> other.length
|
|
26
76
|
|
|
77
|
+
# Returns a segment rounded to precision.
|
|
78
|
+
# @param precision [Integer, nil] decimal precision, or nil for the current function default
|
|
79
|
+
# @return [Sevgi::Geometry::Segment]
|
|
27
80
|
def approx(precision = nil) = with(length: F.approx(length, precision), angle: F.approx(angle, precision))
|
|
28
81
|
|
|
29
|
-
|
|
30
|
-
|
|
82
|
+
# Returns the endpoint reached from a starting point.
|
|
83
|
+
# @param starting [Sevgi::Geometry::Point, Array<Numeric>] start point
|
|
84
|
+
# @return [Sevgi::Geometry::Point]
|
|
85
|
+
# @raise [Sevgi::Geometry::Error] when starting cannot be coerced
|
|
31
86
|
def ending(starting) = Tuple[Point, starting].translate(x, y)
|
|
32
87
|
|
|
88
|
+
# Compares this segment with optional numeric precision.
|
|
89
|
+
# @param other [Sevgi::Geometry::Segment, Array<Numeric>] segment to compare
|
|
90
|
+
# @param precision [Integer, nil] decimal precision, or nil for the current function default
|
|
91
|
+
# @return [Boolean]
|
|
92
|
+
# @raise [Sevgi::Geometry::Error] when other cannot be coerced
|
|
33
93
|
def eq?(other, precision: nil) = self.class.eq?(self, other, precision:)
|
|
34
94
|
|
|
95
|
+
# Reports strict segment equality.
|
|
96
|
+
# @param other [Object] object to compare
|
|
97
|
+
# @return [Boolean]
|
|
35
98
|
def eql?(other) = self.class == other.class && deconstruct == other.deconstruct
|
|
36
99
|
|
|
100
|
+
# Returns a hash compatible with strict equality.
|
|
101
|
+
# @return [Integer]
|
|
37
102
|
def hash = [self.class, *deconstruct].hash
|
|
38
103
|
|
|
104
|
+
# Reports whether any component is infinite.
|
|
105
|
+
# @return [Boolean]
|
|
39
106
|
def infinite? = deconstruct.any?(&:infinite?)
|
|
40
107
|
|
|
108
|
+
# Converts the segment into a line at a point.
|
|
109
|
+
# @param point [Sevgi::Geometry::Point, Array<Numeric>] line start point
|
|
110
|
+
# @return [Sevgi::Geometry::Line]
|
|
111
|
+
# @raise [Sevgi::Geometry::Error] when point cannot be coerced
|
|
41
112
|
def line(point = Origin) = Line[length, angle, position: Tuple[Point, point]]
|
|
42
113
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def ly = y.abs
|
|
46
|
-
|
|
114
|
+
# Reports whether any component is NaN.
|
|
115
|
+
# @return [Boolean]
|
|
47
116
|
def nan? = deconstruct.any?(&:nan?)
|
|
48
117
|
|
|
118
|
+
# Returns the opposite segment.
|
|
119
|
+
# @return [Sevgi::Geometry::Segment]
|
|
49
120
|
def reverse = with(angle: angle + 180.0)
|
|
50
121
|
|
|
51
|
-
|
|
52
|
-
|
|
122
|
+
# Returns the x component of the segment.
|
|
123
|
+
# @return [Float]
|
|
53
124
|
def x = length * F.cos(angle)
|
|
54
125
|
|
|
126
|
+
# Returns the y component of the segment.
|
|
127
|
+
# @return [Float]
|
|
55
128
|
def y = length * F.sin(angle)
|
|
56
129
|
end
|
|
57
130
|
|
|
58
|
-
|
|
131
|
+
# Lightweight polar value used where a plain length/angle tuple is enough.
|
|
132
|
+
Polar = Data.define(:length, :angle)
|
|
59
133
|
end
|
|
60
134
|
end
|
data/lib/sevgi/geometry.rb
CHANGED
|
@@ -12,3 +12,12 @@ require_relative "geometry/equation"
|
|
|
12
12
|
require_relative "geometry/operation"
|
|
13
13
|
|
|
14
14
|
require_relative "geometry/version"
|
|
15
|
+
|
|
16
|
+
module Sevgi
|
|
17
|
+
# Screen-space geometry primitives used by Sevgi layout and drawing helpers.
|
|
18
|
+
#
|
|
19
|
+
# Coordinates follow SVG screen conventions: +x points right, +y points down,
|
|
20
|
+
# and positive angles turn clockwise.
|
|
21
|
+
module Geometry
|
|
22
|
+
end
|
|
23
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sevgi-geometry
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.93.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Recai Oktaş
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.93.1
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.
|
|
25
|
+
version: 0.93.1
|
|
26
26
|
description: Enhances the Sevgi toolkit with geometry objects and methods.
|
|
27
27
|
email: roktas@gmail.com
|
|
28
28
|
executables: []
|
|
@@ -36,11 +36,11 @@ files:
|
|
|
36
36
|
- lib/sevgi/geometry/elements/curve.rb
|
|
37
37
|
- lib/sevgi/geometry/elements/ellipse.rb
|
|
38
38
|
- lib/sevgi/geometry/elements/line.rb
|
|
39
|
-
- lib/sevgi/geometry/elements/
|
|
39
|
+
- lib/sevgi/geometry/elements/parallelogram.rb
|
|
40
40
|
- lib/sevgi/geometry/elements/polygon.rb
|
|
41
41
|
- lib/sevgi/geometry/elements/polyline.rb
|
|
42
42
|
- lib/sevgi/geometry/elements/rect.rb
|
|
43
|
-
- lib/sevgi/geometry/elements/
|
|
43
|
+
- lib/sevgi/geometry/elements/triangle.rb
|
|
44
44
|
- lib/sevgi/geometry/equation.rb
|
|
45
45
|
- lib/sevgi/geometry/equation/linear.rb
|
|
46
46
|
- lib/sevgi/geometry/equation/quadratic.rb
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Parallelogram
|
|
4
|
-
|
|
5
|
-
module Sevgi
|
|
6
|
-
module Geometry
|
|
7
|
-
class Parm < Element.lined(4)
|
|
8
|
-
def self.[](horizontal, vertical, position: Origin)
|
|
9
|
-
horizontal, vertical = Tuples[Segment, horizontal, vertical]
|
|
10
|
-
|
|
11
|
-
new_by_segments(horizontal, vertical.reverse, horizontal.reverse, vertical, position:)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.new_by_height(horizontal:, tallness:, position: Origin)
|
|
15
|
-
horizontal = Tuple[Segment, horizontal]
|
|
16
|
-
tallness = Tuple[LengthAngle, tallness]
|
|
17
|
-
|
|
18
|
-
height = tallness.length - horizontal.ly
|
|
19
|
-
angle = tallness.angle
|
|
20
|
-
length = height / F.sin(angle)
|
|
21
|
-
|
|
22
|
-
self[horizontal, Segment[length, angle], position:]
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def self.new_by_width(vertical:, wideness:, position: Origin)
|
|
26
|
-
vertical = Tuple[Segment, vertical]
|
|
27
|
-
wideness = Tuple[LengthAngle, wideness]
|
|
28
|
-
|
|
29
|
-
width = wideness.length - vertical.lx
|
|
30
|
-
angle = wideness.angle
|
|
31
|
-
length = width / F.cos(angle)
|
|
32
|
-
|
|
33
|
-
self[Segment[length, angle], vertical, position:]
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sevgi
|
|
4
|
-
module Geometry
|
|
5
|
-
class Tri < Element.lined(3)
|
|
6
|
-
def self.[](segment_a, segment_b, position: Origin)
|
|
7
|
-
a, b = Tuples[Segment, segment_a, segment_b]
|
|
8
|
-
|
|
9
|
-
length = ::Math.sqrt((a.length ** 2) + (b.length ** 2) - (2 * a.length * b.length * F.cos(b.sup - a.angle)))
|
|
10
|
-
angle = b.sup + F.asin(a.length * F.sin(b.sup - a.angle) / length)
|
|
11
|
-
|
|
12
|
-
c = Segment[length, angle]
|
|
13
|
-
|
|
14
|
-
new_by_segments(a, b, c, position:)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|