1//////////////////////////////////////////////////////////////////////
2// LibFile: trigonometry.scad
3// Trigonometry shortcuts for people who can't be bothered to remember
4// all the function relations, or silly acronyms like SOHCAHTOA.
5// Includes:
6// include <BOSL2/std.scad>
7// FileGroup: Math
8// FileSummary: Trigonometry shortcuts for when you can't recall the mnemonic SOHCAHTOA.
9// FileFootnotes: STD=Included in std.scad
10//////////////////////////////////////////////////////////////////////
11
12
13
14// Section: 2D General Triangle Functions
15
16
17// Function: law_of_cosines()
18// Usage:
19// C = law_of_cosines(a, b, c);
20// c = law_of_cosines(a, b, C=);
21// Topics: Geometry, Trigonometry, Triangles
22// Description:
23// Applies the Law of Cosines for an arbitrary triangle. Given three side lengths, returns the
24// angle in degrees for the corner opposite of the third side. Given two side lengths, and the
25// angle between them, returns the length of the third side.
26// Figure(2D):
27// stroke([[-50,0], [10,60], [50,0]], closed=true);
28// color("black") {
29// translate([ 33,35]) text(text="a", size=8, halign="center", valign="center");
30// translate([ 0,-6]) text(text="b", size=8, halign="center", valign="center");
31// translate([-22,35]) text(text="c", size=8, halign="center", valign="center");
32// }
33// color("blue") {
34// translate([-37, 6]) text(text="A", size=8, halign="center", valign="center");
35// translate([ 9,51]) text(text="B", size=8, halign="center", valign="center");
36// translate([ 38, 6]) text(text="C", size=8, halign="center", valign="center");
37// }
38// Arguments:
39// a = The length of the first side.
40// b = The length of the second side.
41// c = The length of the third side.
42// ---
43// C = The angle in degrees of the corner opposite of the third side.
44// See Also: law_of_sines()
45function law_of_cosines(a, b, c, C) =
46 // Triangle Law of Cosines:
47 // c^2 = a^2 + b^2 - 2*a*b*cos(C)
48 assert(num_defined([c,C]) == 1, "Must give exactly one of c= or C=.")
49 is_undef(c) ? sqrt(a*a + b*b - 2*a*b*cos(C)) :
50 acos(constrain((a*a + b*b - c*c) / (2*a*b), -1, 1));
51
52
53// Function: law_of_sines()
54// Usage:
55// B = law_of_sines(a, A, b);
56// b = law_of_sines(a, A, B=);
57// Topics: Geometry, Trigonometry, Triangles
58// Description:
59// Applies the Law of Sines for an arbitrary triangle. Given two triangle side lengths and the
60// angle between them, returns the angle of the corner opposite of the second side. Given a side
61// length, the opposing angle, and a second angle, returns the length of the side opposite of the
62// second angle.
63// Figure(2D):
64// stroke([[-50,0], [10,60], [50,0]], closed=true);
65// color("black") {
66// translate([ 33,35]) text(text="a", size=8, halign="center", valign="center");
67// translate([ 0,-6]) text(text="b", size=8, halign="center", valign="center");
68// translate([-22,35]) text(text="c", size=8, halign="center", valign="center");
69// }
70// color("blue") {
71// translate([-37, 6]) text(text="A", size=8, halign="center", valign="center");
72// translate([ 9,51]) text(text="B", size=8, halign="center", valign="center");
73// translate([ 38, 6]) text(text="C", size=8, halign="center", valign="center");
74// }
75// Arguments:
76// a = The length of the first side.
77// A = The angle in degrees of the corner opposite of the first side.
78// b = The length of the second side.
79// ---
80// B = The angle in degrees of the corner opposite of the second side.
81// See Also: law_of_cosines()
82function law_of_sines(a, A, b, B) =
83 // Triangle Law of Sines:
84 // a/sin(A) = b/sin(B) = c/sin(C)
85 assert(num_defined([b,B]) == 1, "Must give exactly one of b= or B=.")
86 let( r = a/sin(A) )
87 is_undef(b) ? r*sin(B) :
88 asin(constrain(b/r, -1, 1));
89
90
91
92// Section: 2D Right Triangle Functions
93// This is a set of functions to make it easier to perform trig calculations on right triangles.
94// In general, all these functions are named using these abbreviations:
95// - **hyp**: The length of the Hypotenuse.
96// - **adj**: The length of the side adjacent to the angle.
97// - **opp**: The length of the side opposite to the angle.
98// - **ang**: The angle size in degrees.
99// .
100// If you know two of those, and want to know the value of a third, you will need to call a
101// function named like `AAA_BBB_to_CCC()`. For example, if you know the length of the hypotenuse,
102// and the length of the side adjacent to the angle, and want to learn the length of the side
103// opposite to the angle, you will call `opp = hyp_adj_to_opp(hyp,adj);`.
104// Figure(2D):
105// color("brown") {
106// stroke([[40,0], [40,10], [50,10]]);
107// left(50) stroke(arc(r=37,angle=30));
108// }
109// color("lightgreen") stroke([[-50,0], [50,60], [50,0]], closed=true);
110// color("black") {
111// translate([ 62,25]) text(text="opp", size=8, halign="center", valign="center");
112// translate([ 0,-6]) text(text="adj", size=8, halign="center", valign="center");
113// translate([ 0,40]) text(text="hyp", size=8, halign="center", valign="center");
114// translate([-25, 5]) text(text="ang", size=7, halign="center", valign="center");
115// }
116
117
118// Function: hyp_opp_to_adj()
119// Alias: opp_hyp_to_adj()
120// Usage:
121// adj = hyp_opp_to_adj(hyp,opp);
122// adj = opp_hyp_to_adj(opp,hyp);
123// Topics: Geometry, Trigonometry, Triangles
124// Description:
125// Given the lengths of the hypotenuse and opposite side of a right triangle, returns the length
126// of the adjacent side.
127// Arguments:
128// hyp = The length of the hypotenuse of the right triangle.
129// opp = The length of the side of the right triangle that is opposite from the primary angle.
130// Example:
131// hyp = hyp_opp_to_adj(5,3); // Returns: 4
132function hyp_opp_to_adj(hyp,opp) =
133 assert(is_finite(hyp+opp) && hyp>=0 && opp>=0,
134 "Triangle side lengths should be a positive numbers." )
135 sqrt(hyp*hyp-opp*opp);
136
137function opp_hyp_to_adj(opp,hyp) = hyp_opp_to_adj(hyp,opp);
138
139
140// Function: hyp_ang_to_adj()
141// Alias: ang_hyp_to_adj()
142// Usage:
143// adj = hyp_ang_to_adj(hyp,ang);
144// adj = ang_hyp_to_adj(ang,hyp);
145// Topics: Geometry, Trigonometry, Triangles
146// Description:
147// Given the length of the hypotenuse and the angle of the primary corner of a right triangle,
148// returns the length of the adjacent side.
149// Arguments:
150// hyp = The length of the hypotenuse of the right triangle.
151// ang = The angle in degrees of the primary corner of the right triangle.
152// Example:
153// adj = hyp_ang_to_adj(8,60); // Returns: 4
154function hyp_ang_to_adj(hyp,ang) =
155 assert(is_finite(hyp) && hyp>=0, "Triangle side length should be a positive number." )
156 assert(is_finite(ang) && ang>-90 && ang<90, "The angle should be an acute angle." )
157 hyp*cos(ang);
158
159function ang_hyp_to_adj(ang,hyp) = hyp_ang_to_adj(hyp, ang);
160
161
162// Function: opp_ang_to_adj()
163// Alias: ang_opp_to_adj()
164// Usage:
165// adj = opp_ang_to_adj(opp,ang);
166// adj = ang_opp_to_adj(ang,opp);
167// Topics: Geometry, Trigonometry, Triangles
168// Description:
169// Given the angle of the primary corner of a right triangle, and the length of the side opposite of it,
170// returns the length of the adjacent side.
171// Arguments:
172// opp = The length of the side of the right triangle that is opposite from the primary angle.
173// ang = The angle in degrees of the primary corner of the right triangle.
174// Example:
175// adj = opp_ang_to_adj(8,30); // Returns: 4
176function opp_ang_to_adj(opp,ang) =
177 assert(is_finite(opp) && opp>=0, "Triangle side length should be a positive number." )
178 assert(is_finite(ang) && ang>-90 && ang<90, "The angle should be an acute angle." )
179 opp/tan(ang);
180
181function ang_opp_to_adj(ang,opp) = opp_ang_to_adj(opp,ang);
182
183
184// Function: hyp_adj_to_opp()
185// Alias: adj_hyp_to_opp()
186// Usage:
187// opp = hyp_adj_to_opp(hyp,adj);
188// opp = adj_hyp_to_opp(adj,hyp);
189// Topics: Geometry, Trigonometry, Triangles
190// Description:
191// Given the length of the hypotenuse and the adjacent side, returns the length of the opposite side.
192// Arguments:
193// hyp = The length of the hypotenuse of the right triangle.
194// adj = The length of the side of the right triangle that is adjacent to the primary angle.
195// Example:
196// opp = hyp_adj_to_opp(5,4); // Returns: 3
197function hyp_adj_to_opp(hyp,adj) =
198 assert(is_finite(hyp) && hyp>=0 && is_finite(adj) && adj>=0,
199 "Triangle side lengths should be a positive numbers." )
200 sqrt(hyp*hyp-adj*adj);
201
202function adj_hyp_to_opp(adj,hyp) = hyp_adj_to_opp(hyp,adj);
203
204
205// Function: hyp_ang_to_opp()
206// Alias: ang_hyp_to_opp()
207// Usage:
208// opp = hyp_ang_to_opp(hyp,ang);
209// opp = ang_hyp_to_opp(ang,hyp);
210// Topics: Geometry, Trigonometry, Triangles
211// Description:
212// Given the length of the hypotenuse of a right triangle, and the angle of the corner, returns the length of the opposite side.
213// Arguments:
214// hyp = The length of the hypotenuse of the right triangle.
215// ang = The angle in degrees of the primary corner of the right triangle.
216// Example:
217// opp = hyp_ang_to_opp(8,30); // Returns: 4
218function hyp_ang_to_opp(hyp,ang) =
219 assert(is_finite(hyp)&&hyp>=0, "Triangle side length should be a positive number." )
220 assert(is_finite(ang) && ang>-90 && ang<90, "The angle should be an acute angle." )
221 hyp*sin(ang);
222
223function ang_hyp_to_opp(ang,hyp) = hyp_ang_to_opp(hyp,ang);
224
225
226// Function: adj_ang_to_opp()
227// Alias: ang_adj_to_opp()
228// Usage:
229// opp = adj_ang_to_opp(adj,ang);
230// opp = ang_adj_to_opp(ang,adj);
231// Topics: Geometry, Trigonometry, Triangles
232// Description:
233// Given the length of the adjacent side of a right triangle, and the angle of the corner, returns the length of the opposite side.
234// Arguments:
235// adj = The length of the side of the right triangle that is adjacent to the primary angle.
236// ang = The angle in degrees of the primary corner of the right triangle.
237// Example:
238// opp = adj_ang_to_opp(8,45); // Returns: 8
239function adj_ang_to_opp(adj,ang) =
240 assert(is_finite(adj)&&adj>=0, "Triangle side length should be a positive number." )
241 assert(is_finite(ang) && ang>-90 && ang<90, "The angle should be an acute angle." )
242 adj*tan(ang);
243
244function ang_adj_to_opp(ang,adj) = adj_ang_to_opp(adj,ang);
245
246
247// Function: adj_opp_to_hyp()
248// Alias: opp_adj_to_hyp()
249// Usage:
250// hyp = adj_opp_to_hyp(adj,opp);
251// hyp = opp_adj_to_hyp(opp,adj);
252// Topics: Geometry, Trigonometry, Triangles
253// Description:
254// Given the length of the adjacent and opposite sides of a right triangle, returns the length of thee hypotenuse.
255// Arguments:
256// adj = The length of the side of the right triangle that is adjacent to the primary angle.
257// opp = The length of the side of the right triangle that is opposite from the primary angle.
258// Example:
259// hyp = adj_opp_to_hyp(3,4); // Returns: 5
260function adj_opp_to_hyp(adj,opp) =
261 assert(is_finite(opp) && opp>=0 && is_finite(adj) && adj>=0,
262 "Triangle side lengths should be a positive numbers." )
263 norm([opp,adj]);
264
265function opp_adj_to_hyp(opp,adj) = adj_opp_to_hyp(adj,opp);
266
267
268// Function: adj_ang_to_hyp()
269// Alias: ang_adj_to_hyp()
270// Usage:
271// hyp = adj_ang_to_hyp(adj,ang);
272// hyp = ang_adj_to_hyp(ang,adj);
273// Topics: Geometry, Trigonometry, Triangles
274// Description:
275// For a right triangle, given the length of the adjacent side, and the corner angle, returns the length of the hypotenuse.
276// Arguments:
277// adj = The length of the side of the right triangle that is adjacent to the primary angle.
278// ang = The angle in degrees of the primary corner of the right triangle.
279// Example:
280// hyp = adj_ang_to_hyp(4,60); // Returns: 8
281function adj_ang_to_hyp(adj,ang) =
282 assert(is_finite(adj) && adj>=0, "Triangle side length should be a positive number." )
283 assert(is_finite(ang) && ang>-90 && ang<90, "The angle should be an acute angle." )
284 adj/cos(ang);
285
286function ang_adj_to_hyp(ang,adj) = adj_ang_to_hyp(adj,ang);
287
288
289// Function: opp_ang_to_hyp()
290// Alias: ang_opp_to_hyp()
291// Usage:
292// hyp = opp_ang_to_hyp(opp,ang);
293// hyp = ang_opp_to_hyp(ang,opp);
294// Topics: Geometry, Trigonometry, Triangles
295// Description:
296// For a right triangle, given the length of the opposite side, and the corner angle, returns the length of the hypotenuse.
297// Arguments:
298// opp = The length of the side of the right triangle that is opposite from the primary angle.
299// ang = The angle in degrees of the primary corner of the right triangle.
300// Example:
301// hyp = opp_ang_to_hyp(4,30); // Returns: 8
302function opp_ang_to_hyp(opp,ang) =
303 assert(is_finite(opp) && opp>=0, "Triangle side length should be a positive number." )
304 assert(is_finite(ang) && ang>-90 && ang<90, "The angle should be an acute angle." )
305 opp/sin(ang);
306
307function ang_opp_to_hyp(ang,opp) = opp_ang_to_hyp(opp,ang);
308
309
310// Function: hyp_adj_to_ang()
311// Alias: adj_hyp_to_ang()
312// Usage:
313// ang = hyp_adj_to_ang(hyp,adj);
314// ang = adj_hyp_to_ang(adj,hyp);
315// Description:
316// For a right triangle, given the lengths of the hypotenuse and the adjacent sides, returns the angle of the corner.
317// Arguments:
318// hyp = The length of the hypotenuse of the right triangle.
319// adj = The length of the side of the right triangle that is adjacent to the primary angle.
320// Example:
321// ang = hyp_adj_to_ang(8,4); // Returns: 60 degrees
322function hyp_adj_to_ang(hyp,adj) =
323 assert(is_finite(hyp) && hyp>0 && is_finite(adj) && adj>=0,
324 "Triangle side lengths should be positive numbers." )
325 acos(adj/hyp);
326
327function adj_hyp_to_ang(adj,hyp) = hyp_adj_to_ang(hyp,adj);
328
329
330// Function: hyp_opp_to_ang()
331// Alias: opp_hyp_to_ang()
332// Usage:
333// ang = hyp_opp_to_ang(hyp,opp);
334// ang = opp_hyp_to_ang(opp,hyp);
335// Topics: Geometry, Trigonometry, Triangles
336// Description:
337// For a right triangle, given the lengths of the hypotenuse and the opposite sides, returns the angle of the corner.
338// Arguments:
339// hyp = The length of the hypotenuse of the right triangle.
340// opp = The length of the side of the right triangle that is opposite from the primary angle.
341// Example:
342// ang = hyp_opp_to_ang(8,4); // Returns: 30 degrees
343function hyp_opp_to_ang(hyp,opp) =
344 assert(is_finite(hyp+opp) && hyp>0 && opp>=0,
345 "Triangle side lengths should be positive numbers." )
346 asin(opp/hyp);
347
348function opp_hyp_to_ang(opp,hyp) = hyp_opp_to_ang(hyp,opp);
349
350
351// Function: adj_opp_to_ang()
352// Alias: opp_adj_to_ang()
353// Usage:
354// ang = adj_opp_to_ang(adj,opp);
355// ang = opp_adj_to_ang(opp,adj);
356// Topics: Geometry, Trigonometry, Triangles
357// Description:
358// For a right triangle, given the lengths of the adjacent and opposite sides, returns the angle of the corner.
359// Arguments:
360// adj = The length of the side of the right triangle that is adjacent to the primary angle.
361// opp = The length of the side of the right triangle that is opposite from the primary angle.
362// Example:
363// ang = adj_opp_to_ang(sqrt(3)/2,0.5); // Returns: 30 degrees
364function adj_opp_to_ang(adj,opp) =
365 assert(is_finite(adj+opp) && adj>0 && opp>=0,
366 "Triangle side lengths should be positive numbers." )
367 atan2(opp,adj);
368
369function opp_adj_to_ang(opp,adj) = adj_opp_to_ang(adj,opp);
370
371
372
373// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap