Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/Playing+3D?V=17
QUERY_STRINGV=17
CONTENT_TYPE
DOCUMENT_URI/revision/Playing+3D
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.69.7.80
REMOTE_PORT53280
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR18.218.196.182
HTTP_CF_RAY87e1a76d48536215-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP18.218.196.182
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {Playing 3D} ----\n\[WikiDbImage\ 3d.gif\]\n\n\[Richard\ Suchenwirth\]\ 2002-04-02\ -\ In\ this\ Easter\ fun\ project,\ I\ experimented\ with\nrendering\ three-dimensional\ objects\ on\ a\ two-dimensional\ \[canvas\].\ Points\nin\ 3D\ space\ are\ specified\ by\ x,\ y,\ and\ z\ coordinates\ (if\ only\ two\ are\ given,\nz\ defaults\ to\ 0,\ \"upgrading\"\ 2D\ points)\;\ such\ points\ can\ be\nused\ to\ construct\ lines\ and\ polygons\ (ovals\ too,\ but\ those\ may\ suffer\nfrom\ distortions).\ Also,\ the\ shadowing\ of\ background\ objects\ by\ foreground\ objects\ leaves\ room\ for\ improvement\ -\ncurrently\ this\ is\ only\ controlled\ by\ the\ order\ of\ creation.\n\nThe\ 2D\ projection\ of\ points\ is\ based\ on\ parallel\ projection,\ with\ some\nperspective\ thrown\ in.\ It\ depends\ heavily\ on\ the\ view\ angle,\ which\ I\ simply\ take\ as\ the\ visual\ angle\ between\ x\ and\ y\ axis.\ The\ x\ axis\ is\ horizontal\ as\ usual,\ z\ axis\ is\ vertical.\ For\ better\norientation,\ the\ axes\ are\ painted\ red\ (x),\ green\ (y),\ and\ blue\ (z).\nType\ \"x\"/\"y\"/\"z\"\ to\ switch\ temporarily\ to\ a\ 2D\ projection\ along\ the\ specified\naxis.\ In\ the\ demo\ program,\ which\ shows\ a\ little\ \"doll\ house\"\ (even\ with\nbadly\ hidden\ Easter\ eggs\ \;-),\ children\ may\ collect\ eggs\ by\ clicking\ on\ them\n(they'll\ turn\ to\ 0-s\ in\ the\ title\ bar).\ For\ adults,\ they\ might\ serve\ to\ verify\nspatial\ arrangement.\n\nYou\ can\ modify\ the\ '''view\ angle'''\ in\ steps\ of\ 5\ degrees\ with\ cursor\nLeft/Right\ keys,\ or\ '''zoom\ in/out'''\ with\ Up/Down\ keys.\ As\ the\ canvas\ncan't\ keep\ the\ 3D\ information,\ changes\ in\ view\ are\ done\ by\ redrawing\neverything\ from\ a\ backing\ store\ \[array\],\ which\ keeps\ all\ parameters\nfor\ every\ object.\ Reaction\ was\ just\ about\ fast\ enough\ on\ my\ P200\ machine.\n\nThe\ standard\ operations\ of\ translating\ (=moving),\ scaling,\nand\ rotating\ 3D\ objects\ are\ implemented\ -\ maybe\ not\ optimally,\ but\ndoing\ their\ job.\ They\ operate\ on\ tags,\ because\ most\ often\ an\nobject\ is\ composed\ of\ several\ primitives\ which\ share\ the\ same\ tag.\n'''Moving'''\ can\ be\ tested\ with\ the\ table\ and\ chairs\ -\ click\ on\ one\ to\ select,\nuse\ Shift-cursor\ keys\ to\ push\ it\ around\ (and\ ignore\ possible\ uglities\nin\ shadowing\ by\ other\ objects).\ To\ test\ movement\ in\ z\ direction,\ntype\ \"F\"\ or\ \"f\"\ to\ hoist\ or\ lower\ the\ flag,\ which\ when\ up\ is\ another\nexperiment\ in\ random\ 3D\ movement\ (but\ grows\ ridiculously\ long\ after\nextended\ Monte\ Carlo\ walks\ in\ 3D\ space\ -\ click\ on\ it\ to\ restore\ original\ndimensions).\ '''Rotation'''\ of\ furniture\ can\ be\ tested\ with\ Alt-cursor\ keys,\n'''scaling'''\ with\ \"+\"\ and\ \"-\".\ Clicking\ on\ the\ swings\ makes\nit\ swing\ (test\ for\ excentric\ animated\ rotation).\ Likewise,\ move\ the\ door\nwith\ left\ or\ right\ click.\ Experiments\ with\ '''dimming\ colours'''\ are\nalso\ included\ -\ use\ \"d\"\ resp.\ \"D\"\ keys\ to\ try.\ If\ things\ get\ too\ dark,\nturn\ on\ the\ light\ with\ the\ switch\ next\ to\ the\ door.\n\nFor\ really\ good\ 3D\ rendering,\ points\ should\ be\ projected\ depending\ on\ the\nlocation\ of\ the\ \"observer\",\ a\ point\ in\ 3D\ space\ from\ which\ the\ objects\nare\ seen,\ and\ his\ \"point\ of\ view\"\ (which\ becomes\ the\ 2D\ origin),\ but\ I\nhad\ no\ appropriate\ math\ books\ handy\ -\ please\ edit\ this\ page\ if\ you\ know\nbetter!\ (But\ then,\ real\ hidden-line\ treatment\ also\ becomes\ inevitable...)\n\nLatest\ addition,\ not\ very\ finished\ yet:\ the\ little\ red\ toy\ cart\ is\nmovable,\ and\ when\ you\ drive\ it\ over\ an\ egg\ and\ click\ right\ on\ the\ egg,\nit\ is\ \"lifted\"\ into\ the\ cart\ and\ stays\ with\ it.\ Still\ pretty\ crude,\ but\na\ long\ Easter\ weekend\ is\ now\ over\ -\ and\ I'm\ not\ paid\ for\ Tk\ games\nprogramming...\ \n\nDISCLAIMER:\ This\ works\ well\ and\ fine\ on\ Linux,\ W95\ and\ W2K.\ On\ Solaris,\ via\ Reflection\ from\ a\ Windows\ box,\ Alt-Cursor\ keys\ don't\ get\ through.\ Also,\ had\ to\ add\ nonzero\ tests\ in\ \"3d'rotate\",\ \nas\ ''atan2''\ errors\ when\ called\ with\ 0.0,0.0\ (not\ so\ on\ Windows).\ \[RS\]\n\n\[Arjen\ Markus\]\ The\ problem\ with\ the\ Alt-key\ may\ be\ that\ Reflection\ has\ not\ been\ informed\ to\ pass\ the\ left\ or\ right\ Alt-key\ to\ X\ Window\ -\ this\ is\ part\ of\ the\ keyboard\ settings.\ \[RS\]:\ Yes,\ this\ did\ it\ -\ thanks!\n----\n''\[escargo\]\ 15\ Apr\ 2003''\ -\ Are\ we\ supposed\ to\ be\ able\ to\ prune\ the\ shrubs?\ \ (Clicking\ on\ some\nof\ the\ greenery\ makes\ it\ go\ away?\ \ Also,\ there\ are\ sometimes\ some\ z-order\ problems.\ \ I\ had\ some\ of\nthe\ shrubs\ get\ drawn\ on\ the\ wrong\ side\ of\ one\ of\ the\ chairs.\ \ Also,\ sometimes\ the\ table\ is\ visible\nthrough\ the\ walls\ of\ the\ house.\ \ (I\ really\ like\ the\ light\ switch!)\n----\n\nI\ Updated\ Merry\ to\ Happy\ in\ the\ window\ title.\ I've\ heard\ of\ Merry\ Christmas,\ but\ never\ Merry\ Easter.\ I\ guess\ Merry\ and\ Happy\ have\ similar\ meanings\ though.\n\n----\n======\n\ set\ ::tcl_precision\ 17\n\ proc\ deg2rad\ \{deg\}\ \{expr\ \{\$deg\ *\ atan(1)/45.\}\}\n\ trace\ var\ 3d(angle)\ w\ \"set\ 3d(th)\ \\\[deg2rad\ \\\$3d(angle)\]\;#\"\n\ array\ set\ 3d\ \{angle\ 30\ scale\ 100\ bright\ 1\ lastDim\ .25\ flat\ 0\}\n\ \n\ proc\ 3d\ \{type\ w\ points\ args\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ set\ cmd\ \[list\ \$w\ create\ \$type\]\n\ \ \ \ foreach\ point\ \$points\ \{eval\ lappend\ cmd\ \[3d'project\ \$point\]\}\n\ \ \ \ if\ \{\$type\ ==\ \"poly\"\ &&\ \[lsearch\ \$args\ -outline\]\ <\ 0\}\ \{\n\tlappend\ cmd\ -outline\ black\ \ \ \;#\ looks\ better...\n\ \ \ \ \}\n\ \ \ \ set\ cmd\ \[concat\ \$cmd\ \$args\]\n\ \ \ \ if\ \{\$3d(bright)\ !=\ 1\}\ \{\n\ \ \ \ \ \ \ foreach\ att\ \{-outline\ -fill\}\ \{\n\t\ \ if\ \{\[set\ pos\ \[lsearch\ \$cmd\ \$att\]\]\ >\ 0\}\ \{\n\t\ \ \ \ \ set\ f\ \[lindex\ \$cmd\ \[incr\ pos\]\]\n\t\ \ \ \ \ set\ cmd\ \[lreplace\ \$cmd\ \$pos\ \$pos\ \[dimColor\ \$f\ \$3d(bright)\]\]\n\t\ \ \}\n\ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ set\ 3d(\[eval\ \$cmd\])\ \[list\ \$type\ \$points\ \$args\]\ \ \ \ \ \ \ \;#\ backing\ store\n\ \}\n\ proc\ 3d'axes\ w\ \{\n\ \ \ \ foreach\ \{name\ from\ \ \ \ \ \ \ to\ \ \ \ \ \ \ color\}\ \{\n\t\ \ \ \ Xaxis\ \{-30\ 0\ 0\}\ \{30\ 0\ 0\}\ \ red\n\t\ \ \ \ X1\ \ \ \ \{1\ 0\ 0\}\ \ \ \{1\ .05\ 0\}\ red\n\t\ \ \ \ Yaxis\ \{0\ -30\ 0\}\ \{0\ 30\ 0\}\ \ green\n\t\ \ \ \ Y1\ \ \ \ \{0\ 1\ 0\}\ \ \ \{0\ 1\ .05\}\ green\n\t\ \ \ \ Zaxis\ \{0\ 0\ -30\}\ \{0\ 0\ 30\}\ \ blue\n\t\ \ \ \ Z1\ \ \ \ \{0\ 0\ 1\}\ \ \ \{.05\ 0\ 1\}\ blue\n\ \ \ \ \}\ \{3d\ line\ \$w\ \[list\ \$from\ \$to\]\ -fill\ \$color\ -tag\ axes\}\n\ \}\n\ proc\ 3d'project\ point\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ foreach\ \{x\ y\ z\}\ \$point\ break\n\ \ \ \ if\ \{\$z==\"\"\}\ \{set\ z\ 0\}\n\ \ \ \ set\ factor\ \$3d(scale)\n\ \ \ \ switch\ --\ \$3d(flat)\ \{\n\tx\ \{list\ \[expr\ \{\$y*\$factor\}\]\ \[expr\ \{-\$z*\$factor\}\]\ \;#\ side\ \ view\}\n\ty\ \{list\ \[expr\ \{\$x*\$factor\}\]\ \[expr\ \{-\$z*\$factor\}\]\ \;#\ front\ view\}\n\tz\ \{list\ \[expr\ \{\$x*\$factor\}\]\ \[expr\ \{-\$y*\$factor\}\]\ \;#\ top\ \ \ view\}\n\tdefault\ \{\n\t\ \ \ \ set\ rad\ \[expr\ \{\$y\ *\ abs(1-(\$3d(angle)/90.))\}\]\n\t\ \ \ \ if\ \{abs(\$y)<6\}\ \{set\ factor\ \[expr\ \{\$factor*(1-\$y/6.)\}\]\}\;#perspective\n\t\ \ \ \ set\ 2dx\ \[expr\ \{(\$x\ +\ \$rad*cos(\$3d(th)))\ *\ \ \$factor\}\]\n\t\ \ \ \ set\ 2dy\ \[expr\ \{(\$z\ +\ \$rad*sin(\$3d(th)))\ *\ -\$factor\}\]\;#+y\ goes\ down\n\t\ \ \ \ list\ \$2dx\ \$2dy\n\t\}\n\ \ \ \ \}\n\ \}\n\ proc\ 3d'redraw\ \{w\ \{tag\ all\}\ \{flat\ \"\"\}\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ if\ \{\$flat\ !=\ \"\"\}\ \{set\ 3d(flat)\ \$flat\}\n\ \ \ \ set\ 3d(angle)\ \[expr\ \{\$3d(angle)>180?\ 180:\ \$3d(angle)<0?\ 0:\ \$3d(angle)\}\]\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tforeach\ \{type\ points\ args\}\ \$::3d(\$item)\ break\n\tunset\ 3d(\$item)\n\t\$w\ delete\ \$item\n\teval\ \[list\ 3d\ \$type\ \$w\ \$points\]\ \$args\n\ \ \ \ \}\n\ \}\n\ proc\ 3d'move\ \{w\ tag\ vector\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tset\ newpoints\ \{\}\n\tforeach\ point\ \[lindex\ \$3d(\$item)\ 1\]\ \{\n\t\ \ \ \ \ lappend\ newpoints\ \[vector'add\ \$point\ \$vector\]\n\t\}\n\tset\ 3d(\$item)\ \[lreplace\ \$3d(\$item)\ 1\ 1\ \$newpoints\]\n\ \ \ \ \}\n\ \ \ \ 3d'redraw\ \$w\ \$tag\n\ \}\n\ proc\ 3d'scale\ \{w\ tag\ factors\ \{rpoint\ \{\}\}\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ if\ \{\$rpoint==\"\"\}\ \{set\ rpoint\ \[3d'center\ \$w\ \$tag\]\}\n\ \ \ \ foreach\ \{x0\ y0\ z0\}\ \$rpoint\ break\n\ \ \ \ foreach\ \{xf\ yf\ zf\}\ \$factors\ break\n\ \ \ \ if\ \{\$yf\ ==\ \"\"\}\ \{set\ yf\ \$xf\}\n\ \ \ \ if\ \{\$zf\ ==\ \"\"\}\ \{set\ zf\ \$yf\}\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tset\ newpoints\ \{\}\n\tforeach\ point\ \[lindex\ \$3d(\$item)\ 1\]\ \{\n\t\ \ \ \ foreach\ \{x\ y\ z\}\ \$point\ break\n\t\ \ \ \ if\ \{\$z\ ==\ \"\"\}\ \{set\ z\ 0\}\n\t\ \ \ \ set\ x1\ \[expr\ \{(\$x\ -\ \$x0)\ *\ \$xf\ +\ \$x0\}\]\n\t\ \ \ \ set\ y1\ \[expr\ \{(\$y\ -\ \$y0)\ *\ \$yf\ +\ \$y0\}\]\n\t\ \ \ \ set\ z1\ \[expr\ \{(\$z\ -\ \$z0)\ *\ \$zf\ +\ \$z0\}\]\n\t\ \ \ \ lappend\ newpoints\ \[list\ \$x1\ \$y1\ \$z1\]\n\t\}\n\tset\ 3d(\$item)\ \[lreplace\ \$3d(\$item)\ 1\ 1\ \$newpoints\]\n\ \ \ \ \}\n\ \ \ \ 3d'redraw\ \$w\ \$tag\n\ \}\n\ proc\ 3d'rotate\ \{w\ tag\ rvector\ \{rpoint\ \{\}\}\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ foreach\ \{rx\ ry\ rz\}\ \$rvector\ break\ \;#\ rotation\ angles\ in\ degrees\n\ \ \ \ foreach\ i\ \{x\ y\ z\}\ \{set\ rd\$i\ \[deg2rad\ \[set\ r\$i\]\]\}\n\ \ \ \ if\ \{\$rpoint\ ==\ \"\"\}\ \{set\ rpoint\ \[3d'center\ \$w\ \$tag\]\}\n\ \ \ \ foreach\ \{xc\ yc\ zc\}\ \$rpoint\ break\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tset\ newpoints\ \{\}\n\tforeach\ point\ \[lindex\ \$3d(\$item)\ 1\]\ \{\n\t\ \ \ \ foreach\ \{x\ y\ z\}\ \$point\ break\n\t\ \ \ \ if\ \{\$z\ ==\ \"\"\}\ \{set\ z\ 0\}\n\t\ \ \ \ set\ x1\ \[expr\ \{\$x-\$xc\}\]\n\t\ \ \ \ set\ y1\ \[expr\ \{\$y-\$yc\}\]\n\t\ \ \ \ set\ z1\ \[expr\ \{\$z-\$zc\}\]\n\t\ \ \ \ if\ \{\$rx\ !=\ 0\}\ \{\n\t\tif\ \{\[set\ rad\ \[expr\ \{hypot(\$y1,\$z1)\}\]\]\}\ \{\n\t\t\ \ set\ th\ \ \[expr\ \{atan2(\$z1,\$y1)\ -\ \$rdx\}\]\n\t\t\ \ set\ y\ \ \ \[expr\ \{\$yc\ +\ \$rad\ *\ cos(\$th)\}\]\n\t\t\ \ set\ z\ \ \ \[expr\ \{\$zc\ +\ \$rad\ *\ sin(\$th)\}\]\n\t\t\}\ \;#\ tests\ for\ nonzero\ rad\ necessary\ on\ Unix\n\t\ \ \ \ \}\n\t\ \ \ \ if\ \{\$ry\ !=\ 0\}\ \{\n\t\tif\ \{\[set\ rad\ \[expr\ \{hypot(\$x1,\$z1)\}\]\]\}\ \{\n\t\t\ \ set\ th\ \ \[expr\ \{atan2(\$z1,\$x1)\ -\ \$rdy\}\]\n\t\t\ \ set\ x\ \ \ \[expr\ \{\$xc\ +\ \$rad\ *\ cos(\$th)\}\]\n\t\t\ \ set\ z\ \ \ \[expr\ \{\$zc\ +\ \$rad\ *\ sin(\$th)\}\]\n\t\t\}\n\t\ \ \ \ \}\n\t\ \ \ \ if\ \{\$rz\ !=\ 0\}\ \{\n\t\tif\ \{\[set\ rad\ \[expr\ \{hypot(\$x1,\$y1)\}\]\]\}\ \{\n\t\t\ \ \ set\ th\ \ \[expr\ \{atan2(\$y1,\$x1)\ -\ \$rdz\}\]\n\t\t\ \ \ set\ x\ \ \ \[expr\ \{\$xc\ +\ \$rad\ *\ cos(\$th)\}\]\n\t\t\ \ \ set\ y\ \ \ \[expr\ \{\$yc\ +\ \$rad\ *\ sin(\$th)\}\]\n\t\t\}\n\t\ \ \ \ \}\n\t\ \ \ \ lappend\ newpoints\ \[list\ \$x\ \$y\ \$z\]\n\t\}\n\tset\ 3d(\$item)\ \[lreplace\ \$3d(\$item)\ 1\ 1\ \$newpoints\]\n\ \ \ \ \}\n\ \ \ \ 3d'redraw\ \$w\ \$tag\n\ \}\n\ proc\ 3d'bcube\ \{w\ tag\}\ \{\n\ \ \ \ #--\ compute\ \"bounding\ cube\"\ (minx\ maxx\ miny\ maxy\ minz\ maxz)\n\ \ \ \ variable\ 3d\n\ \ \ \ set\ xs\ \{\}\;\ set\ ys\ \{\}\;\ set\ zs\ \{\}\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tforeach\ point\ \[lindex\ \$3d(\$item)\ 1\]\ \{\n\t\ \ \ \ foreach\ \{x\ y\ z\}\ \$point\ break\n\t\ \ \ \ lappend\ xs\ \$x\n\t\ \ \ \ lappend\ ys\ \$y\n\t\ \ \ \ lappend\ zs\ \$z\n\t\}\n\ \ \ \ \}\n\ \ \ \ concat\ \[minmax\ \$xs\]\ \[minmax\ \$ys\]\ \[minmax\ \$zs\]\n\ \}\n\ proc\ 3d'center\ \{w\ tag\}\ \{\n\ \ \ \ foreach\ \{x\ x1\ y\ y1\ z\ z1\}\ \[3d'bcube\ \$w\ \$tag\]\ break\n\ \ \ \ list\ \[expr\ \{(\$x+\$x1)/2.\}\]\ \[expr\ \{(\$y+\$y1)/2.\}\]\ \[expr\ \{(\$z+\$z1)/2.\}\]\n\ \}\n\ proc\ 3d'addtag\ \{w\ item\ tag\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ set\ args\ \[lindex\ \$3d(\$item)\ 2\]\n\ \ \ \ set\ found\ 0\;\ set\ newargs\ \{\}\n\ \ \ \ foreach\ \{att\ val\}\ \$args\ \{\n\tif\ \{\$att\ ==\ \"-tag\"\}\ \{lappend\ val\ \$tag\;\ incr\ found\}\n\tlappend\ newargs\ \$att\ \$val\n\ \ \ \ \}\n\ \ \ \ if\ \{!\$found\}\ \{lappend\ newargs\ -tag\ \$tag\}\n\ \ \ \ set\ 3d(\$item)\ \[lreplace\ \$3d(\$item)\ 2\ 2\ \$newargs\]\n\ \}\n\ proc\ dim\ \{w\ factor\ \{tag\ all\}\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ if\ \{\$factor\ ==\ 0\}\ \{\n\tset\ factor\ \[expr\ \{1./\$3d(lastDim)\}\]\n\tset\ 3d(lastDim)\ \$factor\ \;#\ allow\ toggle\ for\ light\ switch\n\ \ \ \ \}\ else\ \{set\ 3d(bright)\ \[expr\ \{\$3d(bright)*\$factor\}\]\}\n\ \ \ \ if\ \{\$tag\ ==\ \"all\"\}\ \{\n\t\$w\ config\ -bg\ \[dimColor\ \[\$w\ cget\ -bg\]\ \$factor\]\n\ \ \ \ \}\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tforeach\ att\ \{-fill\ -outline\}\ \{\n\t\ \ \ \ if\ \{!\[catch\ \{\$w\ itemcget\ \$item\ \$att\}\ f\]\}\ \{\n\t\t\$w\ itemconf\ \$item\ \$att\ \[dimColor\ \$f\ \$factor\]\n\t\ \ \ \ \}\n\t\}\n\ \ \ \ \}\n\ \}\n\ proc\ dimColor\ \{color\ factor\}\ \{\n\ \ \ \ if\ \{\$color\ ==\ \"\"\}\ \{return\ \"\"\}\n\ \ \ \ foreach\ \{r\ g\ b\}\ \[winfo\ rgb\ .\ \$color\]\ break\n\ \ \ \ set\ res\ \"#\"\n\ \ \ \ foreach\ i\ \{r\ g\ b\}\ \{\n\tset\ col\ \[expr\ \{round(\[set\ \$i\]*\$factor)\}\]\n\tif\ \{\$col\ >\ 0xFFFF\}\ \{set\ col\ 0xFFFF\}\n\tappend\ res\ \[format\ %4.4x\ \$col\]\n\ \ \ \ \}\n\ \ \ \ set\ res\n\ \}\n\ proc\ minmax\ L\ \{\n\ \ \ \ set\ sorted\ \[lsort\ -real\ \$L\]\n\ \ \ \ list\ \[lindex\ \$sorted\ 0\]\ \[lindex\ \$sorted\ end\]\n\ \}\n\ proc\ vector'add\ \{v1\ v2\}\ \{\n\ \ \ \ set\ res\ \{\}\n\ \ \ \ foreach\ i\ \$v1\ j\ \$v2\ \{\n\tif\ \{\$i\ ==\ \"\"\}\ \{set\ i\ 0\}\n\tif\ \{\$j\ ==\ \"\"\}\ \{set\ j\ 0\}\n\tlappend\ res\ \[expr\ \{\$i\ +\ \$j\}\]\n\ \ \ \ \}\n\ \ \ \ set\ res\n\ \}\n======\n======\n\ #--------------------------------\ A\ mighty\ elaborate\ and\ playful\ demo:\n======\n\ if\ \{\[file\ tail\ \[info\ script\]\]\ ==\ \[file\ tail\ \$argv0\]\}\ \{\n======\n======\n\ \ \ \ proc\ plant\ \{c\ x\ y\ \{diameter\ 0.6\}\ \{branches\ 8\}\}\ \{\n\tset\ root\ \[list\ \$x\ \$y\ 0\]\n\tfor\ \{set\ i\ 0\}\ \{\$i<\$branches\}\ \{incr\ i\}\ \{\n\t\ \ \ \ set\ x1\ \[expr\ \{\$x\ +\ rand()*\$diameter\ -\ \$diameter/2\}\]\n\t\ \ \ \ set\ y1\ \[expr\ \{\$y\ +\ rand()*\$diameter\ -\ \$diameter/2\}\]\n\t\ \ \ \ set\ z\ \ \[expr\ \{rand()*0.25\ +\ \$diameter\}\]\n\t\ \ \ \ set\ width\ \[expr\ \{round(\$diameter*6)\}\]\n\t\ \ \ \ 3d\ line\ \$c\ \[list\ \$root\ \[list\ \$x1\ \$y1\ \$z\]\]\ -width\ \$width\\\n\t\ \ \ \ -fill\ \[lpick\ \{DarkGreen\ green4\ ForestGreen\ SeaGreen\ YellowGreen\}\]\\\n\t\ \ \ \ -tag\ plant\n\t\}\n\ \ \ \ \}\n\ \ \ \ proc\ chair\ \{c\ x\ y\ \{colors\ \{white\ blue\}\}\}\ \{\n\tset\ h1\ 0.12\n\tset\ h2\ 0.2\n\tset\ h3\ 0.3\n\tset\ y1\ 0.25\;\ set\ y2\ 0.26\n\tset\ tag\ chair\[incr\ ::chairID\]\n\tset\ tag2\ \[list\ \$tag\ mv\]\n\tforeach\ \{c1\ c2\}\ \$colors\ break\n\t3d\ line\ \$c\ \"\{0\ \$y2\}\ \{.05\ \$y2\ \$h2\}\ \{.25\ \$y2\ \$h2\}\ \{.3\ \$y2\}\"\ -fill\ \$c1\\\n\t\ \ \ \ -width\ 2\ -tag\ \$tag2\n\t3d\ poly\ \$c\ \"\{.05\ 0\ \$h1\}\ \{.05\ \$y1\ \$h1\}\ \{.3\ \$y1\ \$h1\}\ \{.3\ 0\ \$h1\}\"\ \\\n\t\ \ \ \ -fill\ \$c2\ -tag\ \$tag2\ -width\ 2\n\t3d\ poly\ \$c\ \"\{.05\ 0\ \$h1\}\ \{0\ 0\ \$h3\}\ \{0\ \$y1\ \$h3\}\ \{.05\ \$y1\ \$h1\}\"\ \\\n\t\ \ \ \ -fill\ \$c2\ -tag\ \$tag2\ -width\ 2\n\t3d\ line\ \$c\ \"\{0\ 0\}\ \{.05\ 0\ \$h2\}\ \{.25\ 0\ \$h2\}\ \{.3\ 0\}\"\ -fill\ \$c1\ \\\n\t\ \ \ \ -width\ 2\ -tag\ \$tag2\n\t3d'move\ \$c\ \$tag\ \[list\ \$x\ \$y\ 0\]\n\tset\ tag\n\ \ \ \ \}\n\ \ \ \ set\ chairID\ 0\n\ \ \ \ proc\ every\ \{ms\ body\}\ \{eval\ \$body\;\ after\ \$ms\ \[info\ level\ 0\]\}\n\ \ \ \ proc\ lpick\ L\ \{lindex\ \$L\ \[expr\ \{int(rand()\ *\ \[llength\ \$L\])\}\]\}\n\ \ \ \ proc\ moveFlag\ \{w\}\ \{\n\tvariable\ 3d\n\tforeach\ i\ \[\$w\ find\ withtag\ =flag\]\ \{\n\t\ \ \ \ set\ points\ \[lindex\ \$3d(\$i)\ 1\]\n\t\ \ \ \ if\ \{\[lindex\ \[lindex\ \$points\ 0\]\ 2\]\ >\ 1.5\}\ \{\n\t\tset\ randv\ \{\}\n\t\tforeach\ _\ \{x\ y\ z\}\ \{\n\t\t\ \ \ \ lappend\ randv\ \[expr\ \{rand()*0.05-0.025\}\]\n\t\t\}\n\t\tset\ p1\ \[vector'add\ \[lindex\ \$points\ 1\]\ \$randv\]\n\t\tset\ p2\ \[vector'add\ \[lindex\ \$points\ 2\]\ \$randv\]\n\t\tset\ points\ \[lreplace\ \$points\ 1\ 2\ \$p1\ \$p2\]\n\t\tset\ 3d(\$i)\ \[lreplace\ \$3d(\$i)\ 1\ 1\ \$points\]\n\t\ \ \ \ \}\n\t\}\n\t3d'redraw\ \$w\ \ =flag\n\t\$w\ lower\ \ \ \ \ \ =flag\ backWall\n\ \ \ \ \}\n\ \ \ \ proc\ placeEggs\ w\ \{\n\ \ \ \ \ \ foreach\ color\ \{\n\tred\ green\ blue\ cyan\ magenta\ yellow\ orange\ pink\ purple\ brown\n\ \ \ \ \ \ \}\ \{\n\t\ set\ x\ \[expr\ \{rand()\ *\ 5.4\ -\ 1.9\}\]\n\t\ set\ y\ \[expr\ \{rand()\ *\ 4\ -\ 2\}\]\n\t\ 3d\ oval\ \$w\ \"\{\$x\ \$y\ .04\}\ \{\[expr\ \$x+.1\]\ \[expr\ \$y+.04\]\ -.04\}\"\\\n\t\ \ \ \ \ -fill\ \$color\ -tag\ egg\n\ \ \ \ \ \ \}\n\ \ \ \ \ \ \$w\ lower\ egg\ frontWall\n\ \ \ \ \ \ wm\ title\ .\ \"Happy\ 3D\ Easter!\"\n\ \ \ \ \ \ \$w\ bind\ egg\ <1>\ \{\n\t\ \ %W\ delete\ current\n\t\ \ wm\ title\ .\ \"\[wm\ title\ .\]\ 0\"\ \;#\ append\ found\ eggs\ to\ title\n\t\ \ if\ \{\[%W\ find\ withtag\ egg\]\ ==\ \"\"\}\ \{\n\t\ \ \ \ \ \ tk_messageBox\ -message\ Super!\n\t\ \ \ \ \ \ placeEggs\ %W\n\t\ \ \}\n\ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ proc\ swings\ \{w\ x0\ y0\}\ \{\n\tset\ x1\ \[expr\ \{\$x0\ +\ 0.8\}\]\n\tset\ xm\ \[expr\ \{(\$x0\ +\ \$x1)/2\}\]\n\tset\ x2\ \[expr\ \{\$xm\ -\ 0.05\}\]\n\tset\ x3\ \[expr\ \{\$xm\ +\ 0.05\}\]\n\tset\ y1\ \[expr\ \{\$y0\ +\ 0.7\}\]\n\tset\ y2\ \[expr\ \{\$y0\ +\ 0.3\}\]\ \;#\ rope\ 1\n\tset\ y3\ \[expr\ \{\$y0\ +\ 0.5\}\]\ \;#\ rope\ 2\n\tset\ h\ 0.8\ \ \ \ \;#\ top\ crossbar\n\tset\ s\ 0.14\ \ \ \;#\ height\ of\ swing\ seat\n\tset\ col\ turquoise4\n\t3d\ line\ \$w\ \"\{\$x0\ \$y1\}\ \{\$xm\ \$y1\ \$h\}\ \{\$x1\ \$y1\}\"\ -width\ 2\ -fill\ \$col\n\t3d\ line\ \$w\ \"\{\$xm\ \$y0\ \$h\}\ \{\$xm\ \$y1\ \$h\}\"\ -width\ 2\ -fill\ \$col\n\t3d\ line\ \$w\ \"\{\$xm\ \$y3\ \$h\}\ \{\$xm\ \$y3\ \$s\}\"\ -tag\ swingm\n\t3d\ poly\ \$w\ \"\{\$x2\ \$y2\ \$s\}\ \{\$x3\ \$y2\ \$s\}\ \{\$x3\ \$y3\ \$s\}\ \{\$x2\ \$y3\ \$s\}\"\\\n\t\ \ \ \ -fill\ orange\ -tag\ swingm\n\t3d\ line\ \$w\ \"\{\$xm\ \$y2\ \$h\}\ \{\$xm\ \$y2\ \$s\}\"\ -tag\ swingm\n\t3d\ line\ \$w\ \"\{\$x0\ \$y0\}\ \{\$xm\ \$y0\ \$h\}\ \{\$x1\ \$y0\}\"\ -width\ 2\ -fill\ \$col\\\n\t\ \ \ \ -tag\ swingfg\n\tset\ swingpoint\ \[list\ \$xm\ \$y2\ \$h\]\n\t\$w\ bind\ swingm\ <1>\ \[list\ swing'move\ %W\ swingm\ \$swingpoint\ 20\]\n\ \ \ \ \}\n\ \ \ \ proc\ swing'move\ \{w\ tag\ rpoint\ angle\}\ \{\n\t\$w\ raise\ swingfg\n\tif\ \{\$angle<=0\}\ return\n\t3d'rotate\ \$w\ \$tag\ \[list\ 0\ \$angle\ 0\]\ \$rpoint\n\tset\ angle2\ \[expr\ \{\$angle*-2\}\]\n\tafter\ 250\ \[list\ 3d'rotate\ \$w\ \$tag\ \[list\ 0\ \$angle2\ 0\]\ \$rpoint\]\n\tafter\ 500\ \[list\ 3d'rotate\ \$w\ \$tag\ \[list\ 0\ \$angle\ 0\]\ \$rpoint\]\n\tafter\ 500\ \[list\ swing'move\ \$w\ \$tag\ \$rpoint\ \[incr\ angle\ -1\]\]\n\ \ \ \ \}\n\ \ \ \ proc\ toycart\ \{w\ x\ y\ \{color\ red\}\}\ \{\n\t3d\ oval\ \$w\ \{\{.01\ .18\ .1\}\ \ \{.09\ .2\ 0\}\}\ -fill\ black\ -tags\ \{cart\ mv\}\n\t3d\ oval\ \$w\ \{\{.19\ .18\ .1\}\ \ \{.27\ .2\ 0\}\}\ -fill\ black\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.01\ .01\ .1\}\ \{.01\ .19\ .1\}\ \{.29\ .19\ .1\}\ \{.29\ .01\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.01\ .19\ .1\}\ \{0\ .2\ .15\}\ \{.3\ .2\ .15\}\ \{.29\ .19\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.01\ .01\ .1\}\ \{0\ 0\ .15\}\ \{0\ .2\ .15\}\ \{.01\ .19\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.29\ .01\ .1\}\ \{.3\ 0\ .15\}\ \{.3\ .2\ .15\}\ \{.29\ .19\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.01\ .01\ .1\}\ \{0\ 0\ .15\}\ \{.3\ 0\ .15\}\ \{.29\ .01\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\ front\}\n\t3d\ line\ \$w\ \{\{.3\ .1\ .1\}\ \ \{.55\ .1\ 0\}\}\ -width\ 2\ \\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ line\ \$w\ \{\{.55\ .07\ 0\}\ \{.55\ .13\ 0\}\}\ -width\ 2\ \\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ oval\ \$w\ \{\{.01\ .02\ .1\}\ \ \{.09\ 0\ 0\}\}\ -fill\ black\ -tags\ \{cart\ mv\}\n\t3d\ oval\ \$w\ \{\{.19\ .02\ .1\}\ \ \{.27\ 0\ 0\}\}\ -fill\ black\ -tags\ \{cart\ mv\}\n\t3d'move\ \$w\ cart\ \[list\ \$x\ \$y\]\ \;#\ bring\ to\ target\ position\n\t\$w\ bind\ egg\ <3>\ \{\n\t\ \ \ \ set\ item\ \[%W\ find\ withtag\ current\]\n\t\ \ \ \ 3d'addtag\ %W\ \$item\ cart\ \ \ \ \ \ \;#\ let\ it\ move\ with\ the\ cart...\n\t\ \ \ \ 3d'move\ \ \ %W\ \$item\ \{0\ 0\ .11\}\ \;#\ ...and\ raise\ it\ on\ board\n\t\ \ \ \ %W\ raise\ front\ egg\n\t\}\n\treturn\ cart\n\ \ \ \ \}\n\ \ \ \ #----------------------------------\ let's\ build\ up\ the\ scene...\n\ \ \ \ set\ c\ \[canvas\ .c\ -width\ 600\ -height\ 400\ \\\n\t-scrollregion\ \{-250\ -300\ 350\ 100\}\ -bg\ steelblue1\]\n\ \ \ \ pack\ \$c\ \ -fill\ both\ -expand\ 1\n\ \ \ \ 3d'axes\ \$c\n\ \ \ \ 3d\ poly\ \$c\ \{\{-4\ -3\}\ \{6\ -3\}\ \{6\ -3\ -2\}\ \{-4\ -3\ -2\}\}\ -fill\ brown\ \ \ \ \;#\ earth\n\ \ \ \ 3d\ poly\ \$c\ \{\{-4\ -3\}\ \{6\ -3\}\ \{6\ 2\}\ \{-4\ 2\}\}\ -fill\ green3\t\ \ \ \ \;#\ lawn\n\ \ \ \ 3d\ poly\ \$c\ \{\{-4\ 2\}\ \{.3\ 2\}\ \{.3\ 2\ .4\}\ \{-4\ 2\ .4\}\}\ -fill\ DarkOrange2\;#\ fence\n\ \ \ \ 3d\ poly\ \$c\ \{\{.7\ 2\}\ \{6\ 2\}\ \{6\ 2\ .4\}\ \{.7\ 2\ .4\}\}\ -fill\ DarkOrange2\ \ \;#\ fence\n\ \ \ \ 3d\ poly\ \$c\ \{\{.3\ .1\}\ \{1.7\ .1\}\ \{1.7\ -.7\}\ \{.3\ -.7\}\}\ -fill\ gray\ \ \ \ \;#terrace\n\ \ \ \ plant\ \$c\ 1\ 1.9\n\ \ \ \ 3d\ line\ \$c\ \{\{.5\ 1.8\}\ \{.5\ 1.8\ 2.85\}\}\ -fill\ white\ -width\ 3\ \ \ \ \ \;#\ flagpole\n\ \ \ \ set\ flagCoords\ \{\{.5\ 1.8\ 2.5\}\ \{.62\ 2\ 2.5\}\ \{.62\ 2\ 2.8\}\ \{.5\ 1.8\ 2.8\}\}\n\ \ \ \ 3d\ poly\ \$c\ \$flagCoords\ -fill\ blue\ -tags\ =flag\t\t\ \ \ \ \;#\ flag\n\ \ \ \ \$c\ bind\ =flag\ <1>\ \{\n\ \ \ \ \ \ \$c\ delete\ =flag\;\ 3d\ poly\ \$c\ \$flagCoords\ -fill\ blue\ -tags\ =flag\n\ \ \ \ \}\n\ \ \ \ 3d\ poly\ \$c\ \{\{0\ .1\}\ \{0\ 1\}\ \{2\ 1\}\ \{2\ .1\}\}\ -fill\ orange\ -tag\ in\ \ \ \ \ \ \;#floor\n\ \ \ \ 3d\ oval\ \$c\ \{\{.3\ .3\}\ \{1.8\ .8\}\}\ -fill\ purple\ -tag\ in\t\ \ \ \ \ \;#\ carpet\n\ \ \ \ plant\ \$c\ \ -1.3\ \ 1.8\ 0.5\n\ \ \ \ plant\ \$c\ \ \ 3\ \ \ \ 1.8\ 0.6\n\ \ \ \ swings\ \$c\ -1.6\ -0.3\n\ \ \ \ 3d\ oval\ \$c\ \{\{-3.2\ -2.7\}\ \{-1.5\ -1\}\}\ \ \ -fill\ beige\t\t\ \;#\ pool\n\ \ \ \ 3d\ oval\ \$c\ \{\{-3.1\ -2.6\}\ \{-1.6\ -1.1\}\}\ -fill\ DeepSkyBlue3\ \;#\ water\ in\ pool\n\ \ \ \ placeEggs\ \$c\n\ \ \ \ 3d\ poly\ \$c\ \{\{.2\ 1\}\ \{.36\ 1.3\}\ \{.36\ 1.3\ .8\}\ \{.2\ 1\ .8\}\}\ \\\n\ \ \ \ -fill\ brown\ -tag\ \{=door\ in\}\t\t\t\t\ \ \ \ \ \ \;#\ door\n\ \ \ \ 3d\ oval\ \$c\ \{\{.34\ 1.25\ .29\}\ \{.37\ 1.29\ .32\}\}\ -fill\ yellow\ \\\n\ \ \ \ -outline\ orange\ -tag\ \{=door\ in\}\t\t\t\t\ \ \ \;#knob\n\ \ \ \ \$c\ bind\ =door\ <1>\ \{\n\t3d'rotate\ %W\ =door\ \{0\ 0\ -15\}\ \{.2\ 1\ .4\}\;\ %W\ lower\ =door\ backWall\}\n\ \ \ \ \$c\ bind\ =door\ <3>\ \{\n\t3d'rotate\ %W\ =door\ \{0\ 0\ 15\}\ \{.2\ 1\ .4\}\;\ %W\ lower\ =door\ backWall\}\n\ \ \ \ 3d\ poly\ \$c\ \{\{0\ 1\}\ \{.2\ 1\}\ \{.2\ 1\ .7\}\ \{.54\ 1\ .7\}\ \{.54\ 1\}\n\t\ \{1.3\ 1\}\ \{1.3\ 1\ .3\}\ \{.8\ 1\ .3\}\ \{.8\ 1\ .7\}\ \{1.3\ 1\ .7\}\n\t\{1.3\ 1\}\ \{2\ 1\}\ \{2\ 1\ 1\}\ \{0\ 1\ 1\}\}\ -fill\ bisque\ -outline\ bisque\ \\\n\t\ \ \ \ -tag\ \{backWall\ in\}\t\t\t\t\ \ \;#\ back\ wall\ \n\ \ \ \ 3d\ poly\ \$c\ \{\{.57\ 1\ .4\}\ \{.65\ 1\ .4\}\ \{.65\ 1\ .48\}\ \{.57\ 1\ .48\}\}\ \\\n\t-fill\ white\ -tag\ \{=lightSwitch\ in\}\t\t\ \ \ \;#\ light\ switch\n\ \ \ \ \$c\ bind\ =lightSwitch\ <1>\ \{dim\ %W\ 0\ in\}\n\ \ \ \ 3d\ line\ \$c\ \{\{1\ 1\ .3\}\ \{1\ 1\ .7\}\}\ -fill\ white\ -width\ 2\ -tag\ in\;#\ window\ bar\n\t3d\ poly\ \$c\ \{\{-.05\ 1.05\ 1\}\ \{-.05\ .5\ 1.5\}\ \{2.05\ .5\ 1.5\}\ \{2.05\ 1.05\ 1\}\}\\\n\t\ -fill\ red\t\t\t\t\t\ \ \ \ \;#\ (back)\ roof\n\ \ \ \ 3d\ poly\ \$c\ \{\{0\ .1\}\ \{0\ 1\}\ \{0\ 1\ 1\}\ \{0\ .5\ 1.5\}\ \{0\ .1\ 1\}\}\ \\\n\t-fill\ beige\t\t\t\t\t\;#\ left\ side\ wall\n\ \ \ \ foreach\ \{x\ y\}\ \{.51\ .31\ \ .51\ .49\ \ .79\ .49\ \ .79\ .31\}\ \{\n\t3d\ line\ \$c\ \[list\ \[list\ \$x\ \$y\ 0\]\ \[list\ \$x\ \$y\ .3\]\]\ \\\n\t\ \ \ \ -fill\ black\ -width\ 3\ -tag\ \{=table\ mv\}\}\t\ \ \ \ \ \;#\ table\ legs\n\ \ \ \ 3d\ poly\ \$c\ \{\{.5\ .3\ .3\}\ \{.5\ .5\ .3\}\ \{.8\ .5\ .3\}\ \{.8\ .3\ .3\}\}\ \\\n\t-fill\ lightblue\ -tag\ \{=table\ mv\ in\}\t\t\ \ \ \;#\ table\ plate\n\ \ \ \ 3d\ poly\ \$c\ \{\{2\ .1\}\ \{2\ 1\}\ \{2\ 1\ 1\}\ \{2\ .5\ 1.5\}\ \{2\ .1\ 1\}\}\ -fill\ pink\ \ \;#wall\n\ \ \ \ 3d\ poly\ \$c\ \{\{0\ .1\}\ \{.3\ .1\}\ \{.3\ .1\ .8\}\ \{1.7\ .1\ .8\}\ \{1.7\ .1\ .3\}\n\ \ \ \ \{1\ .1\ .3\}\ \{1\ .1\ .8\}\ \{.9\ .1\ .8\}\ \{.9\ .1\}\ \{2\ .1\}\ \{2\ .1\ 1\}\ \{0\ .1\ 1\}\}\ \\\n\t-fill\ LightYellow\ -outline\ LightYellow\ -tag\ frontWall\ \ \;#\ front\ wall\n\ \ \ \ 3d\ poly\ \$c\ \{\{.99\ .1\ .29\}\ \{1.7\ .1\ .29\}\ \{1.7\ .1\ .81\}\ \{.99\ .1\ .81\}\}\\\n\t-fill\ \{\}\ -width\ 2\ -outline\ NavyBlue\t\t\ \ \ \;#window\ frame\n\ \ \ \ 3d\ poly\ \$c\ \{\{-.05\ .05\ 1\}\ \{-.05\ .5\ 1.5\}\ \{2.05\ .5\ 1.5\}\ \{2.05\ .05\ 1\}\}\\\n\t\ -fill\ red\t\t\t\t\t\ \ \ \;#\ (front)\ roof\n\ \ \ \ chair\ \ \ \$c\ -0.5\ -1.8\n\ \ \ \ toycart\ \$c\ \ 2\ \ \ -2\n\ \ \ \ 3d'rotate\ \$c\ \[chair\ \$c\ 0\ -2.5\]\ \{0\ 0\ -60\}\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i<10\}\ \{incr\ i\}\ \{\n\tplant\ \$c\ \[expr\ \{5-rand()*6\}\]\ \[expr\ \{-3+rand()*2.3\}\]\ 0.2\ 5\n\ \ \ \ \}\n\ \ \ \ plant\ \$c\ -2.5\ -.8\ .7\n\ \ \ \ plant\ \$c\ \ 2.8\ -.8\ .5\n\ \ \ \ #---------------------------------------------------------\ Bindings\n\ \ \ \ bind\ .\ <Left>\ \ \{incr\ 3d(angle)\ \ 5\;\ 3d'redraw\ .c\ all\ 3d\}\n\ \ \ \ bind\ .\ <Right>\ \{incr\ 3d(angle)\ -5\;\ 3d'redraw\ .c\ all\ 3d\}\n\ \ \ \ bind\ .\ <Up>\ \ \ \ \{set\ 3d(scale)\ \[expr\ \{\$3d(scale)*1.25\}\]\;\ 3d'redraw\ .c\}\n\ \ \ \ bind\ .\ <Down>\ \ \{set\ 3d(scale)\ \[expr\ \{\$3d(scale)/1.25\}\]\;\ 3d'redraw\ .c\}\n\ \ \ \ #--\ test\ transformations\ with\ current\ \"mv\"\ (movable)\ object\n\ \ \ \ set\ mv\ =table\ \;#\ initially:\ table\ (best\ move\ it\ out\ of\ house\ first)\n\ \ \ \ bind\ .\ <Shift-Left>\ \ \{3d'move\ \ \ \$c\ \$mv\ \{-.1\ 0\ 0\}\}\n\ \ \ \ bind\ .\ <Shift-Right>\ \{3d'move\ \ \ \$c\ \$mv\ \{.1\ \ 0\ 0\}\}\n\ \ \ \ bind\ .\ <Shift-Up>\ \ \ \ \{3d'move\ \ \ \$c\ \$mv\ \{0\ \ .1\ 0\}\}\n\ \ \ \ bind\ .\ <Shift-Down>\ \ \{3d'move\ \ \ \$c\ \$mv\ \{0\ -.1\ 0\}\}\n\ \ \ \ bind\ .\ <Alt-Left>\ \ \ \ \{3d'rotate\ \$c\ \$mv\ \{0\ \ 0\ \ 5\}\}\n\ \ \ \ bind\ .\ <Alt-Right>\ \ \ \{3d'rotate\ \$c\ \$mv\ \{0\ \ 0\ -5\}\}\n\ \ \ \ bind\ .\ <Alt-Up>\ \ \ \ \ \ \{3d'rotate\ \$c\ \$mv\ \{0\ \ 5\ \ 0\}\}\n\ \ \ \ bind\ .\ <Alt-Down>\ \ \ \ \{3d'rotate\ \$c\ \$mv\ \{0\ -5\ \ 0\}\}\n\ \ \ \ bind\ .\ +\t\ \ \ \ \ \{3d'scale\ \ \$c\ \$mv\ 1.25\}\t\ \ \ \ \ \ \ \;#\ grow\n\ \ \ \ bind\ .\ -\t\ \ \ \ \ \{3d'scale\ \ \$c\ \$mv\ 0.8\}\t\ \ \ \ \ \ \;#\ shrink\n\ \ \ \ \$c\ bind\ mv\ <1>\ \{\n\tset\ mv\ \[lindex\ \[%W\ gettags\ current\]\ 0\]\n\t3d'move\ %W\ \$mv\ \{-.01\ -.01\ -.01\}\ \ \ \ \ \ \ \;#\ visual\ feedback\ in\ 3D\n\tafter\ 100\ \[list\ 3d'move\ %W\ \$mv\ \{.01\ .01\ .01\}\]\n\ \ \ \ \}\n\ \ \ \ \$c\ bind\ plant\ <1>\ \{%W\ delete\ current\}\t\ \ \ \;#\ for\ \"gardening\"\n\ \ \ \ bind\ .\ x\ \{3d'redraw\ \$c\ all\ x\}\t\ \ \ \;#\ side\ view,\ along\ x\ axis\n\ \ \ \ bind\ .\ y\ \{3d'redraw\ \$c\ all\ y\}\t\ \ \;#\ front\ view,\ along\ y\ axis\n\ \ \ \ bind\ .\ z\ \{3d'redraw\ \$c\ all\ z\}\t\ \ \ \ \;#\ top\ view,\ along\ z\ axis\n\ \ \ \ bind\ .\ 3\ \{3d'redraw\ \$c\ all\ 3d\}\t\ \ \ \;#\ \ \ \ \ \ perspectivic\ view\n\ \ \ \ bind\ .\ F\ \[list\ 3d'move\ \$c\ =flag\ \ \{0\ 0\ \ .1\}\]\t\ \ \;#\ hoist\ flag\n\ \ \ \ bind\ .\ f\ \[list\ 3d'move\ \$c\ =flag\ \ \{0\ 0\ -.1\}\]\t\ \ \;#\ lower\ flag\n\ \ \ \ bind\ .\ d\ \{dim\ .c\ .8\}\t\t\t\;#\ decrease\ brightness\n\ \ \ \ bind\ .\ D\ \{dim\ .c\ 1.25\}\t\t\ \ \ \ \ \ \;#\ increase\ brightness\n\ \ \ \ bind\ .\ <Escape>\ \{exec\ wish\ \$argv0\ &\;\ exit\}\t\ \ \ \ \ \ \;#\ restart\n\ \ \ \ bind\ .\ ?\ \{console\ show\}\t\t\t\ \ \ \;#\ for\ debugging\n\n\ \ \ \ #--------------------------------------------\ Initial\ animation...\n\ \ \ \ set\ 3d(scale)\ 0.2\t\ \ \ \ \ \ \ \;#\ start\ with\ a\ view\ from\ far\ away\n\ \ \ \ 3d'redraw\ .c\n\ \ \ \ raise\ .\;\ update\t\t\t\ \ \ \ \;#\ necessary\ on\ Windows\n\ \ \ \ while\ \{\$3d(scale)<80\}\ \{event\ generate\ .\ <Up>\;\ update\}\n\ \ \ \ every\ 250\ \{moveFlag\ \ .c\}\ \ \ \ \ \;#\ so\ there's\ always\ something\ moving\n======\n======\n\ \}\n======\n----\n\[Tk\]\ -\ \[Category\ 3D\ Graphics\]\ -\ \ \[Arts\ and\ crafts\ of\ Tcl-Tk\ programming\] regexp2} CALL {my render {Playing 3D} ----\n\[WikiDbImage\ 3d.gif\]\n\n\[Richard\ Suchenwirth\]\ 2002-04-02\ -\ In\ this\ Easter\ fun\ project,\ I\ experimented\ with\nrendering\ three-dimensional\ objects\ on\ a\ two-dimensional\ \[canvas\].\ Points\nin\ 3D\ space\ are\ specified\ by\ x,\ y,\ and\ z\ coordinates\ (if\ only\ two\ are\ given,\nz\ defaults\ to\ 0,\ \"upgrading\"\ 2D\ points)\;\ such\ points\ can\ be\nused\ to\ construct\ lines\ and\ polygons\ (ovals\ too,\ but\ those\ may\ suffer\nfrom\ distortions).\ Also,\ the\ shadowing\ of\ background\ objects\ by\ foreground\ objects\ leaves\ room\ for\ improvement\ -\ncurrently\ this\ is\ only\ controlled\ by\ the\ order\ of\ creation.\n\nThe\ 2D\ projection\ of\ points\ is\ based\ on\ parallel\ projection,\ with\ some\nperspective\ thrown\ in.\ It\ depends\ heavily\ on\ the\ view\ angle,\ which\ I\ simply\ take\ as\ the\ visual\ angle\ between\ x\ and\ y\ axis.\ The\ x\ axis\ is\ horizontal\ as\ usual,\ z\ axis\ is\ vertical.\ For\ better\norientation,\ the\ axes\ are\ painted\ red\ (x),\ green\ (y),\ and\ blue\ (z).\nType\ \"x\"/\"y\"/\"z\"\ to\ switch\ temporarily\ to\ a\ 2D\ projection\ along\ the\ specified\naxis.\ In\ the\ demo\ program,\ which\ shows\ a\ little\ \"doll\ house\"\ (even\ with\nbadly\ hidden\ Easter\ eggs\ \;-),\ children\ may\ collect\ eggs\ by\ clicking\ on\ them\n(they'll\ turn\ to\ 0-s\ in\ the\ title\ bar).\ For\ adults,\ they\ might\ serve\ to\ verify\nspatial\ arrangement.\n\nYou\ can\ modify\ the\ '''view\ angle'''\ in\ steps\ of\ 5\ degrees\ with\ cursor\nLeft/Right\ keys,\ or\ '''zoom\ in/out'''\ with\ Up/Down\ keys.\ As\ the\ canvas\ncan't\ keep\ the\ 3D\ information,\ changes\ in\ view\ are\ done\ by\ redrawing\neverything\ from\ a\ backing\ store\ \[array\],\ which\ keeps\ all\ parameters\nfor\ every\ object.\ Reaction\ was\ just\ about\ fast\ enough\ on\ my\ P200\ machine.\n\nThe\ standard\ operations\ of\ translating\ (=moving),\ scaling,\nand\ rotating\ 3D\ objects\ are\ implemented\ -\ maybe\ not\ optimally,\ but\ndoing\ their\ job.\ They\ operate\ on\ tags,\ because\ most\ often\ an\nobject\ is\ composed\ of\ several\ primitives\ which\ share\ the\ same\ tag.\n'''Moving'''\ can\ be\ tested\ with\ the\ table\ and\ chairs\ -\ click\ on\ one\ to\ select,\nuse\ Shift-cursor\ keys\ to\ push\ it\ around\ (and\ ignore\ possible\ uglities\nin\ shadowing\ by\ other\ objects).\ To\ test\ movement\ in\ z\ direction,\ntype\ \"F\"\ or\ \"f\"\ to\ hoist\ or\ lower\ the\ flag,\ which\ when\ up\ is\ another\nexperiment\ in\ random\ 3D\ movement\ (but\ grows\ ridiculously\ long\ after\nextended\ Monte\ Carlo\ walks\ in\ 3D\ space\ -\ click\ on\ it\ to\ restore\ original\ndimensions).\ '''Rotation'''\ of\ furniture\ can\ be\ tested\ with\ Alt-cursor\ keys,\n'''scaling'''\ with\ \"+\"\ and\ \"-\".\ Clicking\ on\ the\ swings\ makes\nit\ swing\ (test\ for\ excentric\ animated\ rotation).\ Likewise,\ move\ the\ door\nwith\ left\ or\ right\ click.\ Experiments\ with\ '''dimming\ colours'''\ are\nalso\ included\ -\ use\ \"d\"\ resp.\ \"D\"\ keys\ to\ try.\ If\ things\ get\ too\ dark,\nturn\ on\ the\ light\ with\ the\ switch\ next\ to\ the\ door.\n\nFor\ really\ good\ 3D\ rendering,\ points\ should\ be\ projected\ depending\ on\ the\nlocation\ of\ the\ \"observer\",\ a\ point\ in\ 3D\ space\ from\ which\ the\ objects\nare\ seen,\ and\ his\ \"point\ of\ view\"\ (which\ becomes\ the\ 2D\ origin),\ but\ I\nhad\ no\ appropriate\ math\ books\ handy\ -\ please\ edit\ this\ page\ if\ you\ know\nbetter!\ (But\ then,\ real\ hidden-line\ treatment\ also\ becomes\ inevitable...)\n\nLatest\ addition,\ not\ very\ finished\ yet:\ the\ little\ red\ toy\ cart\ is\nmovable,\ and\ when\ you\ drive\ it\ over\ an\ egg\ and\ click\ right\ on\ the\ egg,\nit\ is\ \"lifted\"\ into\ the\ cart\ and\ stays\ with\ it.\ Still\ pretty\ crude,\ but\na\ long\ Easter\ weekend\ is\ now\ over\ -\ and\ I'm\ not\ paid\ for\ Tk\ games\nprogramming...\ \n\nDISCLAIMER:\ This\ works\ well\ and\ fine\ on\ Linux,\ W95\ and\ W2K.\ On\ Solaris,\ via\ Reflection\ from\ a\ Windows\ box,\ Alt-Cursor\ keys\ don't\ get\ through.\ Also,\ had\ to\ add\ nonzero\ tests\ in\ \"3d'rotate\",\ \nas\ ''atan2''\ errors\ when\ called\ with\ 0.0,0.0\ (not\ so\ on\ Windows).\ \[RS\]\n\n\[Arjen\ Markus\]\ The\ problem\ with\ the\ Alt-key\ may\ be\ that\ Reflection\ has\ not\ been\ informed\ to\ pass\ the\ left\ or\ right\ Alt-key\ to\ X\ Window\ -\ this\ is\ part\ of\ the\ keyboard\ settings.\ \[RS\]:\ Yes,\ this\ did\ it\ -\ thanks!\n----\n''\[escargo\]\ 15\ Apr\ 2003''\ -\ Are\ we\ supposed\ to\ be\ able\ to\ prune\ the\ shrubs?\ \ (Clicking\ on\ some\nof\ the\ greenery\ makes\ it\ go\ away?\ \ Also,\ there\ are\ sometimes\ some\ z-order\ problems.\ \ I\ had\ some\ of\nthe\ shrubs\ get\ drawn\ on\ the\ wrong\ side\ of\ one\ of\ the\ chairs.\ \ Also,\ sometimes\ the\ table\ is\ visible\nthrough\ the\ walls\ of\ the\ house.\ \ (I\ really\ like\ the\ light\ switch!)\n----\n\nI\ Updated\ Merry\ to\ Happy\ in\ the\ window\ title.\ I've\ heard\ of\ Merry\ Christmas,\ but\ never\ Merry\ Easter.\ I\ guess\ Merry\ and\ Happy\ have\ similar\ meanings\ though.\n\n----\n======\n\ set\ ::tcl_precision\ 17\n\ proc\ deg2rad\ \{deg\}\ \{expr\ \{\$deg\ *\ atan(1)/45.\}\}\n\ trace\ var\ 3d(angle)\ w\ \"set\ 3d(th)\ \\\[deg2rad\ \\\$3d(angle)\]\;#\"\n\ array\ set\ 3d\ \{angle\ 30\ scale\ 100\ bright\ 1\ lastDim\ .25\ flat\ 0\}\n\ \n\ proc\ 3d\ \{type\ w\ points\ args\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ set\ cmd\ \[list\ \$w\ create\ \$type\]\n\ \ \ \ foreach\ point\ \$points\ \{eval\ lappend\ cmd\ \[3d'project\ \$point\]\}\n\ \ \ \ if\ \{\$type\ ==\ \"poly\"\ &&\ \[lsearch\ \$args\ -outline\]\ <\ 0\}\ \{\n\tlappend\ cmd\ -outline\ black\ \ \ \;#\ looks\ better...\n\ \ \ \ \}\n\ \ \ \ set\ cmd\ \[concat\ \$cmd\ \$args\]\n\ \ \ \ if\ \{\$3d(bright)\ !=\ 1\}\ \{\n\ \ \ \ \ \ \ foreach\ att\ \{-outline\ -fill\}\ \{\n\t\ \ if\ \{\[set\ pos\ \[lsearch\ \$cmd\ \$att\]\]\ >\ 0\}\ \{\n\t\ \ \ \ \ set\ f\ \[lindex\ \$cmd\ \[incr\ pos\]\]\n\t\ \ \ \ \ set\ cmd\ \[lreplace\ \$cmd\ \$pos\ \$pos\ \[dimColor\ \$f\ \$3d(bright)\]\]\n\t\ \ \}\n\ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ set\ 3d(\[eval\ \$cmd\])\ \[list\ \$type\ \$points\ \$args\]\ \ \ \ \ \ \ \;#\ backing\ store\n\ \}\n\ proc\ 3d'axes\ w\ \{\n\ \ \ \ foreach\ \{name\ from\ \ \ \ \ \ \ to\ \ \ \ \ \ \ color\}\ \{\n\t\ \ \ \ Xaxis\ \{-30\ 0\ 0\}\ \{30\ 0\ 0\}\ \ red\n\t\ \ \ \ X1\ \ \ \ \{1\ 0\ 0\}\ \ \ \{1\ .05\ 0\}\ red\n\t\ \ \ \ Yaxis\ \{0\ -30\ 0\}\ \{0\ 30\ 0\}\ \ green\n\t\ \ \ \ Y1\ \ \ \ \{0\ 1\ 0\}\ \ \ \{0\ 1\ .05\}\ green\n\t\ \ \ \ Zaxis\ \{0\ 0\ -30\}\ \{0\ 0\ 30\}\ \ blue\n\t\ \ \ \ Z1\ \ \ \ \{0\ 0\ 1\}\ \ \ \{.05\ 0\ 1\}\ blue\n\ \ \ \ \}\ \{3d\ line\ \$w\ \[list\ \$from\ \$to\]\ -fill\ \$color\ -tag\ axes\}\n\ \}\n\ proc\ 3d'project\ point\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ foreach\ \{x\ y\ z\}\ \$point\ break\n\ \ \ \ if\ \{\$z==\"\"\}\ \{set\ z\ 0\}\n\ \ \ \ set\ factor\ \$3d(scale)\n\ \ \ \ switch\ --\ \$3d(flat)\ \{\n\tx\ \{list\ \[expr\ \{\$y*\$factor\}\]\ \[expr\ \{-\$z*\$factor\}\]\ \;#\ side\ \ view\}\n\ty\ \{list\ \[expr\ \{\$x*\$factor\}\]\ \[expr\ \{-\$z*\$factor\}\]\ \;#\ front\ view\}\n\tz\ \{list\ \[expr\ \{\$x*\$factor\}\]\ \[expr\ \{-\$y*\$factor\}\]\ \;#\ top\ \ \ view\}\n\tdefault\ \{\n\t\ \ \ \ set\ rad\ \[expr\ \{\$y\ *\ abs(1-(\$3d(angle)/90.))\}\]\n\t\ \ \ \ if\ \{abs(\$y)<6\}\ \{set\ factor\ \[expr\ \{\$factor*(1-\$y/6.)\}\]\}\;#perspective\n\t\ \ \ \ set\ 2dx\ \[expr\ \{(\$x\ +\ \$rad*cos(\$3d(th)))\ *\ \ \$factor\}\]\n\t\ \ \ \ set\ 2dy\ \[expr\ \{(\$z\ +\ \$rad*sin(\$3d(th)))\ *\ -\$factor\}\]\;#+y\ goes\ down\n\t\ \ \ \ list\ \$2dx\ \$2dy\n\t\}\n\ \ \ \ \}\n\ \}\n\ proc\ 3d'redraw\ \{w\ \{tag\ all\}\ \{flat\ \"\"\}\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ if\ \{\$flat\ !=\ \"\"\}\ \{set\ 3d(flat)\ \$flat\}\n\ \ \ \ set\ 3d(angle)\ \[expr\ \{\$3d(angle)>180?\ 180:\ \$3d(angle)<0?\ 0:\ \$3d(angle)\}\]\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tforeach\ \{type\ points\ args\}\ \$::3d(\$item)\ break\n\tunset\ 3d(\$item)\n\t\$w\ delete\ \$item\n\teval\ \[list\ 3d\ \$type\ \$w\ \$points\]\ \$args\n\ \ \ \ \}\n\ \}\n\ proc\ 3d'move\ \{w\ tag\ vector\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tset\ newpoints\ \{\}\n\tforeach\ point\ \[lindex\ \$3d(\$item)\ 1\]\ \{\n\t\ \ \ \ \ lappend\ newpoints\ \[vector'add\ \$point\ \$vector\]\n\t\}\n\tset\ 3d(\$item)\ \[lreplace\ \$3d(\$item)\ 1\ 1\ \$newpoints\]\n\ \ \ \ \}\n\ \ \ \ 3d'redraw\ \$w\ \$tag\n\ \}\n\ proc\ 3d'scale\ \{w\ tag\ factors\ \{rpoint\ \{\}\}\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ if\ \{\$rpoint==\"\"\}\ \{set\ rpoint\ \[3d'center\ \$w\ \$tag\]\}\n\ \ \ \ foreach\ \{x0\ y0\ z0\}\ \$rpoint\ break\n\ \ \ \ foreach\ \{xf\ yf\ zf\}\ \$factors\ break\n\ \ \ \ if\ \{\$yf\ ==\ \"\"\}\ \{set\ yf\ \$xf\}\n\ \ \ \ if\ \{\$zf\ ==\ \"\"\}\ \{set\ zf\ \$yf\}\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tset\ newpoints\ \{\}\n\tforeach\ point\ \[lindex\ \$3d(\$item)\ 1\]\ \{\n\t\ \ \ \ foreach\ \{x\ y\ z\}\ \$point\ break\n\t\ \ \ \ if\ \{\$z\ ==\ \"\"\}\ \{set\ z\ 0\}\n\t\ \ \ \ set\ x1\ \[expr\ \{(\$x\ -\ \$x0)\ *\ \$xf\ +\ \$x0\}\]\n\t\ \ \ \ set\ y1\ \[expr\ \{(\$y\ -\ \$y0)\ *\ \$yf\ +\ \$y0\}\]\n\t\ \ \ \ set\ z1\ \[expr\ \{(\$z\ -\ \$z0)\ *\ \$zf\ +\ \$z0\}\]\n\t\ \ \ \ lappend\ newpoints\ \[list\ \$x1\ \$y1\ \$z1\]\n\t\}\n\tset\ 3d(\$item)\ \[lreplace\ \$3d(\$item)\ 1\ 1\ \$newpoints\]\n\ \ \ \ \}\n\ \ \ \ 3d'redraw\ \$w\ \$tag\n\ \}\n\ proc\ 3d'rotate\ \{w\ tag\ rvector\ \{rpoint\ \{\}\}\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ foreach\ \{rx\ ry\ rz\}\ \$rvector\ break\ \;#\ rotation\ angles\ in\ degrees\n\ \ \ \ foreach\ i\ \{x\ y\ z\}\ \{set\ rd\$i\ \[deg2rad\ \[set\ r\$i\]\]\}\n\ \ \ \ if\ \{\$rpoint\ ==\ \"\"\}\ \{set\ rpoint\ \[3d'center\ \$w\ \$tag\]\}\n\ \ \ \ foreach\ \{xc\ yc\ zc\}\ \$rpoint\ break\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tset\ newpoints\ \{\}\n\tforeach\ point\ \[lindex\ \$3d(\$item)\ 1\]\ \{\n\t\ \ \ \ foreach\ \{x\ y\ z\}\ \$point\ break\n\t\ \ \ \ if\ \{\$z\ ==\ \"\"\}\ \{set\ z\ 0\}\n\t\ \ \ \ set\ x1\ \[expr\ \{\$x-\$xc\}\]\n\t\ \ \ \ set\ y1\ \[expr\ \{\$y-\$yc\}\]\n\t\ \ \ \ set\ z1\ \[expr\ \{\$z-\$zc\}\]\n\t\ \ \ \ if\ \{\$rx\ !=\ 0\}\ \{\n\t\tif\ \{\[set\ rad\ \[expr\ \{hypot(\$y1,\$z1)\}\]\]\}\ \{\n\t\t\ \ set\ th\ \ \[expr\ \{atan2(\$z1,\$y1)\ -\ \$rdx\}\]\n\t\t\ \ set\ y\ \ \ \[expr\ \{\$yc\ +\ \$rad\ *\ cos(\$th)\}\]\n\t\t\ \ set\ z\ \ \ \[expr\ \{\$zc\ +\ \$rad\ *\ sin(\$th)\}\]\n\t\t\}\ \;#\ tests\ for\ nonzero\ rad\ necessary\ on\ Unix\n\t\ \ \ \ \}\n\t\ \ \ \ if\ \{\$ry\ !=\ 0\}\ \{\n\t\tif\ \{\[set\ rad\ \[expr\ \{hypot(\$x1,\$z1)\}\]\]\}\ \{\n\t\t\ \ set\ th\ \ \[expr\ \{atan2(\$z1,\$x1)\ -\ \$rdy\}\]\n\t\t\ \ set\ x\ \ \ \[expr\ \{\$xc\ +\ \$rad\ *\ cos(\$th)\}\]\n\t\t\ \ set\ z\ \ \ \[expr\ \{\$zc\ +\ \$rad\ *\ sin(\$th)\}\]\n\t\t\}\n\t\ \ \ \ \}\n\t\ \ \ \ if\ \{\$rz\ !=\ 0\}\ \{\n\t\tif\ \{\[set\ rad\ \[expr\ \{hypot(\$x1,\$y1)\}\]\]\}\ \{\n\t\t\ \ \ set\ th\ \ \[expr\ \{atan2(\$y1,\$x1)\ -\ \$rdz\}\]\n\t\t\ \ \ set\ x\ \ \ \[expr\ \{\$xc\ +\ \$rad\ *\ cos(\$th)\}\]\n\t\t\ \ \ set\ y\ \ \ \[expr\ \{\$yc\ +\ \$rad\ *\ sin(\$th)\}\]\n\t\t\}\n\t\ \ \ \ \}\n\t\ \ \ \ lappend\ newpoints\ \[list\ \$x\ \$y\ \$z\]\n\t\}\n\tset\ 3d(\$item)\ \[lreplace\ \$3d(\$item)\ 1\ 1\ \$newpoints\]\n\ \ \ \ \}\n\ \ \ \ 3d'redraw\ \$w\ \$tag\n\ \}\n\ proc\ 3d'bcube\ \{w\ tag\}\ \{\n\ \ \ \ #--\ compute\ \"bounding\ cube\"\ (minx\ maxx\ miny\ maxy\ minz\ maxz)\n\ \ \ \ variable\ 3d\n\ \ \ \ set\ xs\ \{\}\;\ set\ ys\ \{\}\;\ set\ zs\ \{\}\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tforeach\ point\ \[lindex\ \$3d(\$item)\ 1\]\ \{\n\t\ \ \ \ foreach\ \{x\ y\ z\}\ \$point\ break\n\t\ \ \ \ lappend\ xs\ \$x\n\t\ \ \ \ lappend\ ys\ \$y\n\t\ \ \ \ lappend\ zs\ \$z\n\t\}\n\ \ \ \ \}\n\ \ \ \ concat\ \[minmax\ \$xs\]\ \[minmax\ \$ys\]\ \[minmax\ \$zs\]\n\ \}\n\ proc\ 3d'center\ \{w\ tag\}\ \{\n\ \ \ \ foreach\ \{x\ x1\ y\ y1\ z\ z1\}\ \[3d'bcube\ \$w\ \$tag\]\ break\n\ \ \ \ list\ \[expr\ \{(\$x+\$x1)/2.\}\]\ \[expr\ \{(\$y+\$y1)/2.\}\]\ \[expr\ \{(\$z+\$z1)/2.\}\]\n\ \}\n\ proc\ 3d'addtag\ \{w\ item\ tag\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ set\ args\ \[lindex\ \$3d(\$item)\ 2\]\n\ \ \ \ set\ found\ 0\;\ set\ newargs\ \{\}\n\ \ \ \ foreach\ \{att\ val\}\ \$args\ \{\n\tif\ \{\$att\ ==\ \"-tag\"\}\ \{lappend\ val\ \$tag\;\ incr\ found\}\n\tlappend\ newargs\ \$att\ \$val\n\ \ \ \ \}\n\ \ \ \ if\ \{!\$found\}\ \{lappend\ newargs\ -tag\ \$tag\}\n\ \ \ \ set\ 3d(\$item)\ \[lreplace\ \$3d(\$item)\ 2\ 2\ \$newargs\]\n\ \}\n\ proc\ dim\ \{w\ factor\ \{tag\ all\}\}\ \{\n\ \ \ \ variable\ 3d\n\ \ \ \ if\ \{\$factor\ ==\ 0\}\ \{\n\tset\ factor\ \[expr\ \{1./\$3d(lastDim)\}\]\n\tset\ 3d(lastDim)\ \$factor\ \;#\ allow\ toggle\ for\ light\ switch\n\ \ \ \ \}\ else\ \{set\ 3d(bright)\ \[expr\ \{\$3d(bright)*\$factor\}\]\}\n\ \ \ \ if\ \{\$tag\ ==\ \"all\"\}\ \{\n\t\$w\ config\ -bg\ \[dimColor\ \[\$w\ cget\ -bg\]\ \$factor\]\n\ \ \ \ \}\n\ \ \ \ foreach\ item\ \[\$w\ find\ withtag\ \$tag\]\ \{\n\tforeach\ att\ \{-fill\ -outline\}\ \{\n\t\ \ \ \ if\ \{!\[catch\ \{\$w\ itemcget\ \$item\ \$att\}\ f\]\}\ \{\n\t\t\$w\ itemconf\ \$item\ \$att\ \[dimColor\ \$f\ \$factor\]\n\t\ \ \ \ \}\n\t\}\n\ \ \ \ \}\n\ \}\n\ proc\ dimColor\ \{color\ factor\}\ \{\n\ \ \ \ if\ \{\$color\ ==\ \"\"\}\ \{return\ \"\"\}\n\ \ \ \ foreach\ \{r\ g\ b\}\ \[winfo\ rgb\ .\ \$color\]\ break\n\ \ \ \ set\ res\ \"#\"\n\ \ \ \ foreach\ i\ \{r\ g\ b\}\ \{\n\tset\ col\ \[expr\ \{round(\[set\ \$i\]*\$factor)\}\]\n\tif\ \{\$col\ >\ 0xFFFF\}\ \{set\ col\ 0xFFFF\}\n\tappend\ res\ \[format\ %4.4x\ \$col\]\n\ \ \ \ \}\n\ \ \ \ set\ res\n\ \}\n\ proc\ minmax\ L\ \{\n\ \ \ \ set\ sorted\ \[lsort\ -real\ \$L\]\n\ \ \ \ list\ \[lindex\ \$sorted\ 0\]\ \[lindex\ \$sorted\ end\]\n\ \}\n\ proc\ vector'add\ \{v1\ v2\}\ \{\n\ \ \ \ set\ res\ \{\}\n\ \ \ \ foreach\ i\ \$v1\ j\ \$v2\ \{\n\tif\ \{\$i\ ==\ \"\"\}\ \{set\ i\ 0\}\n\tif\ \{\$j\ ==\ \"\"\}\ \{set\ j\ 0\}\n\tlappend\ res\ \[expr\ \{\$i\ +\ \$j\}\]\n\ \ \ \ \}\n\ \ \ \ set\ res\n\ \}\n======\n======\n\ #--------------------------------\ A\ mighty\ elaborate\ and\ playful\ demo:\n======\n\ if\ \{\[file\ tail\ \[info\ script\]\]\ ==\ \[file\ tail\ \$argv0\]\}\ \{\n======\n======\n\ \ \ \ proc\ plant\ \{c\ x\ y\ \{diameter\ 0.6\}\ \{branches\ 8\}\}\ \{\n\tset\ root\ \[list\ \$x\ \$y\ 0\]\n\tfor\ \{set\ i\ 0\}\ \{\$i<\$branches\}\ \{incr\ i\}\ \{\n\t\ \ \ \ set\ x1\ \[expr\ \{\$x\ +\ rand()*\$diameter\ -\ \$diameter/2\}\]\n\t\ \ \ \ set\ y1\ \[expr\ \{\$y\ +\ rand()*\$diameter\ -\ \$diameter/2\}\]\n\t\ \ \ \ set\ z\ \ \[expr\ \{rand()*0.25\ +\ \$diameter\}\]\n\t\ \ \ \ set\ width\ \[expr\ \{round(\$diameter*6)\}\]\n\t\ \ \ \ 3d\ line\ \$c\ \[list\ \$root\ \[list\ \$x1\ \$y1\ \$z\]\]\ -width\ \$width\\\n\t\ \ \ \ -fill\ \[lpick\ \{DarkGreen\ green4\ ForestGreen\ SeaGreen\ YellowGreen\}\]\\\n\t\ \ \ \ -tag\ plant\n\t\}\n\ \ \ \ \}\n\ \ \ \ proc\ chair\ \{c\ x\ y\ \{colors\ \{white\ blue\}\}\}\ \{\n\tset\ h1\ 0.12\n\tset\ h2\ 0.2\n\tset\ h3\ 0.3\n\tset\ y1\ 0.25\;\ set\ y2\ 0.26\n\tset\ tag\ chair\[incr\ ::chairID\]\n\tset\ tag2\ \[list\ \$tag\ mv\]\n\tforeach\ \{c1\ c2\}\ \$colors\ break\n\t3d\ line\ \$c\ \"\{0\ \$y2\}\ \{.05\ \$y2\ \$h2\}\ \{.25\ \$y2\ \$h2\}\ \{.3\ \$y2\}\"\ -fill\ \$c1\\\n\t\ \ \ \ -width\ 2\ -tag\ \$tag2\n\t3d\ poly\ \$c\ \"\{.05\ 0\ \$h1\}\ \{.05\ \$y1\ \$h1\}\ \{.3\ \$y1\ \$h1\}\ \{.3\ 0\ \$h1\}\"\ \\\n\t\ \ \ \ -fill\ \$c2\ -tag\ \$tag2\ -width\ 2\n\t3d\ poly\ \$c\ \"\{.05\ 0\ \$h1\}\ \{0\ 0\ \$h3\}\ \{0\ \$y1\ \$h3\}\ \{.05\ \$y1\ \$h1\}\"\ \\\n\t\ \ \ \ -fill\ \$c2\ -tag\ \$tag2\ -width\ 2\n\t3d\ line\ \$c\ \"\{0\ 0\}\ \{.05\ 0\ \$h2\}\ \{.25\ 0\ \$h2\}\ \{.3\ 0\}\"\ -fill\ \$c1\ \\\n\t\ \ \ \ -width\ 2\ -tag\ \$tag2\n\t3d'move\ \$c\ \$tag\ \[list\ \$x\ \$y\ 0\]\n\tset\ tag\n\ \ \ \ \}\n\ \ \ \ set\ chairID\ 0\n\ \ \ \ proc\ every\ \{ms\ body\}\ \{eval\ \$body\;\ after\ \$ms\ \[info\ level\ 0\]\}\n\ \ \ \ proc\ lpick\ L\ \{lindex\ \$L\ \[expr\ \{int(rand()\ *\ \[llength\ \$L\])\}\]\}\n\ \ \ \ proc\ moveFlag\ \{w\}\ \{\n\tvariable\ 3d\n\tforeach\ i\ \[\$w\ find\ withtag\ =flag\]\ \{\n\t\ \ \ \ set\ points\ \[lindex\ \$3d(\$i)\ 1\]\n\t\ \ \ \ if\ \{\[lindex\ \[lindex\ \$points\ 0\]\ 2\]\ >\ 1.5\}\ \{\n\t\tset\ randv\ \{\}\n\t\tforeach\ _\ \{x\ y\ z\}\ \{\n\t\t\ \ \ \ lappend\ randv\ \[expr\ \{rand()*0.05-0.025\}\]\n\t\t\}\n\t\tset\ p1\ \[vector'add\ \[lindex\ \$points\ 1\]\ \$randv\]\n\t\tset\ p2\ \[vector'add\ \[lindex\ \$points\ 2\]\ \$randv\]\n\t\tset\ points\ \[lreplace\ \$points\ 1\ 2\ \$p1\ \$p2\]\n\t\tset\ 3d(\$i)\ \[lreplace\ \$3d(\$i)\ 1\ 1\ \$points\]\n\t\ \ \ \ \}\n\t\}\n\t3d'redraw\ \$w\ \ =flag\n\t\$w\ lower\ \ \ \ \ \ =flag\ backWall\n\ \ \ \ \}\n\ \ \ \ proc\ placeEggs\ w\ \{\n\ \ \ \ \ \ foreach\ color\ \{\n\tred\ green\ blue\ cyan\ magenta\ yellow\ orange\ pink\ purple\ brown\n\ \ \ \ \ \ \}\ \{\n\t\ set\ x\ \[expr\ \{rand()\ *\ 5.4\ -\ 1.9\}\]\n\t\ set\ y\ \[expr\ \{rand()\ *\ 4\ -\ 2\}\]\n\t\ 3d\ oval\ \$w\ \"\{\$x\ \$y\ .04\}\ \{\[expr\ \$x+.1\]\ \[expr\ \$y+.04\]\ -.04\}\"\\\n\t\ \ \ \ \ -fill\ \$color\ -tag\ egg\n\ \ \ \ \ \ \}\n\ \ \ \ \ \ \$w\ lower\ egg\ frontWall\n\ \ \ \ \ \ wm\ title\ .\ \"Happy\ 3D\ Easter!\"\n\ \ \ \ \ \ \$w\ bind\ egg\ <1>\ \{\n\t\ \ %W\ delete\ current\n\t\ \ wm\ title\ .\ \"\[wm\ title\ .\]\ 0\"\ \;#\ append\ found\ eggs\ to\ title\n\t\ \ if\ \{\[%W\ find\ withtag\ egg\]\ ==\ \"\"\}\ \{\n\t\ \ \ \ \ \ tk_messageBox\ -message\ Super!\n\t\ \ \ \ \ \ placeEggs\ %W\n\t\ \ \}\n\ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ proc\ swings\ \{w\ x0\ y0\}\ \{\n\tset\ x1\ \[expr\ \{\$x0\ +\ 0.8\}\]\n\tset\ xm\ \[expr\ \{(\$x0\ +\ \$x1)/2\}\]\n\tset\ x2\ \[expr\ \{\$xm\ -\ 0.05\}\]\n\tset\ x3\ \[expr\ \{\$xm\ +\ 0.05\}\]\n\tset\ y1\ \[expr\ \{\$y0\ +\ 0.7\}\]\n\tset\ y2\ \[expr\ \{\$y0\ +\ 0.3\}\]\ \;#\ rope\ 1\n\tset\ y3\ \[expr\ \{\$y0\ +\ 0.5\}\]\ \;#\ rope\ 2\n\tset\ h\ 0.8\ \ \ \ \;#\ top\ crossbar\n\tset\ s\ 0.14\ \ \ \;#\ height\ of\ swing\ seat\n\tset\ col\ turquoise4\n\t3d\ line\ \$w\ \"\{\$x0\ \$y1\}\ \{\$xm\ \$y1\ \$h\}\ \{\$x1\ \$y1\}\"\ -width\ 2\ -fill\ \$col\n\t3d\ line\ \$w\ \"\{\$xm\ \$y0\ \$h\}\ \{\$xm\ \$y1\ \$h\}\"\ -width\ 2\ -fill\ \$col\n\t3d\ line\ \$w\ \"\{\$xm\ \$y3\ \$h\}\ \{\$xm\ \$y3\ \$s\}\"\ -tag\ swingm\n\t3d\ poly\ \$w\ \"\{\$x2\ \$y2\ \$s\}\ \{\$x3\ \$y2\ \$s\}\ \{\$x3\ \$y3\ \$s\}\ \{\$x2\ \$y3\ \$s\}\"\\\n\t\ \ \ \ -fill\ orange\ -tag\ swingm\n\t3d\ line\ \$w\ \"\{\$xm\ \$y2\ \$h\}\ \{\$xm\ \$y2\ \$s\}\"\ -tag\ swingm\n\t3d\ line\ \$w\ \"\{\$x0\ \$y0\}\ \{\$xm\ \$y0\ \$h\}\ \{\$x1\ \$y0\}\"\ -width\ 2\ -fill\ \$col\\\n\t\ \ \ \ -tag\ swingfg\n\tset\ swingpoint\ \[list\ \$xm\ \$y2\ \$h\]\n\t\$w\ bind\ swingm\ <1>\ \[list\ swing'move\ %W\ swingm\ \$swingpoint\ 20\]\n\ \ \ \ \}\n\ \ \ \ proc\ swing'move\ \{w\ tag\ rpoint\ angle\}\ \{\n\t\$w\ raise\ swingfg\n\tif\ \{\$angle<=0\}\ return\n\t3d'rotate\ \$w\ \$tag\ \[list\ 0\ \$angle\ 0\]\ \$rpoint\n\tset\ angle2\ \[expr\ \{\$angle*-2\}\]\n\tafter\ 250\ \[list\ 3d'rotate\ \$w\ \$tag\ \[list\ 0\ \$angle2\ 0\]\ \$rpoint\]\n\tafter\ 500\ \[list\ 3d'rotate\ \$w\ \$tag\ \[list\ 0\ \$angle\ 0\]\ \$rpoint\]\n\tafter\ 500\ \[list\ swing'move\ \$w\ \$tag\ \$rpoint\ \[incr\ angle\ -1\]\]\n\ \ \ \ \}\n\ \ \ \ proc\ toycart\ \{w\ x\ y\ \{color\ red\}\}\ \{\n\t3d\ oval\ \$w\ \{\{.01\ .18\ .1\}\ \ \{.09\ .2\ 0\}\}\ -fill\ black\ -tags\ \{cart\ mv\}\n\t3d\ oval\ \$w\ \{\{.19\ .18\ .1\}\ \ \{.27\ .2\ 0\}\}\ -fill\ black\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.01\ .01\ .1\}\ \{.01\ .19\ .1\}\ \{.29\ .19\ .1\}\ \{.29\ .01\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.01\ .19\ .1\}\ \{0\ .2\ .15\}\ \{.3\ .2\ .15\}\ \{.29\ .19\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.01\ .01\ .1\}\ \{0\ 0\ .15\}\ \{0\ .2\ .15\}\ \{.01\ .19\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.29\ .01\ .1\}\ \{.3\ 0\ .15\}\ \{.3\ .2\ .15\}\ \{.29\ .19\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ poly\ \$w\ \{\{.01\ .01\ .1\}\ \{0\ 0\ .15\}\ \{.3\ 0\ .15\}\ \{.29\ .01\ .1\}\}\\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\ front\}\n\t3d\ line\ \$w\ \{\{.3\ .1\ .1\}\ \ \{.55\ .1\ 0\}\}\ -width\ 2\ \\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ line\ \$w\ \{\{.55\ .07\ 0\}\ \{.55\ .13\ 0\}\}\ -width\ 2\ \\\n\t\ \ \ \ -fill\ \$color\ -tags\ \{cart\ mv\}\n\t3d\ oval\ \$w\ \{\{.01\ .02\ .1\}\ \ \{.09\ 0\ 0\}\}\ -fill\ black\ -tags\ \{cart\ mv\}\n\t3d\ oval\ \$w\ \{\{.19\ .02\ .1\}\ \ \{.27\ 0\ 0\}\}\ -fill\ black\ -tags\ \{cart\ mv\}\n\t3d'move\ \$w\ cart\ \[list\ \$x\ \$y\]\ \;#\ bring\ to\ target\ position\n\t\$w\ bind\ egg\ <3>\ \{\n\t\ \ \ \ set\ item\ \[%W\ find\ withtag\ current\]\n\t\ \ \ \ 3d'addtag\ %W\ \$item\ cart\ \ \ \ \ \ \;#\ let\ it\ move\ with\ the\ cart...\n\t\ \ \ \ 3d'move\ \ \ %W\ \$item\ \{0\ 0\ .11\}\ \;#\ ...and\ raise\ it\ on\ board\n\t\ \ \ \ %W\ raise\ front\ egg\n\t\}\n\treturn\ cart\n\ \ \ \ \}\n\ \ \ \ #----------------------------------\ let's\ build\ up\ the\ scene...\n\ \ \ \ set\ c\ \[canvas\ .c\ -width\ 600\ -height\ 400\ \\\n\t-scrollregion\ \{-250\ -300\ 350\ 100\}\ -bg\ steelblue1\]\n\ \ \ \ pack\ \$c\ \ -fill\ both\ -expand\ 1\n\ \ \ \ 3d'axes\ \$c\n\ \ \ \ 3d\ poly\ \$c\ \{\{-4\ -3\}\ \{6\ -3\}\ \{6\ -3\ -2\}\ \{-4\ -3\ -2\}\}\ -fill\ brown\ \ \ \ \;#\ earth\n\ \ \ \ 3d\ poly\ \$c\ \{\{-4\ -3\}\ \{6\ -3\}\ \{6\ 2\}\ \{-4\ 2\}\}\ -fill\ green3\t\ \ \ \ \;#\ lawn\n\ \ \ \ 3d\ poly\ \$c\ \{\{-4\ 2\}\ \{.3\ 2\}\ \{.3\ 2\ .4\}\ \{-4\ 2\ .4\}\}\ -fill\ DarkOrange2\;#\ fence\n\ \ \ \ 3d\ poly\ \$c\ \{\{.7\ 2\}\ \{6\ 2\}\ \{6\ 2\ .4\}\ \{.7\ 2\ .4\}\}\ -fill\ DarkOrange2\ \ \;#\ fence\n\ \ \ \ 3d\ poly\ \$c\ \{\{.3\ .1\}\ \{1.7\ .1\}\ \{1.7\ -.7\}\ \{.3\ -.7\}\}\ -fill\ gray\ \ \ \ \;#terrace\n\ \ \ \ plant\ \$c\ 1\ 1.9\n\ \ \ \ 3d\ line\ \$c\ \{\{.5\ 1.8\}\ \{.5\ 1.8\ 2.85\}\}\ -fill\ white\ -width\ 3\ \ \ \ \ \;#\ flagpole\n\ \ \ \ set\ flagCoords\ \{\{.5\ 1.8\ 2.5\}\ \{.62\ 2\ 2.5\}\ \{.62\ 2\ 2.8\}\ \{.5\ 1.8\ 2.8\}\}\n\ \ \ \ 3d\ poly\ \$c\ \$flagCoords\ -fill\ blue\ -tags\ =flag\t\t\ \ \ \ \;#\ flag\n\ \ \ \ \$c\ bind\ =flag\ <1>\ \{\n\ \ \ \ \ \ \$c\ delete\ =flag\;\ 3d\ poly\ \$c\ \$flagCoords\ -fill\ blue\ -tags\ =flag\n\ \ \ \ \}\n\ \ \ \ 3d\ poly\ \$c\ \{\{0\ .1\}\ \{0\ 1\}\ \{2\ 1\}\ \{2\ .1\}\}\ -fill\ orange\ -tag\ in\ \ \ \ \ \ \;#floor\n\ \ \ \ 3d\ oval\ \$c\ \{\{.3\ .3\}\ \{1.8\ .8\}\}\ -fill\ purple\ -tag\ in\t\ \ \ \ \ \;#\ carpet\n\ \ \ \ plant\ \$c\ \ -1.3\ \ 1.8\ 0.5\n\ \ \ \ plant\ \$c\ \ \ 3\ \ \ \ 1.8\ 0.6\n\ \ \ \ swings\ \$c\ -1.6\ -0.3\n\ \ \ \ 3d\ oval\ \$c\ \{\{-3.2\ -2.7\}\ \{-1.5\ -1\}\}\ \ \ -fill\ beige\t\t\ \;#\ pool\n\ \ \ \ 3d\ oval\ \$c\ \{\{-3.1\ -2.6\}\ \{-1.6\ -1.1\}\}\ -fill\ DeepSkyBlue3\ \;#\ water\ in\ pool\n\ \ \ \ placeEggs\ \$c\n\ \ \ \ 3d\ poly\ \$c\ \{\{.2\ 1\}\ \{.36\ 1.3\}\ \{.36\ 1.3\ .8\}\ \{.2\ 1\ .8\}\}\ \\\n\ \ \ \ -fill\ brown\ -tag\ \{=door\ in\}\t\t\t\t\ \ \ \ \ \ \;#\ door\n\ \ \ \ 3d\ oval\ \$c\ \{\{.34\ 1.25\ .29\}\ \{.37\ 1.29\ .32\}\}\ -fill\ yellow\ \\\n\ \ \ \ -outline\ orange\ -tag\ \{=door\ in\}\t\t\t\t\ \ \ \;#knob\n\ \ \ \ \$c\ bind\ =door\ <1>\ \{\n\t3d'rotate\ %W\ =door\ \{0\ 0\ -15\}\ \{.2\ 1\ .4\}\;\ %W\ lower\ =door\ backWall\}\n\ \ \ \ \$c\ bind\ =door\ <3>\ \{\n\t3d'rotate\ %W\ =door\ \{0\ 0\ 15\}\ \{.2\ 1\ .4\}\;\ %W\ lower\ =door\ backWall\}\n\ \ \ \ 3d\ poly\ \$c\ \{\{0\ 1\}\ \{.2\ 1\}\ \{.2\ 1\ .7\}\ \{.54\ 1\ .7\}\ \{.54\ 1\}\n\t\ \{1.3\ 1\}\ \{1.3\ 1\ .3\}\ \{.8\ 1\ .3\}\ \{.8\ 1\ .7\}\ \{1.3\ 1\ .7\}\n\t\{1.3\ 1\}\ \{2\ 1\}\ \{2\ 1\ 1\}\ \{0\ 1\ 1\}\}\ -fill\ bisque\ -outline\ bisque\ \\\n\t\ \ \ \ -tag\ \{backWall\ in\}\t\t\t\t\ \ \;#\ back\ wall\ \n\ \ \ \ 3d\ poly\ \$c\ \{\{.57\ 1\ .4\}\ \{.65\ 1\ .4\}\ \{.65\ 1\ .48\}\ \{.57\ 1\ .48\}\}\ \\\n\t-fill\ white\ -tag\ \{=lightSwitch\ in\}\t\t\ \ \ \;#\ light\ switch\n\ \ \ \ \$c\ bind\ =lightSwitch\ <1>\ \{dim\ %W\ 0\ in\}\n\ \ \ \ 3d\ line\ \$c\ \{\{1\ 1\ .3\}\ \{1\ 1\ .7\}\}\ -fill\ white\ -width\ 2\ -tag\ in\;#\ window\ bar\n\t3d\ poly\ \$c\ \{\{-.05\ 1.05\ 1\}\ \{-.05\ .5\ 1.5\}\ \{2.05\ .5\ 1.5\}\ \{2.05\ 1.05\ 1\}\}\\\n\t\ -fill\ red\t\t\t\t\t\ \ \ \ \;#\ (back)\ roof\n\ \ \ \ 3d\ poly\ \$c\ \{\{0\ .1\}\ \{0\ 1\}\ \{0\ 1\ 1\}\ \{0\ .5\ 1.5\}\ \{0\ .1\ 1\}\}\ \\\n\t-fill\ beige\t\t\t\t\t\;#\ left\ side\ wall\n\ \ \ \ foreach\ \{x\ y\}\ \{.51\ .31\ \ .51\ .49\ \ .79\ .49\ \ .79\ .31\}\ \{\n\t3d\ line\ \$c\ \[list\ \[list\ \$x\ \$y\ 0\]\ \[list\ \$x\ \$y\ .3\]\]\ \\\n\t\ \ \ \ -fill\ black\ -width\ 3\ -tag\ \{=table\ mv\}\}\t\ \ \ \ \ \;#\ table\ legs\n\ \ \ \ 3d\ poly\ \$c\ \{\{.5\ .3\ .3\}\ \{.5\ .5\ .3\}\ \{.8\ .5\ .3\}\ \{.8\ .3\ .3\}\}\ \\\n\t-fill\ lightblue\ -tag\ \{=table\ mv\ in\}\t\t\ \ \ \;#\ table\ plate\n\ \ \ \ 3d\ poly\ \$c\ \{\{2\ .1\}\ \{2\ 1\}\ \{2\ 1\ 1\}\ \{2\ .5\ 1.5\}\ \{2\ .1\ 1\}\}\ -fill\ pink\ \ \;#wall\n\ \ \ \ 3d\ poly\ \$c\ \{\{0\ .1\}\ \{.3\ .1\}\ \{.3\ .1\ .8\}\ \{1.7\ .1\ .8\}\ \{1.7\ .1\ .3\}\n\ \ \ \ \{1\ .1\ .3\}\ \{1\ .1\ .8\}\ \{.9\ .1\ .8\}\ \{.9\ .1\}\ \{2\ .1\}\ \{2\ .1\ 1\}\ \{0\ .1\ 1\}\}\ \\\n\t-fill\ LightYellow\ -outline\ LightYellow\ -tag\ frontWall\ \ \;#\ front\ wall\n\ \ \ \ 3d\ poly\ \$c\ \{\{.99\ .1\ .29\}\ \{1.7\ .1\ .29\}\ \{1.7\ .1\ .81\}\ \{.99\ .1\ .81\}\}\\\n\t-fill\ \{\}\ -width\ 2\ -outline\ NavyBlue\t\t\ \ \ \;#window\ frame\n\ \ \ \ 3d\ poly\ \$c\ \{\{-.05\ .05\ 1\}\ \{-.05\ .5\ 1.5\}\ \{2.05\ .5\ 1.5\}\ \{2.05\ .05\ 1\}\}\\\n\t\ -fill\ red\t\t\t\t\t\ \ \ \;#\ (front)\ roof\n\ \ \ \ chair\ \ \ \$c\ -0.5\ -1.8\n\ \ \ \ toycart\ \$c\ \ 2\ \ \ -2\n\ \ \ \ 3d'rotate\ \$c\ \[chair\ \$c\ 0\ -2.5\]\ \{0\ 0\ -60\}\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i<10\}\ \{incr\ i\}\ \{\n\tplant\ \$c\ \[expr\ \{5-rand()*6\}\]\ \[expr\ \{-3+rand()*2.3\}\]\ 0.2\ 5\n\ \ \ \ \}\n\ \ \ \ plant\ \$c\ -2.5\ -.8\ .7\n\ \ \ \ plant\ \$c\ \ 2.8\ -.8\ .5\n\ \ \ \ #---------------------------------------------------------\ Bindings\n\ \ \ \ bind\ .\ <Left>\ \ \{incr\ 3d(angle)\ \ 5\;\ 3d'redraw\ .c\ all\ 3d\}\n\ \ \ \ bind\ .\ <Right>\ \{incr\ 3d(angle)\ -5\;\ 3d'redraw\ .c\ all\ 3d\}\n\ \ \ \ bind\ .\ <Up>\ \ \ \ \{set\ 3d(scale)\ \[expr\ \{\$3d(scale)*1.25\}\]\;\ 3d'redraw\ .c\}\n\ \ \ \ bind\ .\ <Down>\ \ \{set\ 3d(scale)\ \[expr\ \{\$3d(scale)/1.25\}\]\;\ 3d'redraw\ .c\}\n\ \ \ \ #--\ test\ transformations\ with\ current\ \"mv\"\ (movable)\ object\n\ \ \ \ set\ mv\ =table\ \;#\ initially:\ table\ (best\ move\ it\ out\ of\ house\ first)\n\ \ \ \ bind\ .\ <Shift-Left>\ \ \{3d'move\ \ \ \$c\ \$mv\ \{-.1\ 0\ 0\}\}\n\ \ \ \ bind\ .\ <Shift-Right>\ \{3d'move\ \ \ \$c\ \$mv\ \{.1\ \ 0\ 0\}\}\n\ \ \ \ bind\ .\ <Shift-Up>\ \ \ \ \{3d'move\ \ \ \$c\ \$mv\ \{0\ \ .1\ 0\}\}\n\ \ \ \ bind\ .\ <Shift-Down>\ \ \{3d'move\ \ \ \$c\ \$mv\ \{0\ -.1\ 0\}\}\n\ \ \ \ bind\ .\ <Alt-Left>\ \ \ \ \{3d'rotate\ \$c\ \$mv\ \{0\ \ 0\ \ 5\}\}\n\ \ \ \ bind\ .\ <Alt-Right>\ \ \ \{3d'rotate\ \$c\ \$mv\ \{0\ \ 0\ -5\}\}\n\ \ \ \ bind\ .\ <Alt-Up>\ \ \ \ \ \ \{3d'rotate\ \$c\ \$mv\ \{0\ \ 5\ \ 0\}\}\n\ \ \ \ bind\ .\ <Alt-Down>\ \ \ \ \{3d'rotate\ \$c\ \$mv\ \{0\ -5\ \ 0\}\}\n\ \ \ \ bind\ .\ +\t\ \ \ \ \ \{3d'scale\ \ \$c\ \$mv\ 1.25\}\t\ \ \ \ \ \ \ \;#\ grow\n\ \ \ \ bind\ .\ -\t\ \ \ \ \ \{3d'scale\ \ \$c\ \$mv\ 0.8\}\t\ \ \ \ \ \ \;#\ shrink\n\ \ \ \ \$c\ bind\ mv\ <1>\ \{\n\tset\ mv\ \[lindex\ \[%W\ gettags\ current\]\ 0\]\n\t3d'move\ %W\ \$mv\ \{-.01\ -.01\ -.01\}\ \ \ \ \ \ \ \;#\ visual\ feedback\ in\ 3D\n\tafter\ 100\ \[list\ 3d'move\ %W\ \$mv\ \{.01\ .01\ .01\}\]\n\ \ \ \ \}\n\ \ \ \ \$c\ bind\ plant\ <1>\ \{%W\ delete\ current\}\t\ \ \ \;#\ for\ \"gardening\"\n\ \ \ \ bind\ .\ x\ \{3d'redraw\ \$c\ all\ x\}\t\ \ \ \;#\ side\ view,\ along\ x\ axis\n\ \ \ \ bind\ .\ y\ \{3d'redraw\ \$c\ all\ y\}\t\ \ \;#\ front\ view,\ along\ y\ axis\n\ \ \ \ bind\ .\ z\ \{3d'redraw\ \$c\ all\ z\}\t\ \ \ \ \;#\ top\ view,\ along\ z\ axis\n\ \ \ \ bind\ .\ 3\ \{3d'redraw\ \$c\ all\ 3d\}\t\ \ \ \;#\ \ \ \ \ \ perspectivic\ view\n\ \ \ \ bind\ .\ F\ \[list\ 3d'move\ \$c\ =flag\ \ \{0\ 0\ \ .1\}\]\t\ \ \;#\ hoist\ flag\n\ \ \ \ bind\ .\ f\ \[list\ 3d'move\ \$c\ =flag\ \ \{0\ 0\ -.1\}\]\t\ \ \;#\ lower\ flag\n\ \ \ \ bind\ .\ d\ \{dim\ .c\ .8\}\t\t\t\;#\ decrease\ brightness\n\ \ \ \ bind\ .\ D\ \{dim\ .c\ 1.25\}\t\t\ \ \ \ \ \ \;#\ increase\ brightness\n\ \ \ \ bind\ .\ <Escape>\ \{exec\ wish\ \$argv0\ &\;\ exit\}\t\ \ \ \ \ \ \;#\ restart\n\ \ \ \ bind\ .\ ?\ \{console\ show\}\t\t\t\ \ \ \;#\ for\ debugging\n\n\ \ \ \ #--------------------------------------------\ Initial\ animation...\n\ \ \ \ set\ 3d(scale)\ 0.2\t\ \ \ \ \ \ \ \;#\ start\ with\ a\ view\ from\ far\ away\n\ \ \ \ 3d'redraw\ .c\n\ \ \ \ raise\ .\;\ update\t\t\t\ \ \ \ \;#\ necessary\ on\ Windows\n\ \ \ \ while\ \{\$3d(scale)<80\}\ \{event\ generate\ .\ <Up>\;\ update\}\n\ \ \ \ every\ 250\ \{moveFlag\ \ .c\}\ \ \ \ \ \;#\ so\ there's\ always\ something\ moving\n======\n======\n\ \}\n======\n----\n\[Tk\]\ -\ \[Category\ 3D\ Graphics\]\ -\ \ \[Arts\ and\ crafts\ of\ Tcl-Tk\ programming\]} CALL {my revision {Playing 3D}} CALL {::oo::Obj5036379 process revision/Playing+3D} CALL {::oo::Obj5036377 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4