omdl  v0.6.1
OpenSCAD Mechanical Design Library
math_triangle.scad
Go to the documentation of this file.
1 //! Triangle solutions mathematical functions.
2 /***************************************************************************//**
3  \file math_triangle.scad
4  \author Roy Allen Sutton
5  \date 2015-2017
6 
7  \copyright
8 
9  This file is part of [omdl] (https://github.com/royasutton/omdl),
10  an OpenSCAD mechanical design library.
11 
12  The \em omdl is free software; you can redistribute it and/or modify
13  it under the terms of the [GNU Lesser General Public License]
14  (http://www.gnu.org/licenses/lgpl.html) as published by the Free
15  Software Foundation; either version 2.1 of the License, or (at
16  your option) any later version.
17 
18  The \em omdl is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Lesser General Public License for more details.
22 
23  You should have received a copy of the GNU Lesser General Public
24  License along with the \em omdl; if not, write to the Free Software
25  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26  02110-1301, USA; or see <http://www.gnu.org/licenses/>.
27 
28  \details
29 
30  \ingroup math math_triangle
31 *******************************************************************************/
32 
33 include <math-base.scad>;
34 
35 //----------------------------------------------------------------------------//
36 /***************************************************************************//**
37  \addtogroup math
38  @{
39 
40  \defgroup math_triangle Triangles
41  \brief Triangle mathematical functions.
42 
43  \details
44 
45  See [Wikipedia](https://en.wikipedia.org/wiki/Triangle)
46  for more information.
47 
48  @{
49 *******************************************************************************/
50 //----------------------------------------------------------------------------//
51 
52 //! Compute the vertex coordinates of a triangle given its side lengths.
53 /***************************************************************************//**
54  \param s1 <decimal> The length of the side 1.
55  \param s2 <decimal> The length of the side 2.
56  \param s3 <decimal> The length of the side 3.
57  \param cw <boolean> Order vertices clockwise.
58 
59  \returns <coords-2d> A list of vertex coordinates [v1, v2, v3].
60 
61  \details
62 
63  Geometry requires that \p s1 + \p s2 is greater then \p s3. A
64  coordinates will be \b 'nan' when specified triangle does not
65  exists.
66 
67  \note Vertex \p v1 at the origin. Side length \p s1 is measured
68  along the positive x-axis.
69 *******************************************************************************/
70 function triangle_sss2lp
71 (
72  s1,
73  s2,
74  s3,
75  cw = true
76 ) =
77  let
78  (
79  v1 = origin2d,
80  v2 = [s1, 0],
81  v3 = [(s1*s1 + s3*s3 - (s2*s2)) / (2*s1),
82  sqrt(s3*s3 - pow((s1*s1 + s3*s3 - (s2*s2)) / (2*s1), 2))]
83  )
84  (cw == true) ? [v1, v3, v2] : [v1, v2, v3];
85 
86 //! Compute the vertex coordinates of a triangle given its side lengths.
87 /***************************************************************************//**
88  \param v <decimal-list-3> The list of side lengths [s1, s2, s3].
89  \param cw <boolean> Order vertices clockwise.
90 
91  \returns <coords-2d> A list of vertex coordinates [v1, v2, v3].
92 
93  \details
94 
95  Geometry requires that \p s1 + \p s2 is greater then \p s3. A
96  coordinates will be \b 'nan' when specified triangle does not
97  exists.
98 
99  \note Vertex \p v1 at the origin. Side length \p s1 is measured
100  along the positive x-axis.
101 *******************************************************************************/
102 function triangle_ls2lp
103 (
104  v,
105  cw = true
106 ) = triangle_sss2lp( s1=v[0], s2=v[1], s3=v[2], cw=cw );
107 
108 //! Compute the side lengths of a triangle given its vertex coordinates.
109 /***************************************************************************//**
110  \param v1 <point-2d> A vertex coordinate [x, y] for vertex 1.
111  \param v2 <point-2d> A vertex coordinate [x, y] for vertex 2.
112  \param v3 <point-2d> A vertex coordinate [x, y] for vertex 3.
113 
114  \returns <decimal-list-3> A list of side lengths [s1, s2, s3].
115 
116  \note Side lengths ordered according to vertex ordering.
117 *******************************************************************************/
118 function triangle_ppp2ls
119 (
120  v1,
121  v2,
122  v3
123 ) = [ distance_pp(v1, v2), distance_pp(v2, v3), distance_pp(v3, v1) ];
124 
125 //! Compute the side lengths of a triangle given its vertex coordinates.
126 /***************************************************************************//**
127  \param v <coords-2d> A list of vertex coordinates [v1, v2, v3].
128 
129  \returns <decimal-list-3> A list of side lengths [s1, s2, s3].
130 
131  \note Side lengths ordered according to vertex ordering.
132 *******************************************************************************/
133 function triangle_lp2ls
134 (
135  v
136 ) = triangle_ppp2ls( v1=v[0], v2=v[1], v3=v[2]);
137 
138 //! Compute the signed area of a triangle given its vertex coordinates.
139 /***************************************************************************//**
140  \param v1 <point-2d> A vertex coordinate [x, y] for vertex 1.
141  \param v2 <point-2d> A vertex coordinate [x, y] for vertex 2.
142  \param v3 <point-2d> A vertex coordinate [x, y] for vertex 3.
143  \param s <boolean> Return the vertex ordering sign.
144 
145  \returns <decimal> The area of the given triangle.
146 *******************************************************************************/
147 function triangle_area_ppp
148 (
149  v1,
150  v2,
151  v3,
152  s = false
153 ) =
154  let( sa = is_left_ppp(p1=v1, p2=v2, p3=v3) / 2 )
155  (s == false) ? abs(sa) : sa;
156 
157 //! Compute the signed area of a triangle given its vertex coordinates.
158 /***************************************************************************//**
159  \param v <coords-2d> A list of vertex coordinates [v1, v2, v3].
160  \param s <boolean> Return the vertex ordering sign.
161 
162  \returns <decimal> The area of the given triangle.
163 *******************************************************************************/
164 function triangle_area_lp
165 (
166  v,
167  s = false
168 ) =
169  let( sa = is_left_ppp(p1=v[0], p2=v[1], p3=v[2]) / 2 )
170  (s == false) ? abs(sa) : sa;
171 
172 //! Compute the centroid (geometric center) of a triangle.
173 /***************************************************************************//**
174  \param v1 <point-2d> A vertex coordinate [x, y] for vertex 1.
175  \param v2 <point-2d> A vertex coordinate [x, y] for vertex 2.
176  \param v3 <point-2d> A vertex coordinate [x, y] for vertex 3.
177 
178  \returns <point-2d> The centroid coordinate point [x, y].
179 *******************************************************************************/
180 function triangle_centroid_ppp
181 (
182  v1,
183  v2,
184  v3
185 ) = [ (v1[0] + v2[0] + v3[0])/3, (v1[1] + v2[1] + v3[1])/3 ];
186 
187 //! Compute the centroid (geometric center) of a triangle.
188 /***************************************************************************//**
189  \param v <coords-2d> A list of vertex coordinates [v1, v2, v3].
190 
191  \returns <point-2d> The centroid coordinate point [x, y].
192 *******************************************************************************/
193 function triangle_centroid_lp
194 (
195  v
196 ) = triangle_centroid_ppp( v1=v[0], v2=v[1], v3=v[2]);
197 
198 //! Compute the coordinate for the triangle's incircle.
199 /***************************************************************************//**
200  \param v1 <point-2d> A vertex coordinate [x, y] for vertex 1.
201  \param v2 <point-2d> A vertex coordinate [x, y] for vertex 2.
202  \param v3 <point-2d> A vertex coordinate [x, y] for vertex 3.
203 
204  \returns <point-2d> The incircle coordinate point [x, y].
205 
206  \details
207 
208  The interior point for which distances to the sides of the triangle
209  are equal.
210 *******************************************************************************/
211 function triangle_incenter_ppp
212 (
213  v1,
214  v2,
215  v3
216 ) =
217 [
218  (
219  (
220  v1[0] * distance_pp(v2, v3)
221  + v2[0] * distance_pp(v3, v1)
222  + v3[0] * distance_pp(v1, v2)
223  )
224  / ( distance_pp(v1, v2) + distance_pp(v2, v3) + distance_pp(v3, v1) )
225  ),
226  (
227  (
228  v1[1] * distance_pp(v2, v3)
229  + v2[1] * distance_pp(v3, v1)
230  + v3[1] * distance_pp(v1, v2)
231  )
232  / ( distance_pp(v1, v2) + distance_pp(v2, v3) + distance_pp(v3, v1) )
233  )
234 ];
235 
236 //! Compute the coordinate for the triangle's incircle.
237 /***************************************************************************//**
238  \param v <coords-2d> A list of vertex coordinates [v1, v2, v3].
239 
240  \returns <point-2d> The incircle coordinate point [x, y].
241 
242  \details
243 
244  The interior point for which distances to the sides of the triangle
245  are equal.
246 *******************************************************************************/
247 function triangle_incenter_lp
248 (
249  v
250 ) = triangle_incenter_ppp( v1=v[0], v2=v[1], v3=v[2]);
251 
252 //! Compute the inradius of a triangle's incircle.
253 /***************************************************************************//**
254  \param v1 <point-2d> A vertex coordinate [x, y] for vertex 1.
255  \param v2 <point-2d> A vertex coordinate [x, y] for vertex 2.
256  \param v3 <point-2d> A vertex coordinate [x, y] for vertex 3.
257 
258  \returns <decimal> The incircle radius.
259 *******************************************************************************/
260 function triangle_inradius_ppp
261 (
262  v1,
263  v2,
264  v3
265 ) =
266 sqrt
267 (
268  (
269  ( - distance_pp(v1, v2) + distance_pp(v2, v3) + distance_pp(v3, v1) )
270  * ( + distance_pp(v1, v2) - distance_pp(v2, v3) + distance_pp(v3, v1) )
271  * ( + distance_pp(v1, v2) + distance_pp(v2, v3) - distance_pp(v3, v1) )
272  )
273  / ( distance_pp(v1, v2) + distance_pp(v2, v3) + distance_pp(v3, v1) )
274 ) / 2;
275 
276 //! Compute the inradius of a triangle's incircle.
277 /***************************************************************************//**
278  \param v <coords-2d> A list of vertex coordinates [v1, v2, v3].
279 
280  \returns <decimal> The incircle radius.
281 *******************************************************************************/
282 function triangle_inradius_lp
283 (
284  v
285 ) = triangle_inradius_ppp( v1=v[0], v2=v[1], v3=v[2]);
286 
287 //! Test the vertex ordering, or orientation, of a triangle.
288 /***************************************************************************//**
289  \param v1 <point-2d> A vertex coordinate [x, y] for vertex 1.
290  \param v2 <point-2d> A vertex coordinate [x, y] for vertex 2.
291  \param v3 <point-2d> A vertex coordinate [x, y] for vertex 3.
292 
293  \returns <boolean> \b true if the vertices are ordered clockwise,
294  \b false if the vertices are ordered counterclockwise, and
295  \b undef if the ordering can not be determined.
296 *******************************************************************************/
297 function triangle_is_cw_ppp
298 (
299  v1,
300  v2,
301  v3
302 ) =
303  let
304  (
305  il = is_left_ppp(p1=v1, p2=v2, p3=v3)
306  )
307  (il < 0) ? true
308  : (il > 0) ? false
309  : undef;
310 
311 //! Test the vertex ordering, or orientation, of a triangle.
312 /***************************************************************************//**
313  \param v <coords-2d> A list of vertex coordinates [v1, v2, v3].
314 
315  \returns <boolean> \b true if the vertices are ordered clockwise,
316  \b false if the vertices are ordered counterclockwise, and
317  \b undef if the ordering can not be determined.
318 *******************************************************************************/
319 function triangle_is_cw_lp
320 (
321  v
322 ) =
323  let
324  (
325  il = is_left_ppp(p1=v[0], p2=v[1], p3=v[2])
326  )
327  (il < 0) ? true
328  : (il > 0) ? false
329  : undef;
330 
331 //! Test if a point is inside a triangle in a Euclidean 2d-space using Barycentric.
332 /***************************************************************************//**
333  \param v1 <point-2d> A vertex coordinate [x, y] for vertex 1.
334  \param v2 <point-2d> A vertex coordinate [x, y] for vertex 2.
335  \param v3 <point-2d> A vertex coordinate [x, y] for vertex 3.
336  \param t <point-2d> A test point coordinate [x, y].
337 
338  \returns <boolean> \b true when the point is inside the polygon and
339  \b false otherwise.
340 
341  \details
342 
343  See [Wikipedia] for more information.
344 
345  [Wikipedia]: https://en.wikipedia.org/wiki/Barycentric_coordinate_system
346 *******************************************************************************/
347 function triangle_is_pit_ppp
348 (
349  v1,
350  v2,
351  v3,
352  t
353 ) = let (d = ((v2[1]-v3[1]) * (v1[0]-v3[0]) + (v3[0]-v2[0]) * (v1[1]-v3[1])))
354  (d == 0) ? true
355  : let (a = ((v2[1]-v3[1]) * ( t[0]-v3[0]) + (v3[0]-v2[0]) * ( t[1]-v3[1])) / d)
356  (a < 0) ? false
357  : let (b = ((v3[1]-v1[1]) * ( t[0]-v3[0]) + (v1[0]-v3[0]) * ( t[1]-v3[1])) / d)
358  (b < 0) ? false
359  : ((a + b) < 1);
360 
361 //! Test if a point is inside a triangle in a Euclidean 2d-space using Barycentric.
362 /***************************************************************************//**
363  \param v <coords-2d> A list of vertex coordinates [v1, v2, v3].
364  \param t <point-2d> A test point coordinate [x, y].
365 
366  \returns <boolean> \b true when the point is inside the polygon and
367  \b false otherwise.
368 *******************************************************************************/
369 function triangle_is_pit_lp
370 (
371  v,
372  t
373 ) = triangle_is_pit_ppp(v1=v[0], v2=v[1], v3=v[2], t=t);
374 
375 //! @}
376 //! @}
377 
378 //----------------------------------------------------------------------------//
379 // end of file
380 //----------------------------------------------------------------------------//
function is_left_ppp(p1, p2, p3)
Test if a point is left, on, or right of an infinite line in a Euclidean 2d-space.
function distance_pp(p1, p2)
Compute the distance between two Euclidean points.
function triangle_area_lp(v, s=false)
Compute the signed area of a triangle given its vertex coordinates.
function triangle_ls2lp(v, cw=true)
Compute the vertex coordinates of a triangle given its side lengths.
function triangle_ppp2ls(v1, v2, v3)
Compute the side lengths of a triangle given its vertex coordinates.
function triangle_inradius_lp(v)
Compute the inradius of a triangle's incircle.
function triangle_centroid_ppp(v1, v2, v3)
Compute the centroid (geometric center) of a triangle.
function triangle_area_ppp(v1, v2, v3, s=false)
Compute the signed area of a triangle given its vertex coordinates.
function triangle_is_pit_ppp(v1, v2, v3, t)
Test if a point is inside a triangle in a Euclidean 2d-space using Barycentric.
function triangle_incenter_ppp(v1, v2, v3)
Compute the coordinate for the triangle's incircle.
function triangle_is_cw_ppp(v1, v2, v3)
Test the vertex ordering, or orientation, of a triangle.
function triangle_inradius_ppp(v1, v2, v3)
Compute the inradius of a triangle's incircle.
function triangle_centroid_lp(v)
Compute the centroid (geometric center) of a triangle.
function triangle_is_pit_lp(v, t)
Test if a point is inside a triangle in a Euclidean 2d-space using Barycentric.
function triangle_sss2lp(s1, s2, s3, cw=true)
Compute the vertex coordinates of a triangle given its side lengths.
origin2d
The origin point coordinate in 2d Euclidean space.
Definition: constants.scad:109
function triangle_incenter_lp(v)
Compute the coordinate for the triangle's incircle.
function triangle_lp2ls(v)
Compute the side lengths of a triangle given its vertex coordinates.
function triangle_is_cw_lp(v)
Test the vertex ordering, or orientation, of a triangle.