mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Merge remote-tracking branch 'origin' into revarbat_dev
This commit is contained in:
commit
c560b0e236
4 changed files with 82 additions and 57 deletions
34
linalg.scad
34
linalg.scad
|
@ -416,14 +416,19 @@ function block_matrix(M) =
|
|||
|
||||
// Function: linear_solve()
|
||||
// Usage:
|
||||
// solv = linear_solve(A,b)
|
||||
// solv = linear_solve(A,b,[pivot])
|
||||
// Description:
|
||||
// Solves the linear system Ax=b. If `A` is square and non-singular the unique solution is returned. If `A` is overdetermined
|
||||
// the least squares solution is returned. If `A` is underdetermined, the minimal norm solution is returned.
|
||||
// If `A` is rank deficient or singular then linear_solve returns `[]`. If `b` is a matrix that is compatible with `A`
|
||||
// then the problem is solved for the matrix valued right hand side and a matrix is returned. Note that if you
|
||||
// want to solve Ax=b1 and Ax=b2 that you need to form the matrix `transpose([b1,b2])` for the right hand side and then
|
||||
// transpose the returned value.
|
||||
// transpose the returned value. The solution is computed using QR factorization. If `pivot` is set to true (the default) then
|
||||
// pivoting is used in the QR factorization, which is slower but expected to be more accurate.
|
||||
// Usage:
|
||||
// A = Matrix describing the linear system, which need not be square
|
||||
// b = right hand side for linear system, which can be a matrix to solve several cases simultaneously. Must be consistent with A.
|
||||
// pivot = if true use pivoting when computing the QR factorization. Default: true
|
||||
function linear_solve(A,b,pivot=true) =
|
||||
assert(is_matrix(A), "Input should be a matrix.")
|
||||
let(
|
||||
|
@ -444,6 +449,31 @@ function linear_solve(A,b,pivot=true) =
|
|||
m<n ? Q*back_substitute(R,transpose(P)*b,transpose=true) // Too messy to avoid input checks here
|
||||
: P*_back_substitute(R, transpose(Q)*b); // Calling internal version skips input checks
|
||||
|
||||
|
||||
// Function: linear_solve3()
|
||||
// Usage:
|
||||
// x = linear_solve3(A,b)
|
||||
// Description:
|
||||
// Fast solution to a 3x3 linear system using Cramer's rule (which appears to be the fastest
|
||||
// method in OpenSCAD). The input `A` must be a 3x3 matrix. Returns undef if `A` is singular.
|
||||
// The input `b` must be a 3-vector. Note that Cramer's rule is not a stable algorithm, so for
|
||||
// the highest accuracy on ill-conditioned problems you may want to use the general solver, which is about ten times slower.
|
||||
// Arguments:
|
||||
// A = 3x3 matrix for linear system
|
||||
// b = length 3 vector, right hand side of linear system
|
||||
function linear_solve3(A,b) =
|
||||
// Arg sanity checking adds 7% overhead
|
||||
assert(b*0==[0,0,0], "Input b must be a 3-vector")
|
||||
assert(A*0==[[0,0,0],[0,0,0],[0,0,0]],"Input A must be a 3x3 matrix")
|
||||
let(
|
||||
Az = [for(i=[0:2])[A[i][0], A[i][1], b[i]]],
|
||||
Ay = [for(i=[0:2])[A[i][0], b[i], A[i][2]]],
|
||||
Ax = [for(i=[0:2])[b[i], A[i][1], A[i][2]]],
|
||||
detA = det3(A)
|
||||
)
|
||||
detA==0 ? undef : [det3(Ax), det3(Ay), det3(Az)] / detA;
|
||||
|
||||
|
||||
// Function: matrix_inverse()
|
||||
// Usage:
|
||||
// mat = matrix_inverse(A)
|
||||
|
|
|
@ -330,9 +330,14 @@ module torx_mask(size, l=5, center, anchor, spin=0, orient=UP) {
|
|||
// robertson_mask(size, [extra]);
|
||||
// Description:
|
||||
// Creates a mask for creating a Robertson/Square drive recess given the drive size as an integer.
|
||||
// The width of the recess will be oversized by `2 * $slop`. Note that this model is based
|
||||
// on an incomplete spec. https://www.aspenfasteners.com/content/pdf/square_drive_specification.pdf
|
||||
// We determined the angle by doing print tests on a Prusa MK3S with $slop set to 0.05.
|
||||
// Arguments:
|
||||
// size = The size of the square drive, as an integer from 0 to 4.
|
||||
// extra = Extra length of drive mask to create.
|
||||
// ang = taper angle of each face. Default: 2.5
|
||||
// $slop = enlarge recess by this twice amount. Default: 0
|
||||
// Example:
|
||||
// robertson_mask(size=2);
|
||||
// Example:
|
||||
|
@ -340,7 +345,7 @@ module torx_mask(size, l=5, center, anchor, spin=0, orient=UP) {
|
|||
// cyl(d1=2, d2=8, h=4, anchor=TOP);
|
||||
// robertson_mask(size=2);
|
||||
// }
|
||||
module robertson_mask(size, extra=1) {
|
||||
module robertson_mask(size, extra=1, ang=2.5) {
|
||||
assert(is_int(size) && size>=0 && size<=4);
|
||||
Mmin = [0.0696, 0.0900, 0.1110, 0.1315, 0.1895][size];
|
||||
Mmax = [0.0710, 0.0910, 0.1126, 0.1330, 0.1910][size];
|
||||
|
@ -351,14 +356,14 @@ module robertson_mask(size, extra=1) {
|
|||
Fmin = [0.032, 0.057, 0.065, 0.085, 0.090][size];
|
||||
Fmax = [0.038, 0.065, 0.075, 0.095, 0.100][size];
|
||||
F = (Fmin + Fmax) / 2 * INCH;
|
||||
ang = 4;
|
||||
h = T + extra;
|
||||
Mslop=M+2*$slop;
|
||||
down(T) {
|
||||
intersection(){
|
||||
Mtop = M + 2*adj_ang_to_opp(F+extra,ang);
|
||||
Mbot = M - 2*adj_ang_to_opp(T-F,ang);
|
||||
Mtop = Mslop + 2*adj_ang_to_opp(F+extra,ang);
|
||||
Mbot = Mslop - 2*adj_ang_to_opp(T-F,ang);
|
||||
prismoid([Mbot,Mbot],[Mtop,Mtop],h=h,anchor=BOT);
|
||||
cyl(d1=0, d2=M/(T-F)*sqrt(2)*h, h=h, anchor=BOT);
|
||||
cyl(d1=0, d2=Mslop/(T-F)*sqrt(2)*h, h=h, anchor=BOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1654,8 +1654,8 @@ function sphere(r, d, circum=false, style="orig", anchor=CENTER, spin=0, orient=
|
|||
// - `style="orig"` constructs a sphere the same way that the OpenSCAD `sphere()` built-in does.
|
||||
// - `style="aligned"` constructs a sphere where, if `$fn` is a multiple of 4, it has vertices at all axis maxima and minima. ie: its bounding box is exactly the sphere diameter in length on all three axes. This is the default.
|
||||
// - `style="stagger"` forms a sphere where all faces are triangular, but the top and bottom poles have thinner triangles.
|
||||
// - `style="octa"` forms a sphere by subdividing an octahedron (8-sided platonic solid). This makes more uniform faces over the entirety of the sphere, and guarantees the bounding box is the sphere diameter in size on all axes. The effective `$fn` value is quantized to a multiple of 4, though. This is used in constructing rounded corners for various other shapes.
|
||||
// - `style="icosa"` forms a sphere by subdividing an icosahedron (20-sided platonic solid). This makes even more uniform faces over the entirety of the sphere. The effective `$fn` value is quantized to a multiple of 5, though.
|
||||
// - `style="octa"` forms a sphere by subdividing an octahedron (8-sided platonic solid). This makes more uniform faces over the entirety of the sphere, and guarantees the bounding box is the sphere diameter in size on all axes. The effective `$fn` value is quantized to a multiple of 4. This is used in constructing rounded corners for various other shapes.
|
||||
// - `style="icosa"` forms a sphere by subdividing an icosahedron (20-sided platonic solid). This makes even more uniform faces over the entirety of the sphere. The effective `$fn` value is quantized to a multiple of 5.
|
||||
// Arguments:
|
||||
// r = Radius of the spheroid.
|
||||
// style = The style of the spheroid's construction. One of "orig", "aligned", "stagger", "octa", or "icosa". Default: "aligned"
|
||||
|
@ -1717,6 +1717,12 @@ module spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, orie
|
|||
}
|
||||
|
||||
|
||||
// p is a list of 3 points defining a triangle in any dimension. N is the number of extra points
|
||||
// to add, so output triangle has N+2 points on each side.
|
||||
function _subsample_triangle(p,N) =
|
||||
[for(i=[0:N+1]) [for (j=[0:N+1-i]) unit(lerp(p[0],p[1],i/(N+1)) + (p[2]-p[0])*j/(N+1))]];
|
||||
|
||||
|
||||
function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, orient=UP) =
|
||||
let(
|
||||
r = get_radius(r=r, d=d, dflt=1),
|
||||
|
@ -1725,7 +1731,36 @@ function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, or
|
|||
octa_steps = round(max(4,hsides)/4),
|
||||
icosa_steps = round(max(5,hsides)/5),
|
||||
rr = circum? (r / cos(90/vsides) / cos(180/hsides)) : r,
|
||||
stagger = style=="stagger",
|
||||
stagger = style=="stagger"
|
||||
)
|
||||
style=="icosa" ? // subdivide faces of an icosahedron and project them onto a sphere
|
||||
let(
|
||||
N = icosa_steps-1,
|
||||
// construct an icosahedron
|
||||
icovert=[ for(i=[-1,1], j=[-1,1]) each [[0,i,j*PHI], [i,j*PHI,0], [j*PHI,0,i]]],
|
||||
icoface = hull(icovert),
|
||||
// Subsample face 0 of the icosahedron
|
||||
face0 = select(icovert,icoface[0]),
|
||||
sampled = rr * _subsample_triangle(face0,N),
|
||||
dir0 = mean(face0),
|
||||
point0 = face0[0]-dir0,
|
||||
// Make a rotated copy of the subsampled triangle on each icosahedral face
|
||||
tri_list = [sampled,
|
||||
for(i=[1:1:len(icoface)-1])
|
||||
let(face = select(icovert,icoface[i]))
|
||||
apply(frame_map(z=mean(face),x=face[0]-mean(face))
|
||||
*frame_map(z=dir0,x=point0,reverse=true),
|
||||
sampled)],
|
||||
// faces for the first triangle group
|
||||
faces = vnf_tri_array(tri_list[0])[1],
|
||||
size = repeat((N+2)*(N+3)/2,3),
|
||||
// Expand to full face list
|
||||
fullfaces = [for(i=idx(tri_list)) each [for(f=faces) f+i*size]],
|
||||
fullvert = flatten(flatten(tri_list)) // eliminate triangle structure
|
||||
)
|
||||
[reorient(anchor,spin,orient, r=r, p=fullvert), fullfaces]
|
||||
:
|
||||
let(
|
||||
verts = style=="orig"? [
|
||||
for (i=[0:1:vsides-1]) let(phi = (i+0.5)*180/(vsides))
|
||||
for (j=[0:1:hsides-1]) let(theta = j*360/hsides)
|
||||
|
@ -1746,32 +1781,6 @@ function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, or
|
|||
) [
|
||||
for (i=idx(meridians), j=[0:1:meridians[i]-1])
|
||||
spherical_to_xyz(rr, j*360/meridians[i], i*180/(len(meridians)-1))
|
||||
] : style=="icosa"? [
|
||||
for (tb=[0,1], j=[0,2], i = [0:1:4]) let(
|
||||
theta0 = i*360/5,
|
||||
theta1 = (i-0.5)*360/5,
|
||||
theta2 = (i+0.5)*360/5,
|
||||
phi0 = 180/3 * j,
|
||||
phi1 = 180/3,
|
||||
v0 = spherical_to_xyz(1,theta0,phi0),
|
||||
v1 = spherical_to_xyz(1,theta1,phi1),
|
||||
v2 = spherical_to_xyz(1,theta2,phi1),
|
||||
ax0 = vector_axis(v0, v1),
|
||||
ang0 = vector_angle(v0, v1),
|
||||
ax1 = vector_axis(v0, v2),
|
||||
ang1 = vector_angle(v0, v2)
|
||||
)
|
||||
for (k = [0:1:icosa_steps]) let(
|
||||
u = k/icosa_steps,
|
||||
vv0 = rot(ang0*u, ax0, p=v0),
|
||||
vv1 = rot(ang1*u, ax1, p=v0),
|
||||
ax2 = vector_axis(vv0, vv1),
|
||||
ang2 = vector_angle(vv0, vv1)
|
||||
)
|
||||
for (l = [0:1:k]) let(
|
||||
v = k? l/k : 0,
|
||||
pt = rot(ang2*v, v=ax2, p=vv0) * rr * (tb? -1 : 1)
|
||||
) pt
|
||||
] : assert(in_list(style,["orig","aligned","stagger","octa","icosa"])),
|
||||
lv = len(verts),
|
||||
faces = style=="orig"? [
|
||||
|
@ -1832,25 +1841,6 @@ function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, or
|
|||
[p5, p7, p8],
|
||||
if (k<m-1) [p5, p8, p6],
|
||||
],
|
||||
] : style=="icosa"? let(
|
||||
pyr = [for (x=[0:1:icosa_steps+1]) x],
|
||||
tri = sum(pyr),
|
||||
soff = cumsum(pyr)
|
||||
) [
|
||||
for (tb=[0,1], j=[0,1], i = [0:1:4]) let(
|
||||
base = ((((tb*2) + j) * 5) + i) * tri
|
||||
)
|
||||
for (k = [0:1:icosa_steps-1])
|
||||
for (l = [0:1:k]) let(
|
||||
v1 = base + soff[k] + l,
|
||||
v2 = base + soff[k+1] + l,
|
||||
v3 = base + soff[k+1] + (l + 1),
|
||||
faces = [
|
||||
if(l>0) [v1-1,v1,v2],
|
||||
[v1,v3,v2],
|
||||
],
|
||||
faces2 = (tb+j)%2? [for (f=faces) reverse(f)] : faces
|
||||
) each faces2
|
||||
] : []
|
||||
) [reorient(anchor,spin,orient, r=r, p=verts), faces];
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ module test_sphere() {
|
|||
assert_approx(sphere(r=40,style="aligned"), [[[0,0,40],[34.6410161514,0,20],[17.3205080757,30,20],[-17.3205080757,30,20],[-34.6410161514,0,20],[-17.3205080757,-30,20],[17.3205080757,-30,20],[34.6410161514,0,-20],[17.3205080757,30,-20],[-17.3205080757,30,-20],[-34.6410161514,0,-20],[-17.3205080757,-30,-20],[17.3205080757,-30,-20],[0,0,-40]],[[1,0,2],[13,7,8],[2,0,3],[13,8,9],[3,0,4],[13,9,10],[4,0,5],[13,10,11],[5,0,6],[13,11,12],[6,0,1],[13,12,7],[1,2,8],[1,8,7],[2,3,9],[2,9,8],[3,4,10],[3,10,9],[4,5,11],[4,11,10],[5,6,12],[5,12,11],[6,1,7],[6,7,12]]]);
|
||||
assert_approx(sphere(r=40,style="stagger"), [[[0,0,40],[30,17.3205080757,20],[0,34.6410161514,20],[-30,17.3205080757,20],[-30,-17.3205080757,20],[0,-34.6410161514,20],[30,-17.3205080757,20],[34.6410161514,0,-20],[17.3205080757,30,-20],[-17.3205080757,30,-20],[-34.6410161514,0,-20],[-17.3205080757,-30,-20],[17.3205080757,-30,-20],[0,0,-40]],[[1,0,2],[13,7,8],[2,0,3],[13,8,9],[3,0,4],[13,9,10],[4,0,5],[13,10,11],[5,0,6],[13,11,12],[6,0,1],[13,12,7],[1,2,8],[1,8,7],[2,3,9],[2,9,8],[3,4,10],[3,10,9],[4,5,11],[4,11,10],[5,6,12],[5,12,11],[6,1,7],[6,7,12]]]);
|
||||
assert_approx(sphere(r=40,style="octa"), [[[0,0,40],[28.2842712475,0,28.2842712475],[0,28.2842712475,28.2842712475],[-28.2842712475,0,28.2842712475],[0,-28.2842712475,28.2842712475],[40,0,0],[28.2842712475,28.2842712475,0],[0,40,0],[-28.2842712475,28.2842712475,0],[-40,0,0],[-28.2842712475,-28.2842712475,0],[0,-40,0],[28.2842712475,-28.2842712475,0],[28.2842712475,0,-28.2842712475],[0,28.2842712475,-28.2842712475],[-28.2842712475,0,-28.2842712475],[0,-28.2842712475,-28.2842712475],[0,0,-40]],[[0,2,1],[0,3,2],[0,4,3],[0,1,4],[17,15,16],[17,14,15],[17,13,14],[17,16,13],[1,6,5],[1,2,6],[13,5,6],[13,6,14],[2,7,6],[14,6,7],[2,8,7],[2,3,8],[14,7,8],[14,8,15],[3,9,8],[15,8,9],[3,10,9],[3,4,10],[15,9,10],[15,10,16],[4,11,10],[16,10,11],[4,12,11],[4,1,12],[16,11,12],[16,12,13],[1,5,12],[13,12,5]]]);
|
||||
assert_approx(sphere(r=40,style="icosa"), [[[0,0,40],[28.0251707689,-20.3614784182,20],[28.0251707689,20.3614784182,20],[0,0,40],[28.0251707689,20.3614784182,20],[-10.7046626932,32.9455641419,20],[0,0,40],[-10.7046626932,32.9455641419,20],[-34.6410161514,6.66133814775e-15,20],[0,0,40],[-34.6410161514,0,20],[-10.7046626932,-32.9455641419,20],[0,0,40],[-10.7046626932,-32.9455641419,20],[28.0251707689,-20.3614784182,20],[34.6410161514,0,-20],[28.0251707689,-20.3614784182,20],[28.0251707689,20.3614784182,20],[10.7046626932,32.9455641419,-20],[28.0251707689,20.3614784182,20],[-10.7046626932,32.9455641419,20],[-28.0251707689,20.3614784182,-20],[-10.7046626932,32.9455641419,20],[-34.6410161514,-4.4408920985e-15,20],[-28.0251707689,-20.3614784182,-20],[-34.6410161514,1.11022302463e-15,20],[-10.7046626932,-32.9455641419,20],[10.7046626932,-32.9455641419,-20],[-10.7046626932,-32.9455641419,20],[28.0251707689,-20.3614784182,20],[0,0,-40],[-28.0251707689,20.3614784182,-20],[-28.0251707689,-20.3614784182,-20],[0,0,-40],[-28.0251707689,-20.3614784182,-20],[10.7046626932,-32.9455641419,-20],[0,0,-40],[10.7046626932,-32.9455641419,-20],[34.6410161514,-6.66133814775e-15,-20],[0,0,-40],[34.6410161514,0,-20],[10.7046626932,32.9455641419,-20],[0,0,-40],[10.7046626932,32.9455641419,-20],[-28.0251707689,20.3614784182,-20],[-34.6410161514,0,20],[-28.0251707689,20.3614784182,-20],[-28.0251707689,-20.3614784182,-20],[-10.7046626932,-32.9455641419,20],[-28.0251707689,-20.3614784182,-20],[10.7046626932,-32.9455641419,-20],[28.0251707689,-20.3614784182,20],[10.7046626932,-32.9455641419,-20],[34.6410161514,4.4408920985e-15,-20],[28.0251707689,20.3614784182,20],[34.6410161514,-1.11022302463e-15,-20],[10.7046626932,32.9455641419,-20],[-10.7046626932,32.9455641419,20],[10.7046626932,32.9455641419,-20],[-28.0251707689,20.3614784182,-20]],[[0,2,1],[3,5,4],[6,8,7],[9,11,10],[12,14,13],[16,17,15],[19,20,18],[22,23,21],[25,26,24],[28,29,27],[31,32,30],[34,35,33],[37,38,36],[40,41,39],[43,44,42],[45,47,46],[48,50,49],[51,53,52],[54,56,55],[57,59,58]]]);
|
||||
assert_approx(sphere(r=40,style="icosa"),[[[0,21.0292444848,34.0260323341],[34.0260323341,0,21.0292444848],[21.0292444848,34.0260323341,0],[21.0292444848,34.0260323341,3.5527136788e-15],[34.0260323341,-3.5527136788e-15,21.0292444848],[34.0260323341,-1.7763568394e-15,-21.0292444848],[34.0260323341,-3.5527136788e-15,-21.0292444848],[34.0260323341,-8.881784197e-15,21.0292444848],[21.0292444848,-34.0260323341,0],[21.0292444848,-34.0260323341,5.3290705182e-15],[34.0260323341,-5.3290705182e-15,21.0292444848],[5.3290705182e-15,-21.0292444848,34.0260323341],[3.5527136788e-15,-21.0292444848,34.0260323341],[34.0260323341,3.5527136788e-15,21.0292444848],[3.5527136788e-15,21.0292444848,34.0260323341],[-21.0292444848,34.0260323341,-3.5527136788e-15],[21.0292444848,34.0260323341,-8.881784197e-15],[0,21.0292444848,-34.0260323341],[5.3290705182e-15,21.0292444848,-34.0260323341],[21.0292444848,34.0260323341,-5.3290705182e-15],[34.0260323341,5.3290705182e-15,-21.0292444848],[3.5527136788e-15,21.0292444848,34.0260323341],[21.0292444848,34.0260323341,-3.5527136788e-15],[-21.0292444848,34.0260323341,-1.7763568394e-15],[-34.0260323341,3.5527136788e-15,-21.0292444848],[-34.0260323341,8.881784197e-15,21.0292444848],[-21.0292444848,34.0260323341,0],[-21.0292444848,34.0260323341,5.3290705182e-15],[-34.0260323341,5.3290705182e-15,21.0292444848],[-5.3290705182e-15,21.0292444848,34.0260323341],[-3.5527136788e-15,21.0292444848,34.0260323341],[-34.0260323341,-3.5527136788e-15,21.0292444848],[-3.5527136788e-15,-21.0292444848,34.0260323341],[-5.39089693932e-15,-21.0292444848,34.0260323341],[-34.0260323341,-9.16854539271e-15,21.0292444848],[-21.0292444848,-34.0260323341,6.83383025096e-15],[-21.0292444848,-34.0260323341,3.5527136788e-15],[-34.0260323341,3.5527136788e-15,21.0292444848],[-34.0260323341,1.7763568394e-15,-21.0292444848],[34.0260323341,-5.39089693932e-15,-21.0292444848],[21.0292444848,-34.0260323341,-9.16854539271e-15],[6.83383025096e-15,-21.0292444848,-34.0260323341],[3.5527136788e-15,-21.0292444848,-34.0260323341],[21.0292444848,-34.0260323341,3.5527136788e-15],[-21.0292444848,-34.0260323341,1.7763568394e-15],[-21.0292444848,-34.0260323341,3.5527136788e-15],[21.0292444848,-34.0260323341,8.881784197e-15],[0,-21.0292444848,34.0260323341],[3.5527136788e-15,-21.0292444848,-34.0260323341],[8.881784197e-15,21.0292444848,-34.0260323341],[34.0260323341,0,-21.0292444848],[-34.0260323341,3.5527136788e-15,-21.0292444848],[3.5527136788e-15,21.0292444848,-34.0260323341],[1.7763568394e-15,-21.0292444848,-34.0260323341],[-21.0292444848,34.0260323341,-5.39089693932e-15],[-9.16854539271e-15,21.0292444848,-34.0260323341],[-34.0260323341,6.83383025096e-15,-21.0292444848],[-34.0260323341,-5.3290705182e-15,-21.0292444848],[-5.3290705182e-15,-21.0292444848,-34.0260323341],[-21.0292444848,-34.0260323341,-5.3290705182e-15]],[[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13,14],[15,16,17],[18,19,20],[21,22,23],[24,25,26],[27,28,29],[30,31,32],[33,34,35],[36,37,38],[39,40,41],[42,43,44],[45,46,47],[48,49,50],[51,52,53],[54,55,56],[57,58,59]]]);
|
||||
}
|
||||
test_sphere();
|
||||
|
||||
|
@ -70,7 +70,7 @@ module test_spheroid() {
|
|||
assert_approx(spheroid(r=50,style="aligned"),[[[0,0,50],[43.3012701892,0,25],[21.6506350946,37.5,25],[-21.6506350946,37.5,25],[-43.3012701892,0,25],[-21.6506350946,-37.5,25],[21.6506350946,-37.5,25],[43.3012701892,0,-25],[21.6506350946,37.5,-25],[-21.6506350946,37.5,-25],[-43.3012701892,0,-25],[-21.6506350946,-37.5,-25],[21.6506350946,-37.5,-25],[0,0,-50]],[[1,0,2],[13,7,8],[2,0,3],[13,8,9],[3,0,4],[13,9,10],[4,0,5],[13,10,11],[5,0,6],[13,11,12],[6,0,1],[13,12,7],[1,2,8],[1,8,7],[2,3,9],[2,9,8],[3,4,10],[3,10,9],[4,5,11],[4,11,10],[5,6,12],[5,12,11],[6,1,7],[6,7,12]]]);
|
||||
assert_approx(spheroid(r=50,style="stagger"),[[[0,0,50],[37.5,21.6506350946,25],[0,43.3012701892,25],[-37.5,21.6506350946,25],[-37.5,-21.6506350946,25],[0,-43.3012701892,25],[37.5,-21.6506350946,25],[43.3012701892,0,-25],[21.6506350946,37.5,-25],[-21.6506350946,37.5,-25],[-43.3012701892,0,-25],[-21.6506350946,-37.5,-25],[21.6506350946,-37.5,-25],[0,0,-50]],[[1,0,2],[13,7,8],[2,0,3],[13,8,9],[3,0,4],[13,9,10],[4,0,5],[13,10,11],[5,0,6],[13,11,12],[6,0,1],[13,12,7],[1,2,8],[1,8,7],[2,3,9],[2,9,8],[3,4,10],[3,10,9],[4,5,11],[4,11,10],[5,6,12],[5,12,11],[6,1,7],[6,7,12]]]);
|
||||
assert_approx(spheroid(r=50,style="octa"),[[[0,0,50],[35.3553390593,0,35.3553390593],[0,35.3553390593,35.3553390593],[-35.3553390593,0,35.3553390593],[0,-35.3553390593,35.3553390593],[50,0,0],[35.3553390593,35.3553390593,0],[0,50,0],[-35.3553390593,35.3553390593,0],[-50,0,0],[-35.3553390593,-35.3553390593,0],[0,-50,0],[35.3553390593,-35.3553390593,0],[35.3553390593,0,-35.3553390593],[0,35.3553390593,-35.3553390593],[-35.3553390593,0,-35.3553390593],[0,-35.3553390593,-35.3553390593],[0,0,-50]],[[0,2,1],[0,3,2],[0,4,3],[0,1,4],[17,15,16],[17,14,15],[17,13,14],[17,16,13],[1,6,5],[1,2,6],[13,5,6],[13,6,14],[2,7,6],[14,6,7],[2,8,7],[2,3,8],[14,7,8],[14,8,15],[3,9,8],[15,8,9],[3,10,9],[3,4,10],[15,9,10],[15,10,16],[4,11,10],[16,10,11],[4,12,11],[4,1,12],[16,11,12],[16,12,13],[1,5,12],[13,12,5]]]);
|
||||
assert_approx(spheroid(r=50,style="icosa"),[[[0,0,50],[35.0314634611,-25.4518480228,25],[35.0314634611,25.4518480228,25],[0,0,50],[35.0314634611,25.4518480228,25],[-13.3808283665,41.1819551773,25],[0,0,50],[-13.3808283665,41.1819551773,25],[-43.3012701892,8.32667268469e-15,25],[0,0,50],[-43.3012701892,0,25],[-13.3808283665,-41.1819551773,25],[0,0,50],[-13.3808283665,-41.1819551773,25],[35.0314634611,-25.4518480228,25],[43.3012701892,0,-25],[35.0314634611,-25.4518480228,25],[35.0314634611,25.4518480228,25],[13.3808283665,41.1819551773,-25],[35.0314634611,25.4518480228,25],[-13.3808283665,41.1819551773,25],[-35.0314634611,25.4518480228,-25],[-13.3808283665,41.1819551773,25],[-43.3012701892,-5.55111512313e-15,25],[-35.0314634611,-25.4518480228,-25],[-43.3012701892,1.38777878078e-15,25],[-13.3808283665,-41.1819551773,25],[13.3808283665,-41.1819551773,-25],[-13.3808283665,-41.1819551773,25],[35.0314634611,-25.4518480228,25],[0,0,-50],[-35.0314634611,25.4518480228,-25],[-35.0314634611,-25.4518480228,-25],[0,0,-50],[-35.0314634611,-25.4518480228,-25],[13.3808283665,-41.1819551773,-25],[0,0,-50],[13.3808283665,-41.1819551773,-25],[43.3012701892,-8.32667268469e-15,-25],[0,0,-50],[43.3012701892,0,-25],[13.3808283665,41.1819551773,-25],[0,0,-50],[13.3808283665,41.1819551773,-25],[-35.0314634611,25.4518480228,-25],[-43.3012701892,0,25],[-35.0314634611,25.4518480228,-25],[-35.0314634611,-25.4518480228,-25],[-13.3808283665,-41.1819551773,25],[-35.0314634611,-25.4518480228,-25],[13.3808283665,-41.1819551773,-25],[35.0314634611,-25.4518480228,25],[13.3808283665,-41.1819551773,-25],[43.3012701892,5.55111512313e-15,-25],[35.0314634611,25.4518480228,25],[43.3012701892,-1.38777878078e-15,-25],[13.3808283665,41.1819551773,-25],[-13.3808283665,41.1819551773,25],[13.3808283665,41.1819551773,-25],[-35.0314634611,25.4518480228,-25]],[[0,2,1],[3,5,4],[6,8,7],[9,11,10],[12,14,13],[16,17,15],[19,20,18],[22,23,21],[25,26,24],[28,29,27],[31,32,30],[34,35,33],[37,38,36],[40,41,39],[43,44,42],[45,47,46],[48,50,49],[51,53,52],[54,56,55],[57,59,58]]]);
|
||||
assert_approx(spheroid(r=50,style="icosa"),[[[0,26.286555606,42.5325404176],[42.5325404176,0,26.286555606],[26.286555606,42.5325404176,0],[26.286555606,42.5325404176,3.5527136788e-15],[42.5325404176,-7.1054273576e-15,26.286555606],[42.5325404176,-1.7763568394e-15,-26.286555606],[42.5325404176,-3.5527136788e-15,-26.286555606],[42.5325404176,-1.24344978758e-14,26.286555606],[26.286555606,-42.5325404176,0],[26.286555606,-42.5325404176,5.3290705182e-15],[42.5325404176,-7.1054273576e-15,26.286555606],[5.3290705182e-15,-26.286555606,42.5325404176],[5.3290705182e-15,-26.286555606,42.5325404176],[42.5325404176,7.1054273576e-15,26.286555606],[3.5527136788e-15,26.286555606,42.5325404176],[-26.286555606,42.5325404176,-3.5527136788e-15],[26.286555606,42.5325404176,-1.24344978758e-14],[0,26.286555606,-42.5325404176],[5.3290705182e-15,26.286555606,-42.5325404176],[26.286555606,42.5325404176,-7.1054273576e-15],[42.5325404176,5.3290705182e-15,-26.286555606],[3.5527136788e-15,26.286555606,42.5325404176],[26.286555606,42.5325404176,-7.1054273576e-15],[-26.286555606,42.5325404176,-1.7763568394e-15],[-42.5325404176,3.5527136788e-15,-26.286555606],[-42.5325404176,1.24344978758e-14,26.286555606],[-26.286555606,42.5325404176,0],[-26.286555606,42.5325404176,5.3290705182e-15],[-42.5325404176,7.1054273576e-15,26.286555606],[-5.3290705182e-15,26.286555606,42.5325404176],[-5.3290705182e-15,26.286555606,42.5325404176],[-42.5325404176,-7.1054273576e-15,26.286555606],[-3.5527136788e-15,-26.286555606,42.5325404176],[-6.73862117414e-15,-26.286555606,42.5325404176],[-42.5325404176,-1.14606817409e-14,26.286555606],[-26.286555606,-42.5325404176,8.5422878137e-15],[-26.286555606,-42.5325404176,3.5527136788e-15],[-42.5325404176,7.1054273576e-15,26.286555606],[-42.5325404176,1.7763568394e-15,-26.286555606],[42.5325404176,-6.73862117414e-15,-26.286555606],[26.286555606,-42.5325404176,-1.14606817409e-14],[8.5422878137e-15,-26.286555606,-42.5325404176],[3.5527136788e-15,-26.286555606,-42.5325404176],[26.286555606,-42.5325404176,7.1054273576e-15],[-26.286555606,-42.5325404176,1.7763568394e-15],[-26.286555606,-42.5325404176,3.5527136788e-15],[26.286555606,-42.5325404176,1.24344978758e-14],[0,-26.286555606,42.5325404176],[3.5527136788e-15,-26.286555606,-42.5325404176],[1.24344978758e-14,26.286555606,-42.5325404176],[42.5325404176,0,-26.286555606],[-42.5325404176,3.5527136788e-15,-26.286555606],[7.1054273576e-15,26.286555606,-42.5325404176],[1.7763568394e-15,-26.286555606,-42.5325404176],[-26.286555606,42.5325404176,-6.73862117414e-15],[-1.14606817409e-14,26.286555606,-42.5325404176],[-42.5325404176,8.5422878137e-15,-26.286555606],[-42.5325404176,-5.3290705182e-15,-26.286555606],[-7.1054273576e-15,-26.286555606,-42.5325404176],[-26.286555606,-42.5325404176,-5.3290705182e-15]],[[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13,14],[15,16,17],[18,19,20],[21,22,23],[24,25,26],[27,28,29],[30,31,32],[33,34,35],[36,37,38],[39,40,41],[42,43,44],[45,46,47],[48,49,50],[51,52,53],[54,55,56],[57,58,59]]]);
|
||||
}
|
||||
test_spheroid();
|
||||
|
||||
|
|
Loading…
Reference in a new issue