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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
ifdef(`View3d',,`threeD_init')
divert(-1)
# Shapedefs.m4
# 3D structures with complex surfaces and hidden lines are the domain of more
# sophisticated software packages, but basic shapes can be drawn with pic.
#####################################################
`cylinder3D(xdispl,ydispl,zdispl,diameter,
[colored "color"])'
define(`cylinder3D',`[ Start: (0,0)
xdispl = `$1'; ydispl = `$2'; zdispl = `$3'
define(`M4CL',`xdispl,ydispl,zdispl')dnl
lenc = length3D(M4CL)
diamc = ifelse(`$4',,(lenc/2),`$4') ; radc = diamc/2
cs = dot3D(View3D,M4CL)/lenc
End: Project(M4CL)
az = atan2(ydispl,xdispl)
ae = atan2(zdispl,sqrt(xdispl^2+ydispl^2))
CL: line invis from Start to End; C: CL.c
nls = int(twopi_*radc/lthick)
define(`M4PP',`rot3Dz(az,rot3Dy(-ae,rot3Dx(-i/nls*twopi_,0,0,radc)))')dnl
for i=0 to nls-1 do { if dot3D(View3D,M4PP) > 0 then {
P: Project(M4PP)
ql = sqrta(dot3D(Light3D,M4PP)/radc)
line from P to End+P outlined rgbstring(ql,ql,ql) `$5' } }
Perp: (vperp(CL,radc))
if cs > 0 then { T: End; B: Start } else { T: Start; B: End }
rpoint_(from Start to Perp)
css = sqrta(cs)
Top: rotellipse(diamc,diamc*cs,
thick linethick/3 shaded rgbstring(css,css,css)) with .c at T
W: line thick linethick/3 from T+Perp to B+Perp
Bot: ellipsearc(diamc,diamc*cs,pi_,twopi_,rp_ang,cw,
thick linethick/3) with .C at B
E: line thick linethick/3 from B-Perp to T-Perp
rpoint_(from Start to End)
`$6']')
`cone3D(xdispl,ydispl,zdispl,diameter,
[colored "color"])'
`internal positions:
Start (centre of base),
End (point),
C (axis centre)'
define(`cone3D',`[ Start: (0,0)
xdispl = `$1'; ydispl = `$2'; zdispl = `$3'
define(`M4CL',`xdispl,ydispl,zdispl')dnl
lenc = length3D(M4CL)
diamc = ifelse(`$4',,(lenc/2),`$4') ; radc = diamc/2
End: Project(M4CL)
cs = dot3D(View3D,M4CL)/lenc
az = atan2(ydispl,xdispl)
ae = atan2(zdispl,sqrt(xdispl^2+ydispl^2))
CL: line invis from Start to End; C: CL.c
nls = int(twopi_*radc/lthick)
lt = sqrt(radc^2+lenc^2)
b = 0
for i=0 to nls-1 do { if dot3D(View3D,
rot3Dz(az,rot3Dy(-ae,rot3Dx(-i/nls*twopi_,radc,0,lenc)))) > 0 then {
ql = sqrta(dot3D(Light3D,
rot3Dz(az,rot3Dy(-ae,rot3Dx(-i/nls*twopi_,radc,0,lenc))))/lt)
P: Project(rot3Dz(az,rot3Dy(-ae,rot3Dx(-i/nls*twopi_,0,0,radc))))
line from P to End outlined rgbstring(ql,ql,ql) `$5'
if !b then { WB: P; b = 1 }
} else { if b then { BW: P; b = 0 } } }
if vlength(CL.x,CL.y) != 0 then { Perp: (vperp(CL,radc,R)) } \
else { Perp: (radc,0) }
if cs >= 0 then { T: End; B: Start } else {T: Start; B: End }
rpoint_(from Start to Perp)
pout = (vlength(End.x,End.y) > abs(radc*cs))
if cs < 0 then { css = sqrta(cs)
if pout then { line thick linethick/3 from BW to End then to WB }
Bot: rotellipse(diamc,diamc*cs,thick linethick/3 \
ifelse(`$5',,`shaded rgbstring(css,css,css)',`$5')) with .c at T } \
else { if pout then {
line thick linethick/3 from BW to End then to WB
a = acos((WB.x*Perp.x+WB.y*Perp.y)/radc^2)
Bot: ellipsearc(diamc,diamc*cs,a,pi_-a,rp_ang,cw, thick linethick/3) \
with .C at B } \
else {
Bot: rotellipse(diamc,diamc*cs,thick linethick/3) with .c at B } }
rpoint_(from Start to End)
`$6']')
`Arrow3D(xdispl,ydispl,zdispl,
diam,arrowwid,arrowht)'
define(`Arrow3D',`[ diam_Ar = ifelse(`$4',,linewid/10,`$4')
wid_Ar = ifelse(`$5',,diam_Ar*2,`$5')
ht_Ar = ifelse(`$6',,wid_Ar*2,`$6')
x_Ar = ifelse(`$1',,1,`$1')
y_Ar = ifelse(`$2',,1,`$2')
z_Ar = ifelse(`$3',,1,`$3')
define(`M4Arrow3D',`x_Ar,y_Ar,z_Ar')dnl
len_Ar = length3D(M4Arrow3D)
len_Shaft = len_Ar - ht_Ar
cs_Ar = dot3D(View3D,M4Arrow3D)
if cs_Ar >= 0 then {
Shaft: cylinder3D(sprod3D(len_Shaft/len_Ar,M4Arrow3D),diam_Ar)
Head: cone3D(sprod3D(ht_Ar/len_Ar,M4Arrow3D),wid_Ar) \
with .Start at Shaft.End } \
else {
Head: cone3D(sprod3D(ht_Ar/len_Ar,M4Arrow3D),wid_Ar)
Shaft: cylinder3D(sprod3D(len_Shaft/len_Ar,M4Arrow3D),diam_Ar) \
with .End at Head.Start }
Start: Shaft.Start; End: Head.End
`$7']')
define(`f2xyz3D',``$1'x = `$2'
`$1'y = `$3'
`$1'z = `$4' ')
`prism3D(xdispl,ydispl,zdispl,endwid,endht,
(rad)rotation)
args1-3 are the 3D coords of .End wrt .Start
arg6 is rotation about x axis
Defined points .Start, .End, .C'
define(`prism3D',`[ Start: (0,0)
xdispl = ifelse(`$1',,linewid,`$1')
ydispl = ifelse(`$2',,linewid,`$2')
zdispl = ifelse(`$3',,linewid,`$3')
widp = ifelse(`$4',,(linewid/5),`$4')
htp = ifelse(`$5',,(linewid/10),`$5')
rotp = ifelse(`$6',,0,`$6')
End: Project(xdispl,ydispl,zdispl); C: 0.5 between Start and End
lenp = length3D(xdispl,ydispl,zdispl)
az = atan2(ydispl,xdispl); ae = atan2(zdispl,sqrt(xdispl^2+ydispl^2))
wp2 = widp/2; hp2 = htp/2
# 3D coords of corners (B=back, F=front)
f2xyz3D(nwB,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp, 0,-wp2, hp2))))
f2xyz3D(swB,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp, 0,-wp2,-hp2))))
f2xyz3D(seB,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp, 0, wp2,-hp2))))
f2xyz3D(neB,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp, 0, wp2, hp2))))
f2xyz3D(nwF,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp,lenp,-wp2, hp2))))
f2xyz3D(swF,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp,lenp,-wp2,-hp2))))
f2xyz3D(seF,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp,lenp, wp2,-hp2))))
f2xyz3D(neF,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp,lenp, wp2, hp2))))
# facets
M4Facet3D(neF,nwF,swF,seF)
M4Facet3D(neB,seB,swB,nwB)
M4Facet3D(neF,seF,seB,neB)
M4Facet3D(neF,neB,nwB,nwF)
M4Facet3D(seF,swF,swB,seB)
M4Facet3D(nwF,nwB,swB,swF)
`$7']')
`M4Facet3D( a,b,c,d )'
define(`M4Facet3D',`
define(`PFacet',`cross3D(diff3D(`$2'x,`$2'y,`$2'z,`$1'x,`$1'y,`$1'z),
diff3D(`$3'x,`$3'y,`$3'z,`$2'x,`$2'y,`$2'z))')
if dot3D(View3D,PFacet) > 0 then {
fFacet = sqrta(dot3D(Light3D,PFacet)/length3D(PFacet))
P1: Project(`$1'x,`$1'y,`$1'z)
P2: Project(`$2'x,`$2'y,`$2'z)
P3: Project(`$3'x,`$3'y,`$3'z)
P4: Project(`$4'x,`$4'y,`$4'z)
line fill_(fFacet) invis from P1 to P2 then to P3 then to P4 then to P1
line from P1 to P2; round
line to P3; round
line to P4; round
line to P1; round } ')
`M4Pgram3D( c,dne,dnw )'
define(`M4Pgram3D',`
f2xyz3D(ne,sum3D(`$1'x,`$1'y,`$1'z,`$3'x,`$3'y,`$3'z))
f2xyz3D(nw,sum3D(`$1'x,`$1'y,`$1'z,`$2'x,`$2'y,`$2'z))
f2xyz3D(sw,diff3D(`$1'x,`$1'y,`$1'z,`$2'x,`$2'y,`$2'z))
f2xyz3D(se,diff3D(`$1'x,`$1'y,`$1'z,`$3'x,`$3'y,`$3'z))
define(`PPgrapm',`cross3D(
diff3D(nwx,nwy,nwz,nex,ney,nez),
diff3D(swx,swy,swz,nwx,nwy,nwz))')
if dot3D(View3D,PPgram) > 0 then {
fPgram = sqrta(dot3D(Light3D,PPgram)/length3D(PPgram))
P1: Project(`$1'x,`$1'y,`$1'z)
P2: Project(`$2'x,`$2'y,`$2'z)
P3: Project(`$3'x,`$3'y,`$3'z)
P4: Project(`$4'x,`$4'y,`$4'z)
line fill_(fPgram) invis from P1 to P2 then to P3 then to P4 then to P1
line from P1 to P2; round
line to P3; round
line to P4; round
line to P1; round } ')
`prism3D(
xdispl,ydispl,zdispl,endwid,endht,(rad)rotation,
index,dataname,r,g,b)
Defined points .Start, .End, .C
args1-3 are the input 3D coords of .End wrt .Start
args4-5 define the end dimensions
arg6 is rotation about x axis
arg7 is the current depth of the data vector
arg8 is the name (e.g. X) of the vector of
stored face distance, color, and projected coords:
eg X0[n]=[d,r]; X1[n]=[g,b]
X2[n]=proj(C); X3[n]=proj(NE); X4[n]=proj(NW)'
define(`prism3D',`[ Start: (0,0)
xdispl = ifelse(`$1',,linewid,`$1')
ydispl = ifelse(`$2',,linewid,`$2')
zdispl = ifelse(`$3',,linewid,`$3')
widp = ifelse(`$4',,(linewid/5),`$4')
htp = ifelse(`$5',,(linewid/10),`$5')
rotp = ifelse(`$6',,0,`$6')
End: Project(xdispl,ydispl,zdispl); C: 0.5 between Start and End
lenp = length3D(xdispl,ydispl,zdispl)
az = atan2(ydispl,xdispl); ae = atan2(zdispl,sqrt(xdispl^2+ydispl^2))
wp2 = widp/2; hp2 = htp/2
# 3D coords of corners (B=back, F=front)
f2xyz3D(nwB,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp, 0,-wp2, hp2))))
f2xyz3D(swB,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp, 0,-wp2,-hp2))))
f2xyz3D(seB,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp, 0, wp2,-hp2))))
f2xyz3D(neB,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp, 0, wp2, hp2))))
f2xyz3D(nwF,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp,lenp,-wp2, hp2))))
f2xyz3D(swF,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp,lenp,-wp2,-hp2))))
f2xyz3D(seF,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp,lenp, wp2,-hp2))))
f2xyz3D(neF,rot3Dz(az,rot3Dy(-ae,rot3Dx(rotp,lenp, wp2, hp2))))
# facets
M4Facet3D(neF,nwF,swF,seF)
M4Facet3D(neB,seB,swB,nwB)
M4Facet3D(neF,seF,seB,neB)
M4Facet3D(neF,neB,nwB,nwF)
M4Facet3D(seF,swF,swB,seB)
M4Facet3D(nwF,nwB,swB,swF)
`$7']')
#####################################################
divert(0)dnl
|