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
|
% torusexperiment.mp
% L. Nobre G.
% 2014
% DO NOT CHANGE PARAMETERS. YOU HAVE BEEN WARNED!
prologues := 1;
input featpost3Dplus2D;
%SphericalDistortion := true;
%ParallelProj := true;
beginfig(1);
Spread:=70;
numeric bigray, smaray, angstep;
color toruscenter, torusmoment, nearaxe, sideaxe, viewline;
color circlecenter, circlemoment;
numeric ang, ind, i, anglim;
path cpath, apath, opath, ipath, wp, ep;
pair outerp[], innerp[], refpair;
pen markpen;
boolean cuspcond;
picture holepic;
color hvec, fakef, visualcircenter, hvecf, perpvec, axisvec;
numeric rratio, hratio, visualray, resultang;
numeric fakedist, fakeangle, fakeviewlimitangle, tmpangle;
markpen = pencircle scaled 5pt;
pickup markpen;
bigray = 5;
smaray = 1;
%message "Villarceau angle: " & decimal(angle(bigray+-+smaray,smaray));
message "Actual view angle: " & decimal(angle(X(f)++Y(f),Z(f)));
angstep= 0.5;
toruscenter = black;
torusmoment = (0,0,1);
% f := (3,-6,3);
%%%%%%%%%%%%%%%%%%%%%%%%%%% f := 3*(0,4.24706,0.67267); fakedist = 7.3;
f := (7,4,2); fakedist = 4.3; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fakeangle = 9;
fakeviewlimitangle = 2;
% fakef = (0,4,3);
% fakef = f;
% fakef = (-Y(f),X(f),Z(f));
fakef = (0,fakedist*cosd(fakeangle),fakedist*sind(fakeangle));
%show fakef;
%endfig;
%end.
if cdotprod(f-viewcentr,torusmoment)<0 :
torusmoment := -torusmoment;
fi;
refpair = unitvector( rp(toruscenter+torusmoment)-rp(toruscenter) );
viewline = f-toruscenter;
ind = 0;
sideaxe = bigray*ncrossprod( torusmoment, viewline );
nearaxe = bigray*ncrossprod( sideaxe, torusmoment );
anglim = 0.5*angstep-180;
hvec = cdotprod(f-toruscenter,N(torusmoment))*N(torusmoment);
hratio = conorm(hvec)/bigray;
rratio = conorm(f-toruscenter-hvec)/bigray;
for ang=anglim step angstep until -anglim:
ind := incr( ind );
circlecenter:= nearaxe*cosd(ang)+sideaxe*sind(ang);
circlemoment:=-nearaxe*sind(ang)+sideaxe*cosd(ang);
cpath:=spatialhalfcircle(circlecenter,circlemoment,smaray,true);
if ang>=0:
outerp[ind]=point 0 of cpath;
innerp[ind]=point (length cpath) of cpath;
elseif ang<0:
innerp[ind]=point 0 of cpath;
outerp[ind]=point (length cpath) of cpath;
fi;
endfor;
opath = for i=1 upto ind: outerp[i].. endfor cycle;
ipath = for i=1 upto ind: innerp[i].. endfor cycle;
holepic = currentpicture;
clip holepic to ipath;
unfill opath;
draw holepic;
draw ipath withcolor red;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% There is an analytic way of getting the angle of the cusp point! %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i := ceiling(1+180/angstep);
forever:
i := incr( i );
cuspcond := refpair dotprod innerp[i+1] < refpair dotprod innerp[i];
exitif cuspcond or ( i > ind-1 );
endfor;
resultang = anglim+angstep*(i-1);
write decimal(smaray/bigray) & " " & decimal(rratio) & " " & decimal(hratio) & " " & decimal(resultang) to "torusexperimentoneline.dat";
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ep = outerp[ind-i]--innerp[ind-i];
wp = innerp[i]--outerp[i];
unfill buildcycle(opath,ep,reverse ipath,wp);
draw opath withcolor green;
draw subpath (i,ind-i) of ipath withcolor red;
hvecf = cdotprod(fakef-toruscenter,N(torusmoment))*N(torusmoment);
visualcircenter = 0.5[toruscenter+hvecf,fakef];
axisvec = fakef-visualcircenter;
visualray = conorm( axisvec );
perpvec = ncrossprod(axisvec,torusmoment)*visualray;
color tmpf, tmpc, tmpp[], tmpq[], tmpa, tmpv;
numeric theta, alpha, beta;
tmpv = N(torusmoment);
i := 0;
drawoptions( withcolor blue withpen pencircle scaled 5pt );
for theta=2*anglim step angstep until -2*anglim:
tmpf := visualcircenter+planarrotation( axisvec, perpvec, theta );
tmpa := N( planarrotation( axisvec, perpvec, theta/2 ) );
tmpc := toruscenter+tmpa*bigray;
beta := getangle(tmpa,tmpf-tmpc);
alpha := angle( smaray, conorm( tmpf-tmpc ) +-+ smaray ); %%%%%%%%%%%%
tmpp[i] := tmpc + smaray*planarrotation( -tmpa, tmpv, 180-alpha-beta );
tmpq[i] := tmpc + smaray*planarrotation( -tmpa, tmpv, 180+alpha-beta );
if i>0:
tmpangle := getangle(tmpp[i]-tmpp[i-1],tmpp[i]-fakef);
%write decimal(i) & " " & decimal(tmpangle) to "torusexperimentangles.dat";
if (tmpangle<fakeviewlimitangle) or (180-tmpangle<fakeviewlimitangle):
draw rp(tmpp[i])--rp(fakef) withpen pencircle scaled 0pt;
fi;
fi;
i := incr(i);
endfor;
draw rp(fakef);
if smaray>bigray:
draw rp(toruscenter+tmpv*(smaray+-+bigray));
draw rp(toruscenter-tmpv*(smaray+-+bigray));
fi;
ind := i-1;
drawoptions();
pickup pencircle scaled 0pt;
draw rp(fakef)--rp((X(fakef),Y(fakef),0))--rp((0,bigray,0))--cycle dashed evenly;
draw goodcirclepath((0,bigray,0),red,smaray) dashed evenly;
draw for i=0 upto ind: rp(tmpp[i]).. endfor cycle;
draw for i=0 upto ind: rp(tmpq[i]).. endfor cycle;
pickup pencircle scaled 2pt;
draw spatialhalfcircle( toruscenter, torusmoment, bigray+smaray, true );
%draw rigorouscircle( toruscenter, torusmoment, bigray-smaray );
draw rigorouscircle( toruscenter+smaray*tmpv, torusmoment, bigray );
%draw rigorouscircle( toruscenter-smaray*tmpv, torusmoment, bigray );
picture tmppicture;
path zoomwindow;
zoomwindow = (550,230)--(750,230)--(750,330)--(550,330)--cycle;
tmppicture = currentpicture;
clip tmppicture to zoomwindow;
endfig;
beginfig(2);
draw tmppicture scaled 4;
endfig;
end.
|