Class: EasyGeometry::D2::Triangle

Inherits:
Polygon
  • Object
show all
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

Instance Method Summary collapse

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

#verticesObject (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

#altitudesObject

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

#bisectorsObject

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

#circumcenterObject

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

#circumcircleObject

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

#circumradiusObject

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

#eulerlineObject

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

#exradiiObject

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

#incenterObject

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

#incircleObject

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

#inradiusObject

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

Returns:

  • (Boolean)


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

Returns:

  • (Boolean)


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

Returns:

  • (Boolean)


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

Returns:

  • (Boolean)


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

Is another triangle similar to this one.

Parameters:

Triangle

Returns:

bool

Returns:

  • (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

#medialObject

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

#mediansObject

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_circleObject

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

#orthocenterObject

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