mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Added several coordinate system conversion functions.
This commit is contained in:
parent
4401bb1135
commit
54af28d8c4
1 changed files with 120 additions and 1 deletions
121
math.scad
121
math.scad
|
@ -249,6 +249,126 @@ function vector2d_angle(v1,v2) = atan2(v1[1],v1[0]) - atan2(v2[1],v2[0]);
|
|||
// NOTE: constrain() corrects crazy FP rounding errors that exceed acos()'s domain.
|
||||
function vector3d_angle(v1,v2) = acos(constrain((v1*v2)/(norm(v1)*norm(v2)), -1, 1));
|
||||
|
||||
|
||||
// Convert polar coordinates to cartesian coordinates.
|
||||
// Returns [X,Y] cartesian coordinates.
|
||||
// r = distance from the origin.
|
||||
// theta = angle in degrees, counter-clockwise of X+.
|
||||
// Examples:
|
||||
// xy = polar_to_xy(20,30);
|
||||
// xy = polar_to_xy([40,60]);
|
||||
function polar_to_xy(r,theta=undef) = let(
|
||||
rad = theta==undef? r[0] : r,
|
||||
t = theta==undef? r[1] : theta
|
||||
) rad*[cos(t), sin(t)];
|
||||
|
||||
|
||||
// Convert cartesian coordinates to polar coordinates.
|
||||
// Returns [radius, theta] where theta is the angle counter-clockwise of X+.
|
||||
// x = X coordinate.
|
||||
// y = Y coordinate.
|
||||
// Examples:
|
||||
// plr = xy_to_polar(20,30);
|
||||
// plr = xy_to_polar([40,60]);
|
||||
function xy_to_polar(x,y=undef) = let(
|
||||
xx = y==undef? x[0] : x,
|
||||
yy = y==undef? x[1] : y
|
||||
) [norm([xx,yy]), atan2(yy,xx)];
|
||||
|
||||
|
||||
// Convert cylindrical coordinates to cartesian coordinates.
|
||||
// Returns [X,Y,Z] cartesian coordinates.
|
||||
// r = distance from the Z axis.
|
||||
// theta = angle in degrees, counter-clockwise of X+ on the XY plane.
|
||||
// z = Height above XY plane.
|
||||
// Examples:
|
||||
// xyz = cylindrical_to_xyz(20,30,40);
|
||||
// xyz = cylindrical_to_xyz([40,60,50]);
|
||||
function cylindrical_to_xyz(r,theta=undef,z=undef) = let(
|
||||
rad = theta==undef? r[0] : r,
|
||||
t = theta==undef? r[1] : theta,
|
||||
zed = theta==undef? r[2] : z
|
||||
) [rad*cos(t), rad*sin(t), zed];
|
||||
|
||||
|
||||
// Convert cartesian coordinates to cylindrical coordinates.
|
||||
// Returns [radius,theta,Z]. Theta is the angle counter-clockwise
|
||||
// of X+ on the XY plane. Z is height above the XY plane.
|
||||
// x = X coordinate.
|
||||
// y = Y coordinate.
|
||||
// z = Z coordinate.
|
||||
// Examples:
|
||||
// cyl = xyz_to_cylindrical(20,30,40);
|
||||
// cyl = xyz_to_cylindrical([40,50,70]);
|
||||
function xyz_to_cylindrical(x,y=undef,z=undef) = let(
|
||||
xx = y==undef? x[0] : x,
|
||||
yy = y==undef? x[1] : y,
|
||||
zz = y==undef? x[2] : z
|
||||
) [norm([xx,yy]), atan2(yy,xx), zz];
|
||||
|
||||
|
||||
// Convert spherical coordinates to cartesian coordinates.
|
||||
// Returns [X,Y,Z] cartesian coordinates.
|
||||
// r = distance from origin.
|
||||
// theta = angle in degrees, counter-clockwise of X+ on the XY plane.
|
||||
// phi = angle in degrees from the vertical Z+ axis.
|
||||
// Examples:
|
||||
// xyz = spherical_to_xyz(20,30,40);
|
||||
// xyz = spherical_to_xyz([40,60,50]);
|
||||
function spherical_to_xyz(r,theta=undef,phi=undef) = let(
|
||||
rad = theta==undef? r[0] : r,
|
||||
t = theta==undef? r[1] : theta,
|
||||
p = theta==undef? r[2] : phi
|
||||
) rad*[sin(p)*cos(t), sin(p)*sin(t), cos(p)];
|
||||
|
||||
|
||||
// Convert cartesian coordinates to spherical coordinates.
|
||||
// Returns [r,theta,phi], where phi is the angle from the Z+ pole,
|
||||
// and theta is degrees counter-clockwise of X+ on the XY plane.
|
||||
// x = X coordinate.
|
||||
// y = Y coordinate.
|
||||
// z = Z coordinate.
|
||||
// Examples:
|
||||
// sph = xyz_to_spherical(20,30,40);
|
||||
// sph = xyz_to_spherical([40,50,70]);
|
||||
function xyz_to_spherical(x,y=undef,z=undef) = let(
|
||||
xx = y==undef? x[0] : x,
|
||||
yy = y==undef? x[1] : y,
|
||||
zz = y==undef? x[2] : z
|
||||
) [norm([xx,yy,zz]), atan2(yy,xx), atan2(norm([xx,yy]),zz)];
|
||||
|
||||
|
||||
// Convert altitude/azimuth/range coordinates to cartesian coordinates.
|
||||
// Returns [X,Y,Z] cartesian coordinates.
|
||||
// alt = altitude angle in degrees above the XY plane.
|
||||
// az = azimuth angle in degrees clockwise of Y+ on the XY plane.
|
||||
// r = distance from origin.
|
||||
// Examples:
|
||||
// xyz = altaz_to_xyz(20,30,40);
|
||||
// xyz = altaz_to_xyz([40,60,50]);
|
||||
function altaz_to_xyz(alt,az=undef,r=undef) = let(
|
||||
p = az==undef? alt[0] : alt,
|
||||
t = 90 - (az==undef? alt[1] : az),
|
||||
rad = az==undef? alt[2] : r
|
||||
) rad*[cos(p)*cos(t), cos(p)*sin(t), sin(p)];
|
||||
|
||||
// Convert cartesian coordinates to altitude/azimuth/range coordinates.
|
||||
// Returns [altitude,azimuth,range], where altitude is angle above the
|
||||
// XY plane, azimuth is degrees clockwise of Y+ on the XY plane, and
|
||||
// range is the distance from the origin.
|
||||
// x = X coordinate.
|
||||
// y = Y coordinate.
|
||||
// z = Z coordinate.
|
||||
// Examples:
|
||||
// aa = xyz_to_altaz(20,30,40);
|
||||
// aa = xyz_to_altaz([40,50,70]);
|
||||
function xyz_to_altaz(x,y=undef,z=undef) = let(
|
||||
xx = y==undef? x[0] : x,
|
||||
yy = y==undef? x[1] : y,
|
||||
zz = y==undef? x[2] : z
|
||||
) [atan2(zz,norm([xx,yy])), atan2(xx,yy), norm([xx,yy,zz])];
|
||||
|
||||
|
||||
// Returns a slice of an array. An index of 0 is the array start, -1 is array end
|
||||
function slice(arr,st,end) = let(
|
||||
s=st<0?(len(arr)+st):st,
|
||||
|
@ -256,5 +376,4 @@ function slice(arr,st,end) = let(
|
|||
) [for (i=[s:e-1]) if (e>s) arr[i]];
|
||||
|
||||
|
||||
|
||||
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||
|
|
Loading…
Reference in a new issue