Experimenting with coordinate systems
This commit is contained in:
29
fcad/align.scad
Normal file
29
fcad/align.scad
Normal file
@@ -0,0 +1,29 @@
|
||||
function fAlign(modelA, coordNameA, modelB, coordNameB) = (
|
||||
let(coordA = fModelCoord(modelA, coordNameA),
|
||||
coordB = fModelCoord(modelB, coordNameB),
|
||||
translation = fCoordTranslation(coordA) - fCoordTranslation(coordB),
|
||||
rotation = fCoordRotation(coordA) - fCoordRotation(coordB),
|
||||
scale = fCoordScale(coordA) - fCoordScale(coordB))
|
||||
fUnion(
|
||||
modelA,
|
||||
fTranslate(
|
||||
fRotate(modelB, coordNameB, rotation),
|
||||
translation
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
function fAttach(modelA, coordNameA, modelB, coordNameB) = (
|
||||
let(coordA = fModelCoord(modelA, coordNameA),
|
||||
coordB = fModelCoord(modelB, coordNameB),
|
||||
translation = fCoordTranslation(coordA) - fCoordTranslation(coordB),
|
||||
rotation = fCoordRotation(coordA) - (-1 * fCoordRotation(coordB)),
|
||||
scale = fCoordScale(coordA) - fCoordScale(coordB))
|
||||
fUnion(
|
||||
modelA,
|
||||
fTranslate(
|
||||
fRotate(modelB, coordNameB, rotation),
|
||||
translation
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -35,3 +35,11 @@ function fCoordRotation(coord) = (
|
||||
function fCoordScale(coord) = (
|
||||
fMapLookup(fKeyScale, coord)
|
||||
);
|
||||
|
||||
function fCoordInverse(coord) = (
|
||||
fCoord(
|
||||
translation=[0, 0, 0] - fCoordTranslation(coord),
|
||||
rotation=[180, 180, 180] + fCoordRotation(coord),
|
||||
scale=1 / fCoordScale(coord)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -13,8 +13,14 @@ function fCube(dims) = (
|
||||
[1, 3, 7, 5], // +z
|
||||
],
|
||||
coords=[
|
||||
[ "/x+,/y+,-z+", fCoord(translation=[x / 2, y / 2, 0]) ],
|
||||
[ "/x+,/y+,+z+", fCoord(translation=[x / 2, y / 2, z]) ],
|
||||
[ "-x-,/y-,/z-", fCoord(translation=[ 0, y / 2, z / 2], rotation=[ 0, -90, 0]) ],
|
||||
[ "+x+,/y+,/z+", fCoord(translation=[ x, y / 2, z / 2], rotation=[ 0, 90, 0]) ],
|
||||
|
||||
[ "/x-,-y-,/z-", fCoord(translation=[x / 2, 0, z / 2], rotation=[-90, 0, 0]) ],
|
||||
[ "/x+,+y+,/z+", fCoord(translation=[x / 2, y, z / 2], rotation=[ 90, 0, 0]) ],
|
||||
|
||||
[ "/x-,/y-,-z-", fCoord(translation=[x / 2, y / 2, 0], rotation=[180, 0, 180]) ],
|
||||
[ "/x+,/y+,+z+", fCoord(translation=[x / 2, y / 2, z], rotation=[ 0, 0, 0]) ],
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
@@ -19,6 +19,9 @@ function fCylinder(h, r, r1=undef, r2=undef, sides=36) = (
|
||||
// sides
|
||||
[for (side = side_range)
|
||||
[for (vertex = [2, 3, 1, 0]) (side * 2 + vertex) % (sides * 2)]]
|
||||
)
|
||||
),
|
||||
coords=[
|
||||
[ "start", fCoord() ],
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,25 +1,3 @@
|
||||
module fDraw(model) {
|
||||
polyhedron(points=fModelPoints(model), faces=fModelFaces(model));
|
||||
}
|
||||
|
||||
module fDrawN(model, scales) {
|
||||
fDraw(model);
|
||||
points = fModelPoints(model);
|
||||
model_max = fMaxPoint(model);
|
||||
translation =
|
||||
[for (axis = [0 : 2])
|
||||
scales[axis] * model_max[axis]];
|
||||
translate(translation) children();
|
||||
}
|
||||
|
||||
module fDrawX(model) {
|
||||
fDrawN(model, [1, 0, 0]) children();
|
||||
}
|
||||
|
||||
module fDrawY(model) {
|
||||
fDrawN(model, [0, 1, 0]) children();
|
||||
}
|
||||
|
||||
module fDrawZ(model) {
|
||||
fDrawN(model, [0, 0, 1]) children();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
include <align.scad>;
|
||||
include <coord.scad>;
|
||||
include <cube.scad>;
|
||||
include <cylinder.scad>;
|
||||
include <draw.scad>;
|
||||
include <math.scad>;
|
||||
include <model.scad>;
|
||||
include <model_util.scad>;
|
||||
include <rotate.scad>;
|
||||
include <sphere.scad>;
|
||||
include <translate.scad>;
|
||||
include <types.scad>;
|
||||
include <union.scad>;
|
||||
|
||||
@@ -6,4 +6,3 @@ function fCartesianProduct(vecs) = (
|
||||
for (val2 = fCartesianProduct(fVectorSlice(vecs, start=1)))
|
||||
concat(val1, val2)]
|
||||
);
|
||||
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
/// fKeyFaces "faces" fModelFaces(): [ [ pointIdx, ... ], ... ]
|
||||
/// fKeyCoords "coords" fModelCoords(): [ [ name, coord ], ... ]
|
||||
|
||||
/// OpenSCAD uses right-handed coordinates. We name directions on these axes:
|
||||
/// X: left (-), right (+)
|
||||
/// Y: back (-), front (+)
|
||||
/// Z: bottom (-), top (+)
|
||||
/// Coordinate systems that attach to surfaces should generally have the Z axis
|
||||
/// normal to the surface.
|
||||
///
|
||||
/// Standard model coords names:
|
||||
///
|
||||
/// [-/+] edge ("/" is midpoint)
|
||||
@@ -39,15 +46,15 @@ function fModelFaces(model) = (
|
||||
);
|
||||
|
||||
fCoordAliases = [
|
||||
[ "bottom", "/x+,/y+,-z-" ],
|
||||
[ "left", "-x-,/y-,/z-" ],
|
||||
[ "right", "+x+,/y+,/z+" ],
|
||||
|
||||
[ "back", "/x-,-y-,/z-" ],
|
||||
[ "front", "/x+,+y+,/z+" ],
|
||||
|
||||
[ "bottom", "/x-,/y-,-z-" ],
|
||||
[ "top", "/x+,/y+,+z+" ],
|
||||
|
||||
[ "back", "-x-,/y+,/z+" ],
|
||||
[ "front", "+x+,/y+,/z+" ],
|
||||
|
||||
[ "left", "/x+,-y-,/z+" ],
|
||||
[ "right", "/x+,+y+,/z+" ],
|
||||
|
||||
[ "center", "/x+,/y+,/z+" ],
|
||||
];
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
function fMinPoint(model) = (
|
||||
[for (axis = [0 : 2])
|
||||
min([for (point = fModelPoints(model)) point[axis]])]
|
||||
);
|
||||
|
||||
function fMaxPoint(model) = (
|
||||
[for (axis = [0 : 2])
|
||||
max([for (point = fModelPoints(model)) point[axis]])]
|
||||
);
|
||||
|
||||
function fCenterPoint(model) = (
|
||||
let(model_min = fMinPoint(model),
|
||||
model_max = fMaxPoint(model),
|
||||
model_size =
|
||||
[for (axis = [0 : 2])
|
||||
model_max[axis] - model_min[axis]])
|
||||
[for (axis = [0 : 2])
|
||||
model_min[axis] + (model_size[axis] / 2)]
|
||||
);
|
||||
45
fcad/rotate.scad
Normal file
45
fcad/rotate.scad
Normal file
@@ -0,0 +1,45 @@
|
||||
function fRotate(model, coordName, rotation) = (
|
||||
// Shift the coordinate frame to the origin, rotate, then restore
|
||||
let(coord = fModelCoord(model, coordName),
|
||||
inverseCoord = fCoordInverse(coord),
|
||||
zeroed = fTranslate(model, fCoordTranslation(inverseCoord)),
|
||||
xMatrix = fRotationMatrixX(rotation[0]),
|
||||
yMatrix = fRotationMatrixY(rotation[1]),
|
||||
zMatrix = fRotationMatrixZ(rotation[2]))
|
||||
fTranslate(
|
||||
fModel(
|
||||
points=
|
||||
[for (point = fModelPoints(zeroed))
|
||||
([point] * xMatrix * yMatrix * zMatrix)[0]],
|
||||
faces=fModelFaces(model),
|
||||
coords=fModelCoords(model)
|
||||
),
|
||||
fCoordTranslation(coord)
|
||||
)
|
||||
);
|
||||
|
||||
// These matrices are transposed because we apply them with post-multiplication
|
||||
// to work around OpenSCAD bugs.
|
||||
function fRotationMatrixX(theta) = (
|
||||
[
|
||||
[ 1, 0, 0 ],
|
||||
[ 0, cos(theta), sin(theta) ],
|
||||
[ 0, -sin(theta), cos(theta) ],
|
||||
]
|
||||
);
|
||||
|
||||
function fRotationMatrixY(theta) = (
|
||||
[
|
||||
[ cos(theta), 0, -sin(theta) ],
|
||||
[ 0, 1, 0 ],
|
||||
[ sin(theta), 0, cos(theta) ],
|
||||
]
|
||||
);
|
||||
|
||||
function fRotationMatrixZ(theta) = (
|
||||
[
|
||||
[ cos(theta), sin(theta), 0 ],
|
||||
[ -sin(theta), cos(theta), 0 ],
|
||||
[ 0, 0, 1 ],
|
||||
]
|
||||
);
|
||||
@@ -2,49 +2,8 @@ function fTranslate(model, translation) = (
|
||||
fModel(
|
||||
points=
|
||||
[for (point = fModelPoints(model))
|
||||
[for (axis = [0 : 2])
|
||||
point[axis] + translation[axis]]
|
||||
],
|
||||
faces=fModelFaces(model)
|
||||
point + translation],
|
||||
faces=fModelFaces(model),
|
||||
coords=fModelCoords(model)
|
||||
)
|
||||
);
|
||||
|
||||
function fZeroN(model, scales) = (
|
||||
let(model_min = fMinPoint(model),
|
||||
translation =
|
||||
[for (axis = [0 : 2])
|
||||
scales[axis] * model_min[axis]])
|
||||
fTranslate(model, translation)
|
||||
);
|
||||
|
||||
function fZeroX(model) = (
|
||||
fZeroN(model, [-1, 0, 0])
|
||||
);
|
||||
|
||||
function fZeroY(model) = (
|
||||
fZeroN(model, [0, -1, 0])
|
||||
);
|
||||
|
||||
function fZeroZ(model) = (
|
||||
fZeroN(model, [0, 0, -1])
|
||||
);
|
||||
|
||||
function fCenterN(model, scales) = (
|
||||
let(model_center = fCenterPoint(model),
|
||||
translation =
|
||||
[for (axis = [0 : 2])
|
||||
scales[axis] * model_center[axis]])
|
||||
fTranslate(model, translation)
|
||||
);
|
||||
|
||||
function fCenterX(model) = (
|
||||
fCenterN(model, [-1, 0, 0])
|
||||
);
|
||||
|
||||
function fCenterY(model) = (
|
||||
fCenterN(model, [0, -1, 0])
|
||||
);
|
||||
|
||||
function fCenterZ(model) = (
|
||||
fCenterN(model, [0, 0, -1])
|
||||
);
|
||||
|
||||
10
fcad/union.scad
Normal file
10
fcad/union.scad
Normal file
@@ -0,0 +1,10 @@
|
||||
function fUnion(modelA, modelB) = (
|
||||
let(numPointsA = len(fModelPoints(modelA)))
|
||||
fModel(
|
||||
points=concat(fModelPoints(modelA), fModelPoints(modelB)),
|
||||
faces=concat(fModelFaces(modelA),
|
||||
[for (face = fModelFaces(modelB))
|
||||
[for (point = face) point + numPointsA]])
|
||||
)
|
||||
// TODO: how should we handle coords here?
|
||||
);
|
||||
22
test.scad
22
test.scad
@@ -1,5 +1,21 @@
|
||||
use <fcad/fcad.scad>;
|
||||
|
||||
fDrawX(fCylinder(10, r1=5, r2=2))
|
||||
fDrawX(fSphere(10))
|
||||
fDrawX(fCube(10));
|
||||
module testAxes(translation=[0, 0, 0], rotation=[0, 0, 0]) {
|
||||
color("red") fDraw(fTranslate(fRotate(fRotate(fCylinder(h=100, r=1), "start", [0, 90, 0]), "start", rotation), translation));
|
||||
color("green") fDraw(fTranslate(fRotate(fRotate(fCylinder(h=100, r=1), "start", [-90, 0, 0]), "start", rotation), translation));
|
||||
color("blue") fDraw(fTranslate(fRotate(fRotate(fCylinder(h=100, r=1), "start", [0, 0, 0]), "start", rotation), translation));
|
||||
}
|
||||
|
||||
testAxes(translation=[0, 0, 200], rotation=[0, 0, 0]);
|
||||
testAxes(translation=[200, 0, 0], rotation=[0, 180, ]);
|
||||
testAxes(translation=[0, 0, -200], rotation=[180, 0, 0]);
|
||||
testAxes(translation=[-200, 0, 0], rotation=[0, -90, 0]);
|
||||
testAxes(translation=[0, 200, 0], rotation=[-90, 0, 0]);
|
||||
testAxes(translation=[0, -200, 0], rotation=[90, 0, 0]);
|
||||
|
||||
|
||||
//result = fAttach(fCube(10), "top", fCube(5), "bottom5");
|
||||
//result = fRotate(fCube(5), "front", [0, 360, 360]);
|
||||
|
||||
//echo(result);
|
||||
//#fDraw(result);
|
||||
Reference in New Issue
Block a user