2 % Very simple model of my hand
\r
6 % In particular, this completely ignores the carpal joints.
\r
8 % Try this with various options to sketch.
\r
11 % -D ok > none or one of these
\r
15 % -D frontview > none or one of these
\r
20 % I am not responsible for modifications to draw
\r
23 % parameterization of model
\r
25 % for fingers, 0 is thumb, 1 is index,
\r
26 % 2 is middle, 3 is ring, 4 is little
\r
28 % lateral angle between fingers
\r
34 % and between thumb and index finger
\r
41 % rotations of finger parts
\r
42 % distal is the finger tip
\r
43 % middle is below that
\r
44 % meta is the knuckle
\r
103 % dependent rotations
\r
104 % fingers have the last two joints wired together
\r
105 def middle_1_rot distal_1_rot
\r
106 def middle_2_rot distal_2_rot
\r
107 def middle_3_rot distal_3_rot
\r
108 def middle_4_rot distal_4_rot
\r
111 def proximal_rad .6
\r
116 def middle_ratio 1.8
\r
117 def proximal_distal_ratio proximal_rad / distal_rad
\r
119 % primitive segment of a finger is a truncated cone
\r
122 sweep { n_faces<>, rotate(360 / n_faces, [J]) }
\r
123 line(proximal_rad, 0)(distal_rad, distal_len)
\r
126 % spheres to connect segments at joints
\r
128 def n_joint_faces 8
\r
129 sweep [fillcolor=red] { n_joint_faces, rotate(360 / n_joint_faces, [J]) }
\r
130 sweep { n_joint_faces, rotate(180 / n_joint_faces) }
\r
134 % following is five separate definitions for five fingers
\r
135 % with parameters, this would be much shorter!
\r
138 put { translate(joint_gap * joint_rad * [J])
\r
139 then rotate(distal_0_rot, [I])
\r
140 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
142 put { rotate(distal_0_rot / 2, [I])
\r
143 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
145 put { scale( [J] + proximal_distal_ratio * ([I]+[K]) ) }
\r
150 put { translate(joint_gap * joint_rad * [J])
\r
151 then rotate(middle_0_rot, [I])
\r
152 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
154 put { scale(proximal_distal_ratio)
\r
155 then rotate(middle_0_rot / 2, [I])
\r
156 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
158 put { scale( middle_ratio * [J] + proximal_distal_ratio^2 * ([I]+[K]) ) }
\r
163 put { translate(joint_gap * joint_rad * [J])
\r
164 then rotate(distal_1_rot, [I])
\r
165 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
167 put { rotate(distal_1_rot / 2, [I])
\r
168 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
170 put { scale( [J] + proximal_distal_ratio * ([I]+[K]) ) }
\r
175 put { translate(joint_gap * joint_rad * [J])
\r
176 then rotate(middle_1_rot, [I])
\r
177 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
179 put { scale(proximal_distal_ratio)
\r
180 then rotate(middle_1_rot / 2, [I])
\r
181 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
183 put { scale( middle_ratio * [J] + proximal_distal_ratio^2 * ([I]+[K]) ) }
\r
188 put { translate(joint_gap * joint_rad * [J])
\r
189 then rotate(distal_2_rot, [I])
\r
190 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
192 put { rotate(distal_2_rot / 2, [I])
\r
193 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
195 put { scale( [J] + proximal_distal_ratio * ([I]+[K]) ) }
\r
200 put { translate(joint_gap * joint_rad * [J])
\r
201 then rotate(middle_2_rot, [I])
\r
202 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
204 put { scale(proximal_distal_ratio)
\r
205 then rotate(middle_2_rot / 2, [I])
\r
206 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
208 put { scale( middle_ratio * [J] + proximal_distal_ratio^2 * ([I]+[K]) ) }
\r
213 put { translate(joint_gap * joint_rad * [J])
\r
214 then rotate(distal_3_rot, [I])
\r
215 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
217 put { rotate(distal_3_rot / 2, [I])
\r
218 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
220 put { scale( [J] + proximal_distal_ratio * ([I]+[K]) ) }
\r
225 put { translate(joint_gap * joint_rad * [J])
\r
226 then rotate(middle_3_rot, [I])
\r
227 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
229 put { scale(proximal_distal_ratio)
\r
230 then rotate(middle_3_rot / 2, [I])
\r
231 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
233 put { scale( middle_ratio * [J] + proximal_distal_ratio^2 * ([I]+[K]) ) }
\r
238 put { translate(joint_gap * joint_rad * [J])
\r
239 then rotate(distal_4_rot, [I])
\r
240 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
242 put { rotate(distal_4_rot / 2, [I])
\r
243 then translate((distal_len + joint_gap * joint_rad) * [J]) }
\r
245 put { scale( [J] + proximal_distal_ratio * ([I]+[K]) ) }
\r
250 put { translate(joint_gap * joint_rad * [J])
\r
251 then rotate(middle_4_rot, [I])
\r
252 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
254 put { scale(proximal_distal_ratio)
\r
255 then rotate(middle_4_rot / 2, [I])
\r
256 then translate((middle_ratio * distal_len + joint_gap * joint_rad) * [J]) }
\r
258 put { scale( middle_ratio * [J] + proximal_distal_ratio^2 * ([I]+[K]) ) }
\r
262 % points on the palm of the hand
\r
263 def proximal_0_loc (1.8,-5.5,0)
\r
264 def proximal_1_loc (1.8,.1,0)
\r
265 def proximal_2_loc (O)
\r
266 def proximal_3_loc (-1.8,-.2,0)
\r
267 def proximal_4_loc (-3.6,-.5,0)
\r
268 def h5 (proximal_4_loc) + [-.6,-.2]
\r
269 def h6 (h5) + [1,-5]
\r
270 def h8 (proximal_0_loc) + [.75,-.5]
\r
271 def h7 (h8) + [-.6,-.8]
\r
272 def h6a (h6) + .6 * ((h7) - (h6))
\r
273 def h9 (h8) + [-1.9,1]
\r
274 def h10 (proximal_1_loc) + [.85,-.3]
\r
278 % thumb has an extra rotation for opposable-ness!
\r
279 def opposition_rot rotate(-50, [J])
\r
280 def thk_scale_0 1.2
\r
281 put { scale([thk_scale_0,.9,thk_scale_0]) % this distorts a little; oh well
\r
282 then translate((joint_gap * joint_rad) * [J])
\r
283 then [[opposition_rot]]
\r
284 then rotate(meta_0_rot, [I])
\r
285 then rotate(-spread_rot_0, [K])
\r
286 then translate((proximal_0_loc) - (O)) }
\r
289 put { scale(thk_scale_0 * proximal_distal_ratio^2)
\r
290 then [[opposition_rot]]
\r
291 then rotate(meta_0_rot / 2, [I])
\r
292 then rotate(-spread_rot_0, [K])
\r
293 then translate((proximal_0_loc) - (O)) }
\r
298 put { scale(scale_1)
\r
299 then translate((joint_gap * joint_rad) * [J])
\r
300 then rotate(meta_1_rot, [I])
\r
301 then rotate(-spread_rot, [K])
\r
302 then translate((proximal_1_loc) - (O)) }
\r
305 put { scale(scale_1 * proximal_distal_ratio^2)
\r
306 then rotate(meta_1_rot / 2, [I])
\r
307 then rotate(-spread_rot, [K])
\r
308 then translate((proximal_1_loc) - (O)) }
\r
312 put { % no scale then
\r
313 translate((joint_gap * joint_rad) * [J])
\r
314 then rotate(meta_2_rot, [I])
\r
315 % no spread rotation
\r
316 then translate((proximal_2_loc) - (O)) }
\r
319 put { scale(proximal_distal_ratio^2)
\r
320 then rotate(meta_2_rot / 2, [I])
\r
321 then translate((proximal_2_loc) - (O)) }
\r
326 put { scale(scale_3)
\r
327 then translate((joint_gap * joint_rad) * [J])
\r
328 then rotate(meta_3_rot, [I])
\r
329 then rotate(spread_rot, [K])
\r
330 then translate((proximal_3_loc) - (O)) }
\r
333 put { scale(scale_3 * proximal_distal_ratio^2)
\r
334 then rotate(meta_3_rot / 2, [I])
\r
335 then rotate(spread_rot, [K])
\r
336 then translate((proximal_3_loc) - (O)) }
\r
341 put { scale(scale_4)
\r
342 then translate((joint_gap * joint_rad) * [J])
\r
343 then rotate(meta_4_rot, [I])
\r
344 then rotate(2 * spread_rot, [K])
\r
345 then translate((proximal_4_loc) - (O)) }
\r
348 put { scale(scale_4 * proximal_distal_ratio^2)
\r
349 then rotate(meta_4_rot / 2, [I])
\r
350 then rotate(2 * spread_rot, [K])
\r
351 then translate((proximal_4_loc) - (O)) }
\r
354 % palm is built by sweeping a polygon through a small
\r
355 % angle in order to make it thicker at the wrist
\r
356 put { translate(joint_gap * joint_rad * -[J]) } % drop polytope to expose knuckles
\r
357 sweep { 1, rotate(6, (0,15,0), [I]) }
\r
358 put { rotate(-3, (0,15,0), [I]) } {
\r
359 % need two polygons for convexity; the desired shape is concave at the thumb
\r
360 polygon(proximal_1_loc)(proximal_2_loc)(proximal_3_loc)(proximal_4_loc)
\r
361 (h5)(h6)(h6a)(h9)(h10)
\r
362 polygon(h6a)(h7)(h8)(h9)
\r
368 <frontview> view((0,0,10))
\r
369 <sideview> view((10,0,0))
\r
370 <topview> view((0,10,0), (O), -[K])
\r
373 % either a single copy or a repeat to show different angles
\r
376 put { [[viewxf]] then scale(.25) } {
\r
378 repeat { N, rotate(270/N, [3,2,1]), translate(14*[I]) } {hand}
\r
380 <> put { [[viewxf]] then scale(.3) } {hand}
\r