> 2 => {
PairsFromProjection:
PROC
RETURNS
[list:
PairList]
~
{
FOR n:
NAT
IN [0..p.nVertices)
DO
q: Triple ¬ GetPoint[p, n];
t: Triple ¬ G3dVector.Sub[p.origin, G3dPlane.ProjectPointToPlane[q, pln]];
t: Triple ¬ G3dPlane.ProjectPointToPlane[q, pln];
pp: Pair ¬ [G3dVector.Dot[t, xAxis], G3dVector.Dot[t, yAxis]];
list ¬ CONS[[G3dVector.Dot[t, xAxis], G3dVector.Dot[t, yAxis]], list];
IF debug
THEN {
Out[IO.PutFR["q = (%g, %g, %g\n", IO.real[q.x], IO.real[q.y], IO.real[q.z]]];
Out[IO.PutFLR["t = (%g, %g, %g), p = (%g, %g)\n",
LIST[IO.real[t.x], IO.real[t.y], IO.real[t.z], IO.real[pp.x], IO.real[pp.y]]]];
};
ENDLOOP;
};
normal: Triple ¬ p.normal ¬ G3dPolygon.PolygonNormal[p.points, p.indices, TRUE];
pln: G3dPlane.Plane ¬ G3dPlane.FromPointAndNormal[GetPoint[p, 0], normal];
plane: Quad ¬ p.plane ¬ [pln.x, pln.y, pln.z, pln.w];
xAxis: Triple ¬ p.xAxis ¬
IF p.twist.tw0 # 0
OR p.twist.tw1 # 0
-- x axis in the plane
THEN G3dVector.Unit[G3dVector.Sub[p.twist.p1, p.twist.p0]]
ELSE G3dVector.Ortho[normal];
yAxis: Triple ¬ p.yAxis ¬ G3dVector.Cross[xAxis, normal];
origin: Triple ¬ G3dVector.Mul[normal, -p.plane.w]; -- origin of plane
mm: G2dBasic.Box ¬ MinMaxOfPairs[PairsFromProjection[]]; -- 2d image bounds
min: Pair ¬ G2dVector.Sub[mm.min, [2*p.extent, 2*p.extent]]; -- extent margin
p.size ¬ G2dVector.Add[[4*p.extent, 4*p.extent], G2dVector.Sub[mm.max, mm.min]];
p.scale ¬ MIN[REAL[p.res.x]/p.size.x, REAL[p.res.y]/p.size.y];
p.origin ¬ G3dVector.Add[origin, G3dVector.Combine[xAxis, min.x, yAxis, min.y]];
IF debug
THEN {
PrintTriple["xAxis", p.xAxis];
PrintTriple["yAxis", p.yAxis];
Out[IO.PutFLR["size: (%g, %g), scale: %g, extent = %g\n",
LIST[IO.real[p.size.x], IO.real[p.size.y], IO.real[p.scale], IO.real[p.extent]]]];
Out[IO.PutFR["min: (%g, %g)\n", IO.real[min.x], IO.real[min.y]]];
PrintTriple["origin", p.origin];
Out[IO.PutFLR["plane: (%g, %g, %g, %g)\n",
LIST[IO.real[p.plane.x], IO.real[p.plane.y], IO.real[p.plane.z], IO.real[p.plane.w]]]];
};
If obviate GetImageProjection scale:
p.xAxis ¬ G3dVector.Mul[xAxis, p.scale];
p.yAxis ¬ G3dVector.Mul[yAxis, p.scale];
p.normal ¬ G3dVector.Mul[normal, p.scale];
If using major plane projection in 2d:
p.major ¬ G3dPlane.GetMajorPlane[p.plane];
p.xAxis ¬ G3dPlane.ProjectPointToMajorPlane[p.xAxis, p.major];
p.yAxis ¬ G3dPlane.ProjectPointToMajorPlane[p.yAxis, p.major];
IF p.twist.tw0 # 0
OR p.twist.tw1 # 0
THEN {
[Artwork node; type 'Artwork on' to command tool]
p.p0x ¬ G3dVector.Add[
p.twist.p0, G3dVector.Project[G3dVector.Sub[p.origin, p.twist.p0], xAxis]];
p.p1x ¬ G3dVector.Add[p.p0x, G3dVector.Mul[xAxis, p.size.x]];
p.h ¬ G3dVector.Dot[yAxis, G3dVector.Sub[p.twist.p0, p.origin]];
[p.accV, p.accW] ¬ NearnessAccelerator[p.twist.p0, p.twist.p1];
};
};
2 => {
p0: Triple ¬ GetPoint[p, 0];
p1: Triple ¬ GetPoint[p, 1];
axis: Triple ¬ G3dVector.Unit[G3dVector.Sub[p1, p0]];
p.origin ¬ p0 ¬ G3dVector.ScaleRay[[p0, axis], -2.0*p.extent];
p1 ¬ G3dVector.ScaleRay[[p1, axis], 2.0*p.extent];
[p.accV, p.accW] ¬ NearnessAccelerator[p0, p1];
p.res.y ¬ 1;
p.scale ¬ REAL[p.res.x]/G3dVector.Distance[p1, p0];
IF debug
THEN
Out[IO.PutFR["segment, scale: %g, extent = %g\n", IO.real[p.scale], IO.real[p.extent]]];
};