openjscad-aurora-webapp
160 строк · 4.4 Кб
1/*
2License: This code is placed in the public Domain
3Contributed By: Willliam A Adams
4August 2011
5*/
6
7// A couple of useful constants
8Cpi = 3.14159;
9Cphi = 1.61803399;
10Cepsilon = 0.00000001;
11
12
13// Function: clean
14//
15// Parameters:
16// n - A number that might be very close to zero
17// Description:
18// There are times when you want a very small number to
19// just be zero, instead of being that very small number.
20// This function will compare the number to an arbitrarily small
21// number. If it is smaller than the 'epsilon', then zero will be
22// returned. Otherwise, the original number will be returned.
23//
24
25function clean(n) = (n < 0) ? ((n < -Cepsilon) ? n : 0) :
26(n < Cepsilon) ? 0 : n;
27
28// Function: safediv
29//
30// Parameters
31// n - The numerator
32// d - The denominator
33//
34// Description:
35// Since division by zero is generally not a desirable thing, safediv
36// will return '0' whenever there is a division by zero. Although this will
37// mask some erroneous division by zero errors, it is often the case
38// that you actually want this behavior. So, it makes it convenient.
39function safediv(n,d) = (d==0) ? 0 : n/d;
40
41
42//==================================
43// Degrees
44//==================================
45
46function DEGREES(radians) = (180/Cpi) * radians;
47
48function RADIANS(degrees) = Cpi/180 * degrees;
49
50function deg(deg, min=0, sec=0) = [deg, min, sec];
51
52function deg_to_dec(d) = d[0] + d[1]/60 + d[2]/60/60;
53
54
55//==================================
56// Spherical coordinates
57//==================================
58
59// create an instance of a spherical coordinate
60// long - rotation around z -axis
61// lat - latitude, starting at 0 == 'north pole'
62// rad - distance from center
63function sph(long, lat, rad=1) = [long, lat, rad];
64
65// Convert spherical to cartesian
66function sph_to_cart(s) = [
67clean(s[2]*sin(s[1])*cos(s[0])),
68clean(s[2]*sin(s[1])*sin(s[0])),
69clean(s[2]*cos(s[1]))
70];
71
72// Convert from cartesian to spherical
73function sph_from_cart(c) = sph(
74atan2(c[1],c[0]),
75atan2(sqrt(c[0]*c[0]+c[1]*c[1]), c[2]),
76sqrt(c[0]*c[0]+c[1]*c[1]+c[2]*c[2])
77);
78
79function sphu_from_cart(c, rad=1) = sph(
80atan2(c[1],c[0]),
81atan2(sqrt(c[0]*c[0]+c[1]*c[1]), c[2]),
82rad
83);
84
85// compute the chord distance between two points on a sphere
86function sph_dist(c1, c2) = sqrt(
87c1[2]*c1[2] + c2[2]*c2[2] -
882*c1[2]*c2[2]*
89((cos(c1[1])*cos(c2[1])) + cos(c1[0]-c2[0])*sin(c1[1])*sin(c2[1]))
90);
91
92
93//==========================================
94// Geodesic calculations
95//
96// Reference: Geodesic Math and How to Use It
97// By: Hugh Kenner
98// Second Paperback Edition (2003), p.74-75
99// http://www.amazon.com/Geodesic-Math-How-Hugh-Kenner/dp/0520239318
100//
101// The book was used for reference, so if you want to check the math,
102// you can plug in various numbers to various routines and see if you get
103// the same numbers in the book.
104//
105// In general, there are enough routines here to implement the various
106// pieces necessary to make geodesic objects.
107//==========================================
108
109function poly_sum_interior_angles(sides) = (sides-2)*180;
110function poly_single_interior_angle(pq) = poly_sum_interior_angles(pq[0])/pq[0];
111
112
113
114// Given a set of coordinates, return the frequency
115// Simply calculated by adding up the values of the coordinates
116function geo_freq(xyz) = xyz[0]+xyz[1]+xyz[2];
117
118// Convert between the 2D coordinates of vertices on the face triangle
119// to the 3D vertices needed to calculate spherical coordinates
120function geo_tri2_tri3(xyf) = [xyf[1], xyf[0]-xyf[1], xyf[2]-xyf[0]];
121
122// Given coordinates for a vertex on the octahedron face
123// return the spherical coordinates for the vertex
124// class 1, method 1
125function octa_class1(c) = sph(
126atan(safediv(c[0], c[1])),
127atan(sqrt(c[0]*c[0]+c[1]*c[1])/c[2]),
1281
129);
130
131function octa_class2(c) = sph(
132atan(c[0]/c[1]),
133atan( sqrt( 2*(c[0]*c[0]+c[1]*c[1])) /c[2]),
1341
135);
136
137function icosa_class1(c) = octa_class1(
138[
139c[0]*sin(72),
140c[1]+c[0]*cos(72),
141geo_freq(c)/2+c[2]/Cphi
142]);
143
144function icosa_class2(c) = sph(
145atan([c0]/c[1]),
146atan(sqrt(c[0]*c[0]+c[1]*c[1]))/cos(36)*c[2],
1471
148);
149
150function tetra_class1(c) = octa_class1(
151[
152sqrt(3*c[0]),
1532*c[1]-c[0],
154(3*c[2]-c[0]-c[1])/sqrt(2)
155]);
156
157function class1_icosa_chord_factor(v1, v2, freq) = sph_dist(
158icosa_class1(geo_tri2_tri3( [v1[0], v1[1], freq])),
159icosa_class1(geo_tri2_tri3( [v2[0], v2[1], freq]))
160);
161
162
163