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
|
tikz.within( '*' )
local cos = math.cos
local sin = math.sin
local pi = math.pi
-- granularity of calculation
local fine = 10
-- factor the projection length is reduced
local fproj = 0.35
-- strength of the ellipse mediums
local s1 = 1.00
local s2 = 1.50
local s3 = 1.75
local e1 = ellipse{ at=p{ 0.00, 0.00 }, xradius=3.00, yradius=3.00 }
local e2 = ellipse{ at=p{ 0.40, 1.20 }, xradius=0.85, yradius=0.50 }
local e3 = ellipse{ at=p{ 0.00, -0.89 }, xradius=1.00, yradius=0.60 }
draw{ fill='black!08!white', line_width=1, e1 }
draw{ fill='black!16!white', line_width=1, e2 }
draw{ fill='black!24!white', line_width=1, e3 }
-- list of projection angles
local listphi =
{
-1/4 * pi,
2/4 * pi,
5/4 * pi,
}
-- length of projection lines
local lenmaintop = 5.0
local lenmainbot = 6.5
for proji, phimain in ipairs( listphi )
do
local lmain =
line{
p{ cos( phimain ), sin( phimain ) } * -lenmaintop,
p{ cos( phimain ), sin( phimain ) } * lenmainbot,
}
local phinorm = phimain - pi/2
-- gets a point on the projection.
-- dp: distance from projection center
-- dv: projection value
function getpproj( dp, dv )
return(
lmain.p2
+ p{ cos( phinorm ) * dp, sin( phinorm ) * dp }
+ p{ cos( phimain ) * dv * fproj, sin( phimain ) * dv * fproj }
)
end
-- distance of projection line
local ddis = 1 / fine
-- list of all projection points
local listp = { }
for i = -3.5 * fine, 3.5 * fine
do
local p1i =
lmain.p1
+ p{ cos( phinorm ) * ddis * i, sin( phinorm ) * ddis * i }
local li = line{ p1i, p1i + ( lmain.p2 - lmain.p1 ) }
local lv = 0
local is1 = e1.intersectLine( li )
if is1 and #is1 > 1
then
local lis = line{ is1[ 1 ], is1[ 2 ] }
lv = lv + lis.length * s1
end
local is2 = e2.intersectLine( li )
if is2 and #is2 > 1
then
local lis = line{ is2[ 1 ], is2[ 2 ] }
lv = lv + lis.length * s2
end
local is3 = e3.intersectLine( li )
if is3 and #is3 > 1
then
local lis = line{ is3[ 1 ], is3[ 2 ] }
lv = lv + lis.length * s3
end
local pproj = getpproj( ddis * i, lv )
if i % ( 0.7 * fine ) == 0
then
draw{
dotted, arrow, line_width=0.5,
line{ li.p1, getpproj( ddis * i, -0.20 ) },
}
draw{
dotted, line_width=0.5,
line{ li.p1, pproj },
}
end
table.insert( listp, pproj )
end
-- draws the projection screen
local lenlproj = 8
draw{
line{
getpproj( lenlproj / 2, 0 ),
getpproj( -lenlproj / 2, 0 ),
}
}
-- draws the projection curve
draw{ line_width=1, polyline{ table.unpack( listp ) } }
end
|