Class: EasyGeometry::D2::Triangle
- Defined in:
- lib/easy_geometry/d2/triangle.rb
Overview
A polygon with three vertices and three sides.
Constant Summary collapse
- EQUITY_TOLERANCE =
0.0000000000001
Instance Attribute Summary collapse
-
#vertices ⇒ Object
readonly
Returns the value of attribute vertices.
Instance Method Summary collapse
-
#altitudes ⇒ Object
The altitudes of the triangle.
-
#bisectors ⇒ Object
The angle bisectors of the triangle.
-
#circumcenter ⇒ Object
The circumcenter of the triangle.
-
#circumcircle ⇒ Object
The circle which passes through the three vertices of the triangle.
-
#circumradius ⇒ Object
The radius of the circumcircle of the triangle.
-
#eulerline ⇒ Object
The Euler line of the triangle.
-
#exradii ⇒ Object
The radius of excircles of a triangle.
-
#incenter ⇒ Object
The center of the incircle.
-
#incircle ⇒ Object
The incircle of the triangle.
-
#initialize(*args) ⇒ Triangle
constructor
A new instance of Triangle.
-
#inradius ⇒ Object
The radius of the incircle.
-
#is_equilateral? ⇒ Boolean
Are all the sides the same length? Precision - 10e-13.
-
#is_isosceles? ⇒ Boolean
Are two or more of the sides the same length? Precision - 10e-13.
-
#is_right? ⇒ Boolean
Is the triangle right-angled.
-
#is_scalene? ⇒ Boolean
Are all the sides of the triangle of different lengths? Precision - 10e-13.
-
#is_similar?(other) ⇒ Boolean
Is another triangle similar to this one.
-
#medial ⇒ Object
The medial triangle of the triangle.
-
#medians ⇒ Object
The medians of the triangle.
-
#nine_point_circle ⇒ Object
The nine-point circle of the triangle.
-
#orthocenter ⇒ Object
The orthocenter of the triangle.
Methods inherited from Polygon
#==, #area, #bounds, #centroid, #distance, #hashable_content, #intersection, #is_convex?, #is_encloses_point?, is_right?, #perimeter, #sides
Constructor Details
#initialize(*args) ⇒ Triangle
Returns a new instance of Triangle.
9 10 11 12 13 |
# File 'lib/easy_geometry/d2/triangle.rb', line 9 def initialize(*args) @vertices = preprocessing_args(args) remove_consecutive_duplicates remove_collinear_points end |
Instance Attribute Details
#vertices ⇒ Object (readonly)
Returns the value of attribute vertices.
5 6 7 |
# File 'lib/easy_geometry/d2/triangle.rb', line 5 def vertices @vertices end |
Instance Method Details
#altitudes ⇒ Object
The altitudes of the triangle.
An altitude of a triangle is a segment through a vertex, perpendicular to the opposite side, with length being the height of the vertex measured from the line containing the side.
Returns:
Hash (The hash consists of keys which are vertices and values
which are Segments.)
92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/easy_geometry/d2/triangle.rb', line 92 def altitudes return @altitudes if defined?(@altitudes) @altitudes = { self.vertices[0] => self.sides[1].perpendicular_segment(self.vertices[0]), self.vertices[1] => self.sides[2].perpendicular_segment(self.vertices[1]), self.vertices[2] => self.sides[0].perpendicular_segment(self.vertices[2]) } @altitudes end |
#bisectors ⇒ Object
The angle bisectors of the triangle.
An angle bisector of a triangle is a straight line through a vertex which cuts the corresponding angle in half.
Returns:
Hash (each key is a vertex (Point) and each value is the corresponding
bisector (Segment).)
168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/easy_geometry/d2/triangle.rb', line 168 def bisectors s = self.sides.map { |side| Line.new(side.p1, side.p2) } c = self.incenter inter1 = Line.new(self.vertices[0], c).intersection(s[1]).first inter2 = Line.new(self.vertices[1], c).intersection(s[2]).first inter3 = Line.new(self.vertices[2], c).intersection(s[0]).first { self.vertices[0] => Segment.new(self.vertices[0], inter1), self.vertices[1] => Segment.new(self.vertices[1], inter2), self.vertices[2] => Segment.new(self.vertices[2], inter3), } end |
#circumcenter ⇒ Object
The circumcenter of the triangle.
The circumcenter is the center of the circumcircle.
Returns:
Point
132 133 134 135 136 137 138 139 |
# File 'lib/easy_geometry/d2/triangle.rb', line 132 def circumcenter return @circumcenter if defined?(@circumcenter) a, b, c = self.sides.map { |side| side.perpendicular_bisector } @circumcenter = a.intersection(b)[0] @circumcenter end |
#circumcircle ⇒ Object
The circle which passes through the three vertices of the triangle.
Returns:
Circle
155 156 157 |
# File 'lib/easy_geometry/d2/triangle.rb', line 155 def circumcircle # Circle.new(self.circumcenter, self.circumradius) end |
#circumradius ⇒ Object
The radius of the circumcircle of the triangle.
Returns:
Numeric
146 147 148 |
# File 'lib/easy_geometry/d2/triangle.rb', line 146 def circumradius @circumradius ||= self.vertices[0].distance(self.circumcenter) end |
#eulerline ⇒ Object
The Euler line of the triangle. The line which passes through circumcenter, centroid and orthocenter.
Returns:
Line (or Point for equilateral triangles in which case all
centers coincide)
307 308 309 310 |
# File 'lib/easy_geometry/d2/triangle.rb', line 307 def eulerline return self.orthocenter if self.is_equilateral? Line.new(self.orthocenter, self.circumcenter) end |
#exradii ⇒ Object
The radius of excircles of a triangle.
An excircle of the triangle is a circle lying outside the triangle, tangent to one of its sides and tangent to the extensions of the other two.
Returns:
Hash
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/easy_geometry/d2/triangle.rb', line 238 def exradii return @exradii if defined?(@exradii) a = self.sides[0].length b = self.sides[1].length c = self.sides[2].length s = (a + b + c) / 2 area = self.area @exradii = { self.sides[0] => area / (s - a), self.sides[1] => area / (s - b), self.sides[2] => area / (s - c) } @exradii end |
#incenter ⇒ Object
The center of the incircle.
The incircle is the circle which lies inside the triangle and touches all three sides.
Returns:
Point
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/easy_geometry/d2/triangle.rb', line 191 def incenter return @incenter if defined?(@incenter) s = self.sides l = [1, 2, 0].map { |i| s[i].length } p = l.sum x_arr = self.vertices.map { |v| v.x / p } y_arr = self.vertices.map { |v| v.y / p } x = l[0] * x_arr[0] + l[1] * x_arr[1] + l[2] * x_arr[2] y = l[0] * y_arr[0] + l[1] * y_arr[1] + l[2] * y_arr[2] @incenter = Point.new(x, y) @incenter end |
#incircle ⇒ Object
The incircle of the triangle.
The incircle is the circle which lies inside the triangle and touches all three sides.
Returns:
Circle
225 226 227 |
# File 'lib/easy_geometry/d2/triangle.rb', line 225 def incircle # Circle.new(self.incenter, self.inradius) end |
#inradius ⇒ Object
The radius of the incircle.
Returns:
Numeric
213 214 215 |
# File 'lib/easy_geometry/d2/triangle.rb', line 213 def inradius @inradius ||= 2 * self.area / self.perimeter end |
#is_equilateral? ⇒ Boolean
Are all the sides the same length? Precision - 10e-13
Returns:
bool
43 44 45 46 47 |
# File 'lib/easy_geometry/d2/triangle.rb', line 43 def is_equilateral? lengths = self.sides.map { |side| side.length } lengths = lengths.map { |l| l - lengths.first } return lengths.reject { |l| l.abs < EQUITY_TOLERANCE }.length == 0 end |
#is_isosceles? ⇒ Boolean
Are two or more of the sides the same length? Precision - 10e-13
Returns:
bool
55 56 57 |
# File 'lib/easy_geometry/d2/triangle.rb', line 55 def is_isosceles? has_dups(self.sides.map { |side| side.length }) end |
#is_right? ⇒ Boolean
Is the triangle right-angled.
Returns:
bool
74 75 76 77 78 79 80 |
# File 'lib/easy_geometry/d2/triangle.rb', line 74 def is_right? s = self.sides s[0].perpendicular_to?(s[1]) || s[1].perpendicular_to?(s[2]) || s[0].perpendicular_to?(s[2]) end |
#is_scalene? ⇒ Boolean
Are all the sides of the triangle of different lengths? Precision - 10e-13
Returns:
bool
65 66 67 |
# File 'lib/easy_geometry/d2/triangle.rb', line 65 def is_scalene? !has_dups(self.sides.map { |side| side.length }) end |
#is_similar?(other) ⇒ Boolean
23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/easy_geometry/d2/triangle.rb', line 23 def is_similar?(other) return false unless other.is_a?(Triangle) s1_1, s1_2, s1_3 = self.sides.map {|side| side.length} s2 = other.sides.map {|side| side.length} are_similar?(s1_1, s1_2, s1_3, *s2) || are_similar?(s1_1, s1_3, s1_2, *s2) || are_similar?(s1_2, s1_1, s1_3, *s2) || are_similar?(s1_2, s1_3, s1_1, *s2) || are_similar?(s1_3, s1_1, s1_2, *s2) || are_similar?(s1_3, s1_2, s1_1, *s2) end |
#medial ⇒ Object
The medial triangle of the triangle. The triangle which is formed from the midpoints of the three sides.
Returns:
Triangle
279 280 281 282 283 284 285 |
# File 'lib/easy_geometry/d2/triangle.rb', line 279 def medial @medial ||= Triangle.new( self.sides[0].midpoint, self.sides[1].midpoint, self.sides[2].midpoint ) end |
#medians ⇒ Object
The medians of the triangle.
A median of a triangle is a straight line through a vertex and the midpoint of the opposite side, and divides the triangle into two equal areas.
Returns:
Hash (each key is a vertex (Point) and each value is the median (Segment)
at that point.)
265 266 267 268 269 270 271 |
# File 'lib/easy_geometry/d2/triangle.rb', line 265 def medians @medians ||= { self.vertices[0] => Segment.new(self.vertices[0], self.sides[1].midpoint), self.vertices[1] => Segment.new(self.vertices[1], self.sides[2].midpoint), self.vertices[2] => Segment.new(self.vertices[2], self.sides[0].midpoint) } end |
#nine_point_circle ⇒ Object
The nine-point circle of the triangle.
Nine-point circle is the circumcircle of the medial triangle, which passes through the feet of altitudes and the middle points of segments connecting the vertices and the orthocenter.
Returns:
Circle
296 297 298 |
# File 'lib/easy_geometry/d2/triangle.rb', line 296 def nine_point_circle # Circle.new(*self.medial.vertices) end |
#orthocenter ⇒ Object
The orthocenter of the triangle.
The orthocenter is the intersection of the altitudes of a triangle. It may lie inside, outside or on the triangle.
Returns:
Point
112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/easy_geometry/d2/triangle.rb', line 112 def orthocenter return @orthocenter if defined?(@orthocenter) a = self.altitudes a1 = a[self.vertices[0]]; a2 = a[self.vertices[1]] l1 = Line.new(a1.p1, a1.p2) l2 = Line.new(a2.p1, a2.p2) @orthocenter = l1.intersection(l2)[0] @orthocenter end |