-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSolidPrismFromVerticesOfPolygonContainingOrigin.inc
79 lines (57 loc) · 2.39 KB
/
SolidPrismFromVerticesOfPolygonContainingOrigin.inc
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "math.inc"
#include "PointCutter.inc"
/*
Creates a solid prism from the points of a convex polygon containing the origin.
The sides of the prism are moved to the inside by `Offset`.
Vertex points are expected in correct order, last point equal to first.
The origin must be properly within the polygon, i.e. not on an edge.
*/
#macro SolidPrismFromVerticesOfPolygonContainingOrigin(Points, Offset, PrismThickness)
#local Debug = false;
// perpendicular to the plane containing the vertices (and the origin)
#local PerpPlane = VPerp_To_Plane(Points[0], Points[1]);
// from this cylinder the prism will be cut
#local Cylinder = cylinder{
PerpPlane*PrismThickness/2, -PerpPlane*PrismThickness/2, 100
#if (Debug)
pigment{color rgbt<.5,.5,.5,.5>}
#end
}
#local CutUnion = union{
#local ArrayLen = dimension_size(Points, 1);
#for (Index, 0, ArrayLen-2)
#local A = Points[Index];
#local B = Points[Index+1];
#local Diff = B - A;
// perpendicular to the line through A and B in the main plane
#local Perp = VPerp_Adjust(A, Diff);
// distance of the line through A and B from O
// http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
#local LenA = vlength(A);
#local LenDiff = vlength(Diff);
#local NumeratorMinuend = pow(LenA,2) * pow(LenDiff,2);
#local NumeratorSubtrahend = pow( vdot( A, Diff ), 2 );
#local Denominator = pow( LenDiff, 2 );
#local Dist = sqrt( (NumeratorMinuend - NumeratorSubtrahend) / Denominator );
// intersection point of the line through A and B and the perpendicular
#local SectPoint = Perp * Dist;
#if (!Debug)
// add the halfspace at this point to the cut union
PointCutter(SectPoint, Offset)
#else
sphere{A, 2*PrismThickness pigment{color Blue} }
sphere{SectPoint, 1.5*PrismThickness pigment{color Green} }
#end
#end
}
#if (!Debug)
difference{
object{Cylinder}
object{CutUnion}
}
#else
cylinder{<0,0,0>, PerpPlane, PrismThickness pigment{color Red} }
object{Cylinder}
object{CutUnion}
#end
#end