1 /** This file is part of Shapes.
3 ** Shapes is free software: you can redistribute it and/or modify
4 ** it under the terms of the GNU General Public License as published by
5 ** the Free Software Foundation, either version 3 of the License, or
8 ** Shapes is distributed in the hope that it will be useful,
9 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 ** GNU General Public License for more details.
13 ** You should have received a copy of the GNU General Public License
14 ** along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 ** Copyright 2008 Henrik Tidefelt
22 R := [evalf(seq(2/N*(N-i),i=1..N))]:
23 phi := [evalf(seq(1.4*Pi/N*(N-i)+0.5,i=1..N))]:
24 p3 := plot3d(sin(x*y),x=-2.1..2.1,y=-2.1..2.1,grid=[15,15],style=patch,color=white): # 2.1 [15,15] el. [25,25] för hög eller
26 points:= [seq([R[i]*sin(phi[i]),R[i]*cos(phi[i]),sin(R[i]*sin(phi[i])*R[i]*cos(phi[i]))],i=1..N)]:
27 p4 := pointplot3d(points,style=LINE,thickness=2,color=black):
28 p5 := pointplot3d(points[-1],color=black,symbol=solidsphere,symbolsize=20):
29 p6 := pointplot3d(points[1],color=black,symbol=solidsphere,symbolsize=20):
31 display(p3,p4,p5,orientation=[-17,25]);
37 /** The function describing the manifold.
39 surfz: \ p .> (0.24*R) * [sin (p.x/u) * (p.y/u)]
41 /** A general-purpose helper.
43 surfit: \ f p .> ( p.x, p.y, [f p] )
45 /** A general-purpose surface-circle.
47 surfaceCircle: \ f r c sides:'12 .>
50 [[range '0 sides-'1].foldl
51 \ p e .> p & [fill mid--[surfit f c+r*[dir (360°*e)/sides]]--[surfit f c+r*[dir (360°*(e+'1))/sides]]--cycle]
55 /** A path on our surface.
62 p--[surfit surfz (2/N)*(N-i)*u*[dir 90°-(1.4*(180°/N)*(N-i)-0)]]
69 helper: \ op nullRes last lst .> [if [null? lst] nullRes [helper op [op nullRes last lst.car] lst.car lst.cdr]]
74 [helper op nullRes lst.car lst.cdr]]
79 helper: \ op nullRes back2 back1 lst .> [if [null? lst] nullRes [helper op [op nullRes back2 back1 lst.car] back1 lst.car lst.cdr]]
86 [helper op nullRes lst.car lst.cdr.car lst.cdr.cdr]]]
89 functionMesh: \ zMap xRange yRange step:'1 .>
91 xyz: \ p .> ( p.x, p.y, [zMap p] )
98 \ p y .> p--[xyz (x,y)]
102 [sublist [consify xRange] step]
111 \ p x .> p--[xyz (x,y)]
115 [sublist [consify yRange] step]
119 functionSurface: \ zMap xRange yRange .>
121 xyz: \ p .> ( p.x, p.y, [zMap p] )
122 xConsRange: [consify xRange]
123 yConsRange: [consify yRange]
137 pc: [xyz (0.5*(x1+x2),0.5*(y1+y2))]
138 [fill pc--p11--p12--cycle]
140 [fill pc--p12--p22--cycle]
142 [fill pc--p22--p21--cycle]
144 [fill pc--p21--p11--cycle]
147 [stroke p11--pc--p22]
149 [stroke p12--pc--p21]
160 [functionMesh zMap xRange yRange]
164 angle_in_ccw_range?: \ a low high .>
166 am: [mod a - low 360°]
167 [if am < 0 am+360° am] < high - low
172 ridgeTest: \ p1 p2 o1 o2 .>
174 d11: [normalized o1 - p1]
175 d12: [normalized o2 - p1]
177 d21: [normalized o1 - p2]
178 d22: [normalized o2 - p2]
180 dc: [normalized p2 - p1]
181 ( dm1*dc <= dm1*d11 ) and ( ~(dm2*dc) <= dm2*d22 )
184 \ zMap xRange yRange tf .>
186 xyz: \ p .> ( p.x, p.y, [zMap p] )
188 xConsRange: [consify xRange]
189 yConsRange: [consify yRange]
195 p11: view [] tf [] [xyz (x1,y1)]
196 p12: view [] tf [] [xyz (x1,y2)]
197 p21: view [] tf [] [xyz (x2,y1)]
198 p22: view [] tf [] [xyz (x2,y2)]
200 pc: view [] tf [] [xyz (0.5*(x1+x2),0.5*(y1+y2))]
201 pc3D: [xyz (0.5*(x1+x2),0.5*(y1+y2))]
205 [if [ridgeTest p11 pc p12 p21] [stroke [xyz (x1,y1)]--pc3D] null3D]
207 [if [ridgeTest p12 pc p11 p22] [stroke [xyz (x1,y2)]--pc3D] null3D]
209 [if [ridgeTest p22 pc p12 p21] [stroke [xyz (x2,y2)]--pc3D] null3D]
211 [if [ridgeTest p21 pc p11 p22] [stroke [xyz (x2,y1)]--pc3D] null3D]
225 p1: view [] tf [] [xyz (x2,y1)]
226 p2: view [] tf [] [xyz (x2,y2)]
227 pc1: view [] tf [] [xyz (0.5*(x1+x2),0.5*(y1+y2))]
228 pc2: view [] tf [] [xyz (0.5*(x2+x3),0.5*(y1+y2))]
229 [if [ridgeTest p1 p2 pc1 pc2]
230 p & [stroke [xyz (x2,y1)]--[xyz (x2,y2)]]
245 p1: view [] tf [] [xyz (x1,y2)]
246 p2: view [] tf [] [xyz (x2,y2)]
247 pc1: view [] tf [] [xyz (0.5*(x1+x2),0.5*(y1+y2))]
248 pc2: view [] tf [] [xyz (0.5*(x1+x2),0.5*(y2+y3))]
249 [if [ridgeTest p1 p2 pc1 pc2]
250 p & [stroke [xyz (x1,y2)]--[xyz (x2,y2)]]
262 T_view: [rotate3D dir:(1,0,0) angle:~90°-~19°]*[rotate3D dir:(0,0,1) angle:~90°+25°]
266 xRange: [range ~R R count: N_major * N_minor + '1]
267 yRange: [range ~R R count: N_major * N_minor + '1]
269 •page << @width:0.8bp
275 << @nonstroking:OCCLUDING
276 | [functionSurface surfz xRange yRange]
277 << [functionMesh surfz xRange yRange N_minor]
278 << [ridgeLines surfz xRange yRange T_view]
281 •page << @width:1.8bp
287 << @cap:CAP_ROUND | [stroke points]
288 << [surfaceCircle surfz 2.5*@width (points.begin.p.x,points.begin.p.y)]
289 << [surfaceCircle surfz 2.5*@width (points.end.p.x,points.end.p.y)]