From 0d4c022232882dfe46ba3ceac64aed2fbdf9fc98 Mon Sep 17 00:00:00 2001 From: MiQ75 Date: Mon, 25 Jan 2021 18:19:21 +0100 Subject: [PATCH 1/2] free rotation code and example --- README.md | 19 ++- cubeExample.py | 11 +- foldExample.py | 138 +++++++++++++++++++++ graphics/__pycache__/engine.cpython-38.pyc | Bin 7328 -> 8960 bytes graphics/__pycache__/face.cpython-38.pyc | Bin 501 -> 504 bytes graphics/__pycache__/screen.cpython-38.pyc | Bin 1679 -> 1682 bytes graphics/__pycache__/vertex.cpython-38.pyc | Bin 1593 -> 3114 bytes graphics/engine.py | 70 +++++++++-- graphics/vertex.py | 29 ++++- 9 files changed, 246 insertions(+), 21 deletions(-) mode change 100644 => 100755 cubeExample.py create mode 100755 foldExample.py mode change 100644 => 100755 graphics/engine.py diff --git a/README.md b/README.md index 1612ea9..4fe7908 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,25 @@ test = Engine3D([[1, 1, 1], [0, 0, 0], [2, 2, 2]], [[0, 1, 2]]) # this will crea test = Engine3D([[1, 1, 1], [0, 0, 0], [2, 2, 2]], [[0, 1, 2, "green"]]) # you can also change the color of the triangle (the default is green) ``` -From your code, you can modify the display using the writePoints, writeTriangles, rotate, clear and render methods. +You can also define a list of folds that would be used to animate a multi-step folding. +Each folding step is itself composed of simultaneously done line folds. +Each line fold is defined by it's angle in degreee, two vertices that defines an oriented axe and a list of concerned vertices. + +```Python +vertices = [[-1, -1, 1], [-1, 1, 0], [1, -1, .5], [-1, -1, -.5]] +faces = [[0, 1, 2, "green"], [1, 2, 3, "red"]] +folds = [[(45, 1, 2, [3])]] +test = Engine3D(vertices, faces, folds) +``` + +From your code, you can modify the display using the writePoints, writeTriangles, rotate, free_rotate, part_free_rotate, clear and render methods. ```Python test.writePoints([[3, 3, 3], [0, 0, 0], [2, 2, 2]]) # change the points test.writeTriangles([[2, 1, 0, "blue"]]) # the order of the points does not matter test.rotate("y", 45) # rotate the object 45 degrees around the y axis +test.free_rotate(45, 1, 2) # rotate the object 45 degrees around vertices[1]vertices[2] axis +test.part_free_rotate(45, 1, 2, [3, 4]) # rotate vertices[3] and vertices[4] 45 degrees around (vertices[1],vertices[2]) axis test.clear() # clear the display test.render() # update the image ``` @@ -39,6 +52,7 @@ You can also use the following keys to interact with the display. 2. Up arrow -> Zoom in 3. Down arrow -> Zoom out 4. w, a, s, d -> Move the view up, left, down or right +5. n, p -> Animate the next or previous fold The module now also allows you to move points on the model (this is still a work in progress) @@ -48,4 +62,5 @@ The module now also allows you to move points on the model (this is still a work --- -If you would like to help me improve this project, you can contact me at code@henryhaefliger.com +Initial code: code@henryhaefliger.com +Folding and free rotation axis code: miq75@free.fr diff --git a/cubeExample.py b/cubeExample.py old mode 100644 new mode 100755 index 6123e64..997f7a0 --- a/cubeExample.py +++ b/cubeExample.py @@ -1,18 +1,19 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- ### Cube ### import graphics.engine points = [[-1,-1,-1],[-1,-1,1],[-1,1,1],[-1,1,-1],[1,-1,-1],[1,-1,1],[1,1,1],[1,1,-1]] -triangles = [[0,1,2],[0,2,3],[2,3,7],[2,7,6],[1,2,5],[2,5,6],[0,1,4],[1,4,5],[4,5,6],[4,6,7],[3,7,4],[4,3,0]] - +triangles = [[0,1,3],[1,2,3],[1,2,6],[1,5,6],[0,1,4],[1,4,5],[4,5,6],[4,7,6],[0,3,4],[3,4,7],[2,3,6],[3,6,7]] test = graphics.engine.Engine3D(points, triangles, title='Cube') def animation(): test.clear() - test.rotate('y', 0.1) - test.rotate('x', 0.1) + test.rotate('y', 1) + test.rotate('x', 1) test.render() - test.screen.after(1, animation) + test.screen.after(100, animation) animation() test.screen.window.mainloop() diff --git a/foldExample.py b/foldExample.py new file mode 100755 index 0000000..2eadb79 --- /dev/null +++ b/foldExample.py @@ -0,0 +1,138 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""Folding management example. + + +Origami pattern +--------------- + +Here we got an example of how graphical engine can use rotation around free +axis. We use those rotations on a rectangular paper sheet and fold it into +origami card box. + +The origami pattern is flat modelised with final card box dimensions, so +vertices coordinates are calculated accordly to few parameters. + +Folds are a bit complexe to describe: +- Parameter is a list of step-folds; +- Each step-fold is itself a list of line-folds moving together during the + folding step; +- Each line-fold is a 4 tuple composed by: + - The angle value in degrees; + - 2 vertices indexes that defines the rotation axe (oriented); + - A list of vertices indexes that rotates around this . + + +Commands +-------- + +A set of two new commmands are added to the keyboard binding: +-: forward animation of the next fold +-: backward animation of the previous fold + + +Technical remarks +----------------- + +- The current drawing engine uses a fast but simple ordering of faces on their +z-middle-coordinate. Then faces are drawn from far to close, and close faces +covers far ones. This way of rendering is quite good enougth to draw volumic +models with single grid faces, but is doesn't render perfect for faces that are +close and almost parallels like folded sheets of paper. So, until the render +engine is changed for a more complex and strict one, folded models may need to +be turn around to be correctly drawn and understood. + +- Some patterns contains faces that are not triangles, but the current engine +only manages triangles. Until other polygones ares managed by main engine, +patterns would use a uniq color to show each rigid polygon (So 2 consecutive +same color triangles do not fold in beetween in the final model - but they can +fold a bit during folding for gaining light paper twist). + +- There is no management for polygons intersections during fold visualisation so +there might be vertices that moves a little through faces. During real paper +folding, paper polygons are flexibles so there is no problem. + +""" + +import graphics.engine + +# Flat pattern that folds into a parametric box. +W = 1.3 # box width +T = .5 # box thickness +S = .01 # paper thickness causing a little shift on some faces (pre calculated in flat pattern). + +points = [ + [-2.5*W-2*T+S, -.5*W, .5*T], [-1.5*W-2*T+S, -.5*W, .5*T], [-1.5*W-T, -.5*W, .5*T], # 0 1 2 + [-.5*W-T, -.5*W, .5*T], [-.5*W, -.5*W, .5*T], [.5*W, -.5*W, .5*T+S/2], # 3 4 5 + [.5*W+T-S, -.5*W, .5*T+S/2], [1.5*W+T-S, -.5*W, .5*T+S/2], [1.5*W+2*T-3*S, -.5*W, .5*T+S/2], # 6 7 8 + [-2.5*W-2*T+S, .5*W, .5*T], [-1.5*W-2*T+S, .5*W, .5*T], [-1.5*W-T, .5*W, .5*T], # 9 10 11 + [-.5*W-T, .5*W, .5*T], [-.5*W, .5*W, .5*T], [.5*W, .5*W, .5*T-S/2], # 12 13 14 + [.5*W+T-S, .5*W, .5*T-S/2], [1.5*W+T-S, .5*W, .5*T-S/2], [1.5*W+2*T-3*S, .5*W, .5*T-S/2], # 15 16 17 + [-2*W-2*T+S, 0, .5*T], [-1.5*W-1.5*T+S, 0, .5*T], [-1*W-T, 0, .5*T], # 18 19 20 + [-.5*W-.5*T, 0, .5*T], [0, 0, .5*T], [.5*W+.5*T, 0, .5*T], # 21 22 23 + [W+T-S, 0, .5*T], [1.5*W+1.5*T-S, 0, .5*T], # 24 25 + ] + +quads = [ + [0, 1, 18, 'pink'], [0, 9, 18, 'pink'], [1, 10, 18, 'pink'], [9, 10, 18, 'pink'], + [1, 2, 19, 'red'], [1, 10, 19, 'red'], [2, 11, 19, 'red'], [10, 11, 19, 'red'], + [2, 3, 20, 'orange'], [2, 11, 20, 'orange'], + [3, 12, 20, 'gold'], [11, 12, 20, 'gold'], + [3, 4, 21, 'lime'], [3, 12, 21, 'lime'], [4, 13, 21, 'lime'], [12, 13, 21, 'lime'], + [4, 5, 22, 'green'], [4, 13, 22, 'green'], [5, 14, 22, 'green'], [13, 14, 22, 'green'], + [5, 6, 23, 'cyan'], [5, 14, 23, 'cyan'], [6, 15, 23, 'cyan'], [14, 15, 23, 'cyan'], + [6, 15, 24, 'royal blue'], [15, 16, 24, 'royal blue'], + [6, 7, 24, 'blue'], [7, 16, 24, 'blue'], + [7, 8, 25, 'purple'], [7, 16, 25, 'purple'], [8, 17, 25, 'purple'], [16, 17, 25, 'purple'], + ] + +PA = 15 # small angle to visualise paper marks in pre-fold +folds = [ + [ # pre mark for any final fold + (PA, 1, 10, [0, 9, 18]), # pink/red + (PA, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange + (PA, 11, 3, [0, 1, 2, 9, 10, 18, 19]), # orange/yellow + (PA, 12, 3, [0, 1, 2, 9, 10, 11, 18, 19, 20]), # yellow/lime + (PA, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green + (PA, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan + (PA, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue + (PA, 6, 16, [7, 8, 17, 25]), # lightblue/blue + (PA, 16, 7, [8, 17, 25]), # blue/purple + ], [ # first step-fold: outside pre 90° folds for bottom + (90-PA, 1, 10, [0, 9, 18]), # pink/red + (90-PA, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange + (90-PA, 16, 7, [8, 17, 25]), # blue/purple + ], [ # second step-fold: diagonals for triangle crossing in front part + # (not 180° to avoid face identity when draw) + (179-PA, 11, 3, [0, 1, 2, 9, 10, 18, 19]), # orange/yellow + (179-PA, 6, 16, [7, 8, 17, 25]), # lightblue/blue + ], [ # third step-fold: face bottom parts, left "outside" side + (30, 1, 9, [0]), # pink/pink + (10, 1, 10, [0, 9, 18]), # pink/red + (30, 11, 2, [0, 1, 9, 10, 18, 19]), # red/orange + (90-PA, 12, 3, [0, 1, 2, 9, 10, 11, 18, 19, 20]), # yellow/lime + (60-PA, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green + ], [ # fourth step-fold: face bottom parts, right "inside" side + (35, 5, 13, [6, 7, 8, 14, 15, 16, 17, 23, 24, 25]), # green/green + (45-PA, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan + (20, 6, 14, [7, 8, 15, 16, 17, 24, 25]), # cyan/cyan + (75-PA, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue + (60, 24, 7, [8, 16, 17, 25]), # blue/blue + (45, 16, 7, [8, 17, 25]), # blue/purple + ], [ # fifth step-fold: slide into bottom and complete box + (30, 9, 1, [0]), # pink/pink + (10, 10, 1, [0, 9, 18]), # pink/red + (30, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange + (30, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green + (35, 13, 5, [6, 7, 8, 14, 15, 16, 17, 23, 24, 25]), # green/green + (45, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan + (20, 14, 6, [7, 8, 15, 16, 17, 24, 25]), # cyan/cyan + (15, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue + (60, 7, 24, [8, 16, 17, 25]), # blue/blue + (45, 7, 16, [8, 17, 25]), # blue/purple + ] + ] + +test = graphics.engine.Engine3D(points, quads, folds, title='Fold') +test.render() +test.screen.window.mainloop() diff --git a/graphics/__pycache__/engine.cpython-38.pyc b/graphics/__pycache__/engine.cpython-38.pyc index 75ee6490186569f7b96631f04b64ace9c3ed88e9..1abc82b767cde683189acd313375f84a0e3eaafa 100644 GIT binary patch delta 3262 zcmZ`*OKcm*8Q$3!-=su|;!BdFha*##L`!mPrBM{ep`Apn6(n|=mXW)mIV*}3Mar`) zSyh){TRW&*qe0y1p~xlVF(^$2ur-YkTVB|A*9r0ZL-O znfd3RnScK0w4VO%)$r?~kY9q|YY)S3{ciMOc+2mB(Ixn-FCO0gsqrkGq^IwZ{2+aj zPTiC8F?xn(pdBhnbef)}Gjx{D(d>qYo}=@?7pDt!5#|&0Jben`DGd@2Oc=VJ3C85;M)3tKO>anwf~JTSXkRDcmlIfJ$N`eAxFU8Rz@Hxrqc4Mgd%H zqrO|CLV}DU4re+}PVvut56B$KSLjr8U8422E^(Gu?3%qysyt-cMAB& z`R9=X{TUoCi#6Zx`ys(znospx`m@Iqzv|C5QIRjeXMF>}kt&i+0Oh-6OJX-{1^Vh; zl9O&uH)QB*E#3A|))tXsZp*`^XvPrQUyzZQmfQrBQWp!3$^mLVcF)6#qd_HR@ksj<|^fy?Z%BO zwNkleF6InF?1Ib%+x$T3SOMLcrFeh;Kr>(%HFMt~(IVTjOv{YN8s0g{M7`+Sw4{C-g3D6Ez+p^HlU{^oN z(y@NDHAdhhwt|34x|;E_=Wu`;VV4nvfl(HgL%4$QJi^t(+wL%PPuzAJ$lcre;kI+V zw>@IJQN$}A{!lxpJ#pO)=s0NiOAWDKfAD70R35I^BAC;g89BAVh_^t_HS%x3v>(bJvo zBp*u+@J2L9n*2x6`=|11i50$`(OsX-%0eKET@q^$R{8uuoLu8C56qBzd~e`vQ}{yp zV{pjFc(2D4ATKZG^4guvvTYVc8V4Hwu#Zf_bnk&DVTeNLfj=6=fgmrN&G35Pixk;oFn9K+qO`yet=)p%64SJy-3T_kbp@&|$C z%k#6>>UOzaTRG@ozPxMO_1bGDzZn||VbO63bxF-7JN$dGELr3q#$pTOos1w7gh&As zxZOCyDguT|UccTcYA@k{|2_6-$sIhAJdaXi5A`TFu#@%W=R@ya`6_OV!NFbu$oM?cG-py<WL;1FPy(3kIh$`NFZ?G(IvtyBkw7A2kxE1cHL-IeEJxVHH&UR6`|S5E7LFn2bYB6R7Zt8k5y1Y#fkP%aXLCVQ-B?`Asl22``WR@tO^8% zRqBMmSbvxh7}nCt=PxCv`F`@^B{VJ++aJqNk!1>@ zM%A}LCLu3owNNYUC{&~R+bFR@buctOSbiyj(zC`tPfnAs@mT5%`3ql3Exhsgzwql6 z=2IX}Cerc$PNqj`#}Gu=2~QVsARdb1wI^PSq?p%=^=h5LBeTwIld>89n^by37)mTy zgH50+?UnLhc5f_upTTG0P8ckHl2TN_X(;M`;)i#Z{2#B@r$os? zh&T;n4_%I-8KHFZ`tVSIK^+q%$~w>got~W4y}Cc>)x4g>S+5E$`~^!!&qtt6?rfHe O)?D{hzRGjM>;D5V6x&V! delta 1757 zcmY+E`)eFk6vyYzYu}GNHpyl;**x3KW}Dq4t*JJt4Q^AF8fs%(ourA|y_0>o-POCB zhK4CAG=)kLTW&!Sts4+TkRk*`#r_8s?62c5{%C$FiujZM;5oBxnjM(Wobx^R#hG)@ z^||_s{&PN`TY%@${fEorU3dNOxmEB^z+3(P?u~on6I7$|Euy#6QJUBi^bkEn$KcyR zlQae2PCC9IXp@%nWI0zT8?DJ+9axU1A2+l^ipSvMygLtr=RtQma|?nZ1n{7sWKN zUVg!~NCx?iYiux#LJVLjtCh7fwU3}lEP^^_iH&gCeVZis9XBJBz!*S?ba0=iS+M)+a>k0j2Y_zjP}ObR0j zz8v^67)R4S{l3}5!435#3>>o;dl>wXG^~}DE9&&~z~3!t{vb4?;)&QO|0^`yFo$`x zBSvz3y5rWACFfY?s-{}58Y^VVxsp+}q!OfT6erC9ba^$CHFS9n2zjwnGRyz%NRSdA z=^WkM{R95w?$06sW4jb!iIZtdSU?IpoE$fFDM;NiVu{|CdCg* zSCbMjg@eU#L#lV1WScxqP{b7KQBy>p3UGCU^L#3N#DT?b5z4QIlhath8|w6FW3_gC z!!dofkjvMOYdvfTbY>SU{(XiOsH+S1J+jpGLYY?9E&gYC$IJE?>u=q6P8`Sat%x*0 zb2VzkuD)3ipdbpgmbcWrfqOmQ$Wm&BTFJ2ZcafpaDvYd700dDbs?<(eiAq{U{!e6( zNIV=p1ve!V?I)k|8_^|_^^srs z`Pfl%iGLi6D;|N82>&5=^q5GcErH4(iPuC^ObZu#uVEqi>V8wA3MDtiumBbb3z+T? zzO~b;&a*z)gs1xAjl7T6b zl7f3>5etZS5a$sW5N{#QA?#AYDq&fK-Q4^nC>?!v&(pyG76hn=!hVbE6uP1OU? TrrysNvemJtEq#W6HL&zQNS=@F diff --git a/graphics/__pycache__/face.cpython-38.pyc b/graphics/__pycache__/face.cpython-38.pyc index 24f652892b689f241134be0a0c868b08b627e58a..04aa2b7b783e910bd2742ecc406a112dab7ee481 100644 GIT binary patch delta 64 zcmey${DYY%l$V!_0SKx;^Ce8=`Kj)tpOK%Ns-K%#sPB@WT$-DjS5mC+UzC}in476z SkXTZbpI5A3W;9uo@eBZ;Z59v! delta 61 zcmeyt{FRv}l$V!_0SJ~G?v0zs^HarMKO;XkRX-ymF*PkGGd;CP-z7h}G&eP`q*y8=@->8={Lt4%~agG6t= zfTef__O|^Rc2??YLPRaTRNZ^dse5lLca`!{rP9}<&-GjN^s&5R7$n^?rWS~K*v_0T z7lG_%w&E&e#Mz(VO+1QNP^+nTX(_2dcXC-tf+4#Jq@Kcn#?% z5fdu*_JOx(#JvtxAVut5E*(Ddrlv@3-dJI-0L(jUE6qGm9%0{Z7HW z>2%#bSewmdy(qJ3Q!&tc=O)D?MoP^@_=-#M*IrLw?8ed{CQTqF5i^KsL>=)n)8}m< dU3C_hab+<7YwKE8T90IqglxmmuNY+|^8+~kehdHr delta 552 zcmZvXO;6iE5Qed1o0NPgf}pkp5h)O=y$}g56^%;yIFti|Ln0v#AY+e{Eo(0tuN(Ey z-%zQ(_7C)kdhWfw_q0ES6FYGc2;swH?|R;6X1>?H)vCif+xUAST-iC zQ-^wh;48Semg37uCTtcP`AVtP)LtMZhUv6vfrb32^y75Vq?nB_&Fjqd5#@wAg{tyj zMLqBZ$(_C9!AIs|!yNE6VTsTpEE8y>d-<+2Zcj(@LJ**USw-$~%^zpjSu+_k06De8 z6~vD%qO3w?t{*8tvv(0vJO*8kvLsMkCQsum|LY!XG|AK^bO`H&E`bpq iW}1F2o8NomZ|3Ie49{Ob z&wtlwF!nc1_CE$D*U-{8K_rvB$6D-DCWSN}GimIK7MFaDdFBi7*=n2U{zqVP4J~~i zBxI0gEg`uSk6Fu*hBVQe(vmiMOV*@=-j*}6j=m;mp}A4ocS4ng+ilV{c`OXbwwq|F z3zGBuMj;BLFmsVJpXCN9&rMJv*&2J!S3RTT+a=#A`N*?MGYxy4(i$XDoGB9;6zNnp z$aAJ<(EW33c_ZnE%l&9``Bu^%_QNG*yWN15-_M^Xobi8{COj*e8GH762na%u9AIkZK)cnyP$<*dtd zu|U1Z#UeWmw-?whFAU8yUdb~N1fwI?m?G_-SsLW=p0nC_&r&roODk;$y|8p-lx9KP z4qNqsO1fb?3+26i-B&85CafYAaqxrFeWA*|6NQ|t|{+;DG zLIC45ptS%`yBHNB=hAp6)C2N2V^87VGx&>{iJ4W+mRNzK)+Wm8XFU`@az#51T6j<+Sx76dvye2Jg&8|pP1?Ks zd#>RtGJ+)7lTrLA=ta_1Nfu;L61%~6lzL8S_JeGr z6oW_$mqt5D_3@WR8pT>mS-%tXhT(0c66M(y6inJ(T0y+t3tMI!Zr#=No~EtC0I>B( z!(*^3JqyCbap4G;yWHWEzFy6RQ-ObOjE!pN0ca3VscC3@jR6A9ad1mHGNKEhe82>9 zJid%|f%S`e9jT$$dF*1Hfb*GNN2=&`f$*Z@PMjcY+y=n?SMHI`ThP6DOIo{T~DLdzK4v5bKb7Isl9oXkY7 z*wQ?~@*2@amOEAdj2AP6@zX3byY>Pr>X5DFb*#_kCdLkp^VuA{dC4y2n8d}oD{djCzo5E%_Nt<72lSAg zge|Rykh+eDemh_ACrGJNY?l2bHci|Nblqv=r-omW1N{_SwCMoz3j8y*#@X>|; z@!rT(-NC2 zEwOc}6x(P!ms(C=kndzp=)N$IkK!j33f89G)MbSX|m;8FkZ)oi$AGD0? zH@1oF5E-?M`1*}jV3n>ppEvqqC-2|nWjAb|E6RGGmkdT ziF5pIKF{mCDb9$|@s~rq>N(0IOV1OzK!pCS)Da>}MCgZHk=A`*-3y?i=n!5~G6a#U fIkt1ksq1x5D2j|8ziM;oT&WK2Dg|06nZzFPTP&TC5pS<+C|55Jh!+nx=pL*xlem|8(*ss!eN(Sy9JDpPfWas zOp-z#YQilb9=azc9pHfa*kmmt+CFMhs4|}na0-Fqpp;*gK>-_8#$3K0@iYoJa5Yez zM;~9C90Fhe7}T)=0*8kGK7>F8{4`)r1sYUZq=!XPRwf*iiLymmDgW1_jN}1#G*2_t zTYQ6kuvDoJtyH-Ww5pm2#;uhbA27AAXPDm?318^?>{P@$hG$3QtPwHyTzKI(UCpXO zjyht-Wy6iQ;ndq!g-f~>uCYx$2N01ttmE*QMTs=1JRMp@CfwyETF$HCp}sN`10ts7 ik(I|%_#Ru%YH-!CrfQ0|AP9&&5pxm~!0B*4KK}y`D} 0: + for i in range(self.anim_steps): + self.screen.after(int(1000/self.anim_steps), self.__fold_animate(self.folds[self.fold_index-1],False)) + self.fold_index -= 1 + + def __fold_animate(self, folds, do=True): + for subfolds in folds: + angle, axe1, axe2, points = subfolds + if do == True: + angle = angle / self.anim_steps + else: + angle = -angle / self.anim_steps + self.part_free_rotate(angle, axe1, axe2, points) + self.clear() + self.render() + self.screen.window.update_idletasks() + def writePoints(self, points): self.points = [] for point in points: self.points.append(graphics.vertex.Vertex(point)) - + def writeTriangles(self, triangles): self.triangles = [] for triangle in triangles: if len(triangle) != 4: triangle.append('gray') self.triangles.append(graphics.face.Face(triangle)) - - def __init__(self, points, triangles, width=1000, height=700, distance=6, scale=100, title='3D', background='white'): + + def __init__(self, points, triangles, folds=[], width=1000, height=700, distance=6, scale=100, title='3D', background='white'): + # folding animation parameters + self.anim_steps = 20 + self.fold_index = 0 + self.folds = folds + #object parameters self.distance = distance self.scale = scale @@ -129,6 +158,8 @@ def __init__(self, points, triangles, width=1000, height=700, distance=6, scale= self.screen.window.bind('s', self.__cameradown) self.screen.window.bind('a', self.__cameraleft) self.screen.window.bind('d', self.__cameraright) + self.screen.window.bind('n', self.__next_fold) + self.screen.window.bind('p', self.__prev_fold) # this is for editing the model self.__selected = None @@ -141,11 +172,10 @@ def __init__(self, points, triangles, width=1000, height=700, distance=6, scale= self.screen.window.bind('z', self.__selectz) self.screen.window.bind('', self.__movedown) self.screen.window.bind('', self.__moveup) - + #store coordinates self.writePoints(points) self.flattened = [] - #store faces self.writeTriangles(triangles) @@ -158,6 +188,16 @@ def rotate(self, axis, angle): for point in self.points: point.rotate(axis, angle) + def part_free_rotate(self, angle, A, B, points): + #rotate part of model around free vector (from self.points[A] to self.points[B]) + for point in [self.points[index] for index in points]: + point.free_rotate(angle, self.points[A], self.points[B]) + + def free_rotate(self, angle, A, B): + #rotate model around free vector (from self.points[A] to self.points[B]) + for point in self.points: + point.free_rotate(angle, self.points[A], self.points[B]) + def render(self): #calculate flattened coordinates (x, y) self.flattened = [] @@ -167,12 +207,16 @@ def render(self): #get coordinates to draw triangles triangles = [] for triangle in self.triangles: - avgZ = -(self.points[triangle.a].z + self.points[triangle.b].z + self.points[triangle.c].z) / 3 - triangles.append((self.flattened[triangle.a], self.flattened[triangle.b], self.flattened[triangle.c], triangle.color, avgZ)) + avgZ = (self.points[triangle.a].z + self.points[triangle.b].z + self.points[triangle.c].z) #/ 3 + triangles.append((self.flattened[triangle.a], + self.flattened[triangle.b], + self.flattened[triangle.c], triangle.color, avgZ)) #sort triangles from furthest back to closest triangles = sorted(triangles,key=lambda x: x[4]) #draw triangles - for triangle in triangles: + for triangle in triangles[::-1]: self.screen.createTriangle(triangle[0:3], triangle[3]) + + diff --git a/graphics/vertex.py b/graphics/vertex.py index 66dc6be..69bdbbe 100644 --- a/graphics/vertex.py +++ b/graphics/vertex.py @@ -17,7 +17,7 @@ def flatten(self, scale, distance): def rotate(self, axis, angle): #rotate point around axis angle = angle / 450 * 180 / math.pi - sqrt2 = math.sqrt(2) + #sqrt2 = math.sqrt(2) if axis == 'z': #rotate aroud Z axis newX = self.x * math.cos(angle) - self.y * math.sin(angle) @@ -49,3 +49,30 @@ def move(self, axis, value): else: raise ValueError('Invalid movement axis') + def free_rotate(self, phi, A, B): + """Compute new coordinates for self as image of itself by the rotation R + of phi degrees around the AB vector.""" + # Define conjugate and * for Quaternions (4-tuples) + class Quaternion(tuple): + def conj(self): + return self[0], *[-self[i] for i in range(1,4)] + def __mul__(self, q2): + w1, x1, y1, z1 = self + w2, x2, y2, z2 = q2 + w = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2 + x = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2 + y = w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2 + z = w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2 + return w, x, y, z + # Compute "vector to rotate" quaternion using vector Aself. + p = Quaternion((0, self.x-A.x, self.y-A.y, self.z-A.z)) + # Compute "rotation" quaternion using vector of AB. + ABx, ABy, ABz = B.x-A.x, B.y-A.y, B.z-A.z + nAB = math.sqrt(ABx**2 + ABy**2 + ABz**2) + half_phi_rad = phi / 360 * math.pi + S = math.sin(half_phi_rad) + r = Quaternion((math.cos(half_phi_rad), S*ABx/nAB, S*ABy/nAB, S*ABz/nAB)) + # Calculate "image" quaternion using p and r conjugation (q = r⋅p⋅r^-1). + qw, qx, qy, qz = Quaternion(r * p) * r.conj() + # Get Q coordinates. + self.x, self.y, self.z = qx+A.x, qy+A.y, qz+A.z From 495cc7405d89fa9188845370d070b53f2e6feab4 Mon Sep 17 00:00:00 2001 From: MiQ75 Date: Wed, 27 Jan 2021 23:04:27 +0100 Subject: [PATCH 2/2] Common file input method for examples Reduce verbosity of code with more pythonic code and minor optimisations Vertices replace points, polygons replace triangles in code and pyramid replace cube in examples --- __pycache__/graphics.cpython-37.pyc | Bin 3177 -> 0 bytes coords/{GalleonT.txt => GalleonP.txt} | 0 coords/SharkP.txt | 734 +++++++++++++++++++ coords/SharkT.txt | 734 ------------------- cubeExample.py | 21 - dragExample.py | 36 +- foldExample.py | 156 ++-- galleonExample.py | 37 +- graphics/__pycache__/__init__.cpython-37.pyc | Bin 158 -> 0 bytes graphics/__pycache__/engine.cpython-37.pyc | Bin 2613 -> 0 bytes graphics/__pycache__/engine.cpython-38.pyc | Bin 8960 -> 0 bytes graphics/__pycache__/face.cpython-37.pyc | Bin 479 -> 0 bytes graphics/__pycache__/face.cpython-38.pyc | Bin 504 -> 0 bytes graphics/__pycache__/screen.cpython-37.pyc | Bin 1264 -> 0 bytes graphics/__pycache__/screen.cpython-38.pyc | Bin 1682 -> 0 bytes graphics/__pycache__/vertex.cpython-37.pyc | Bin 1288 -> 0 bytes graphics/__pycache__/vertex.cpython-38.pyc | Bin 3114 -> 0 bytes graphics/engine.py | 260 ++++--- graphics/face.py | 8 - graphics/screen.py | 15 +- graphics/{vertex.py => structures.py} | 20 +- pyramidExample.py | 19 + sharkExample.py | 37 +- 23 files changed, 1011 insertions(+), 1066 deletions(-) delete mode 100644 __pycache__/graphics.cpython-37.pyc rename coords/{GalleonT.txt => GalleonP.txt} (100%) create mode 100644 coords/SharkP.txt delete mode 100644 coords/SharkT.txt delete mode 100755 cubeExample.py mode change 100644 => 100755 dragExample.py mode change 100644 => 100755 galleonExample.py delete mode 100644 graphics/__pycache__/__init__.cpython-37.pyc delete mode 100644 graphics/__pycache__/engine.cpython-37.pyc delete mode 100644 graphics/__pycache__/engine.cpython-38.pyc delete mode 100644 graphics/__pycache__/face.cpython-37.pyc delete mode 100644 graphics/__pycache__/face.cpython-38.pyc delete mode 100644 graphics/__pycache__/screen.cpython-37.pyc delete mode 100644 graphics/__pycache__/screen.cpython-38.pyc delete mode 100644 graphics/__pycache__/vertex.cpython-37.pyc delete mode 100644 graphics/__pycache__/vertex.cpython-38.pyc delete mode 100644 graphics/face.py rename graphics/{vertex.py => structures.py} (85%) create mode 100755 pyramidExample.py mode change 100644 => 100755 sharkExample.py diff --git a/__pycache__/graphics.cpython-37.pyc b/__pycache__/graphics.cpython-37.pyc deleted file mode 100644 index b32dfca795a9fb381ed586c69907175004ea3252..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3177 zcmd5;&2Jnv6t_JeJK20RE!!q(N};7d7esXHrP(1(Viu;S0$hv$}l@J+>4Q4jvoA z1C(qT5HX)i2JI>7NcRQzEm@J?3+CH$L{?Eda#W6?cICL7KwXg+BgR?5(H<=Xa7;2{W62kH z7ky`CGtQ&BrJcQ4=9}8xjN;~IuElz@KCWnE$^&Rm##tV;!$><>7$lLdOESf zMlf7Zk=+$c&VFU;3aWqZ&Hs=^Dw~h;U5O9m^NUfom8YHg&OyGJwwG1fio!gbZ>pfP z8HXprT<1W0jYiy#^G1UVp3zc_yX7mYe2ib^RpIi(ivx4b4fI1;%sj-x&_=(YQEKe)K6I>_wfWY|rha}wq^hs7XspBJpTLd2yd_wRk!EFLM z1n1dZrKL`>>luE}vAg=N**(SBSyua=Jn+_2x@SH5f6VS0S>qJD`T;=p-q8Dq8wbVklS6n5KPG18 zWj?cJO-5`X)>2Mvi7AF2*0O4BiaqCD$LJw0q8AzNt$HpPbT)*^erK4gJK92eGRf{F z_n3S%V2KW;=KGo-XnyEdJ7vO&RGzR`fAIR{O;fj86}dEEYNj%NZ0FnAq5e7 zs3ylUWKBXKN9e(!DD9hIFP5|wB+07HNKOXw8jr7hU=Rl z+ydx2aLQP;U$g$75SpwjP^|syv=bz^8WNl6;d0Rvg?(i9wKKWG_H!~1##?Z5x|SG+ zo882xWU}(1Wo-&nS~NQmR{6__i3#Hj4Nq!Nqa!rrKBpL`Kq5Ny`|C#Ox&h8dQ4oOBA;k_jAE=-;Ep*%8CEQ*Z_sIM z4XVEy$ghQGZy^b`*JW`3JDQEc4sQ&(R#96$i!ok9 zS>SVG5_h7*3um^wRJRrJqv#5y=m;x1_xS$>sz&LK)eg3!MnhK{jqOzKCM1tF8aul| zQjVx;npP+HjNo$u`kC?{X+!EE!HMGGNW}%jgh9w WyQKc6?`UtK+}wRSUFIN6ihlt=GKsMO diff --git a/coords/GalleonT.txt b/coords/GalleonP.txt similarity index 100% rename from coords/GalleonT.txt rename to coords/GalleonP.txt diff --git a/coords/SharkP.txt b/coords/SharkP.txt new file mode 100644 index 0000000..3d53ede --- /dev/null +++ b/coords/SharkP.txt @@ -0,0 +1,734 @@ +3 0 1 2 cyan +3 3 2 4 cyan +3 5 6 7 cyan +3 8 9 10 cyan +3 11 12 9 cyan +3 13 14 15 cyan +3 16 17 14 cyan +3 18 19 20 cyan +3 21 22 23 cyan +3 24 25 21 cyan +3 26 27 24 cyan +3 28 29 26 cyan +3 30 31 28 cyan +3 32 33 30 cyan +3 34 35 32 cyan +3 36 37 34 cyan +3 38 39 36 cyan +3 40 41 38 cyan +3 42 43 44 cyan +3 44 45 46 cyan +3 46 47 48 cyan +3 48 49 50 cyan +3 50 51 52 cyan +3 52 53 54 cyan +3 54 55 56 cyan +3 56 57 58 cyan +3 58 59 60 cyan +3 60 61 7 cyan +3 62 63 64 cyan +3 64 65 66 cyan +3 66 67 68 cyan +3 68 69 70 cyan +3 70 71 72 cyan +3 72 73 74 cyan +3 75 76 77 cyan +3 78 79 75 cyan +3 80 81 78 cyan +3 82 83 80 cyan +3 74 84 82 cyan +3 85 86 87 cyan +3 88 89 85 cyan +3 90 91 88 cyan +3 92 93 90 cyan +3 94 95 92 cyan +3 96 97 94 cyan +3 98 99 96 cyan +3 100 101 102 cyan +3 102 103 104 cyan +3 104 105 106 cyan +3 106 107 108 cyan +3 108 109 110 cyan +3 110 111 112 cyan +3 112 113 114 cyan +3 115 116 117 cyan +3 115 117 118 cyan +3 118 119 115 cyan +3 120 117 116 cyan +3 120 118 117 cyan +3 120 119 118 cyan +3 121 122 116 cyan +3 121 123 122 cyan +3 121 124 123 cyan +3 121 125 124 cyan +3 116 122 126 cyan +3 127 125 121 cyan +3 127 125 121 cyan +3 127 128 125 cyan +3 116 129 121 cyan +3 129 130 121 cyan +3 130 131 121 cyan +3 131 132 121 cyan +3 133 129 116 cyan +3 134 132 121 cyan +3 121 132 134 cyan +3 132 128 134 cyan +3 135 136 137 cyan +3 137 136 138 cyan +3 139 140 135 cyan +3 136 135 141 cyan +3 141 135 140 cyan +3 138 142 139 cyan +3 143 138 136 cyan +3 142 138 143 cyan +3 144 145 146 cyan +3 144 146 147 cyan +3 148 144 147 cyan +3 149 148 147 cyan +3 149 147 150 cyan +3 146 145 151 cyan +3 151 145 152 cyan +3 151 152 153 cyan +3 151 153 150 cyan +3 153 149 150 cyan +3 154 155 148 cyan +3 156 157 158 cyan +3 159 157 156 cyan +3 160 161 162 cyan +3 163 160 162 cyan +3 163 162 164 cyan +3 163 164 165 cyan +3 159 163 165 cyan +3 157 161 160 cyan +3 166 161 157 cyan +3 167 166 157 cyan +3 159 167 157 cyan +3 159 165 167 cyan +3 164 168 169 cyan +3 170 146 160 cyan +3 170 160 171 cyan +3 172 146 151 cyan +3 172 151 173 cyan +3 147 174 175 cyan +3 147 175 150 cyan +3 174 176 177 cyan +3 174 177 175 cyan +3 176 178 179 cyan +3 176 179 177 cyan +3 178 180 181 cyan +3 178 181 179 cyan +3 180 182 183 cyan +3 180 183 181 cyan +3 182 163 159 cyan +3 182 159 183 cyan +3 160 184 185 cyan +3 160 185 157 cyan +3 157 185 186 cyan +3 157 186 158 cyan +3 183 159 156 cyan +3 183 156 187 cyan +3 181 183 187 cyan +3 181 187 188 cyan +3 179 181 188 cyan +3 179 188 189 cyan +3 177 179 189 cyan +3 177 189 190 cyan +3 175 177 190 cyan +3 175 190 191 cyan +3 150 175 191 cyan +3 150 191 192 cyan +3 151 150 192 cyan +3 151 192 193 cyan +3 173 151 193 cyan +3 173 193 194 cyan +3 170 195 147 cyan +3 170 147 146 cyan +3 195 196 174 cyan +3 195 174 147 cyan +3 196 197 176 cyan +3 196 176 174 cyan +3 197 198 178 cyan +3 197 178 176 cyan +3 198 199 180 cyan +3 198 180 178 cyan +3 199 200 182 cyan +3 199 182 180 cyan +3 200 201 163 cyan +3 200 163 182 cyan +3 201 171 160 cyan +3 201 160 163 cyan +3 201 195 170 cyan +3 201 170 171 cyan +3 196 195 201 cyan +3 196 201 200 cyan +3 197 196 200 cyan +3 197 200 199 cyan +3 198 197 199 cyan +3 202 203 204 cyan +3 204 203 205 cyan +3 203 202 206 cyan +3 207 205 203 cyan +3 208 209 186 cyan +3 158 186 209 cyan +3 158 209 210 cyan +3 156 158 210 cyan +3 156 210 211 cyan +3 187 156 211 cyan +3 187 211 212 cyan +3 213 209 214 cyan +3 213 214 215 cyan +3 216 213 215 cyan +3 216 215 217 cyan +3 212 216 217 cyan +3 212 217 218 cyan +3 219 214 208 cyan +3 219 208 220 cyan +3 221 219 220 cyan +3 221 220 222 cyan +3 218 221 222 cyan +3 218 222 223 cyan +3 224 208 225 cyan +3 224 225 226 cyan +3 224 226 227 cyan +3 224 227 228 cyan +3 228 227 229 cyan +3 228 229 223 cyan +3 230 225 206 cyan +3 230 206 231 cyan +3 232 233 234 cyan +3 232 234 229 cyan +3 230 231 233 cyan +3 230 233 232 cyan +3 187 229 234 cyan +3 187 223 229 cyan +3 187 218 223 cyan +3 187 212 218 cyan +3 206 208 186 cyan +3 206 225 208 cyan +3 194 235 236 cyan +3 237 235 194 cyan +3 237 194 193 cyan +3 238 237 193 cyan +3 238 193 192 cyan +3 239 238 192 cyan +3 239 192 191 cyan +3 240 241 235 cyan +3 240 235 242 cyan +3 243 240 242 cyan +3 243 242 244 cyan +3 245 243 244 cyan +3 245 244 239 cyan +3 246 236 241 cyan +3 246 241 247 cyan +3 248 246 247 cyan +3 248 247 249 cyan +3 250 248 249 cyan +3 250 249 245 cyan +3 251 252 236 cyan +3 251 236 253 cyan +3 254 255 251 cyan +3 254 251 253 cyan +3 250 256 255 cyan +3 250 255 254 cyan +3 257 258 252 cyan +3 257 252 259 cyan +3 256 260 261 cyan +3 256 261 262 cyan +3 262 261 257 cyan +3 262 257 259 cyan +3 260 256 191 cyan +3 256 250 191 cyan +3 250 245 191 cyan +3 245 239 191 cyan +3 194 236 258 cyan +3 236 252 258 cyan +3 204 205 263 cyan +3 204 263 264 cyan +3 265 204 264 cyan +3 265 264 266 cyan +3 267 265 266 cyan +3 267 266 268 cyan +3 140 267 268 cyan +3 140 268 141 cyan +3 269 142 143 cyan +3 269 143 270 cyan +3 271 269 270 cyan +3 271 270 272 cyan +3 273 271 272 cyan +3 273 272 274 cyan +3 275 273 274 cyan +3 275 274 276 cyan +3 277 278 271 cyan +3 277 271 273 cyan +3 278 260 269 cyan +3 278 269 271 cyan +3 260 279 142 cyan +3 260 142 269 cyan +3 279 280 139 cyan +3 279 139 142 cyan +3 280 281 140 cyan +3 280 140 139 cyan +3 281 234 267 cyan +3 281 267 140 cyan +3 234 282 265 cyan +3 234 265 267 cyan +3 282 202 204 cyan +3 282 204 265 cyan +3 188 187 234 cyan +3 188 234 281 cyan +3 189 188 281 cyan +3 189 281 280 cyan +3 190 189 280 cyan +3 190 280 279 cyan +3 191 190 279 cyan +3 191 279 260 cyan +3 235 241 236 cyan +3 214 209 208 cyan +3 273 283 277 cyan +3 275 283 273 cyan +3 258 277 283 cyan +3 283 275 284 cyan +3 285 286 287 cyan +3 288 289 290 cyan +3 291 288 290 cyan +3 291 290 292 cyan +3 293 294 295 cyan +3 296 297 298 cyan +3 299 296 298 cyan +3 299 298 300 cyan +3 301 302 303 cyan +3 301 303 304 cyan +3 305 301 304 cyan +3 276 274 306 cyan +3 276 306 307 cyan +3 274 272 308 cyan +3 274 308 306 cyan +3 272 270 309 cyan +3 272 309 308 cyan +3 270 143 310 cyan +3 270 310 309 cyan +3 143 136 311 cyan +3 143 311 310 cyan +3 136 141 312 cyan +3 136 312 311 cyan +3 141 268 313 cyan +3 141 313 312 cyan +3 268 266 314 cyan +3 268 314 313 cyan +3 266 264 315 cyan +3 266 315 314 cyan +3 264 263 316 cyan +3 264 316 315 cyan +3 307 306 317 cyan +3 307 317 318 cyan +3 306 308 319 cyan +3 306 319 317 cyan +3 308 309 320 cyan +3 308 320 319 cyan +3 309 310 321 cyan +3 309 321 320 cyan +3 310 311 322 cyan +3 310 322 321 cyan +3 311 312 323 cyan +3 311 323 322 cyan +3 312 313 324 cyan +3 312 324 323 cyan +3 313 314 325 cyan +3 313 325 324 cyan +3 314 315 326 cyan +3 314 326 325 cyan +3 315 316 327 cyan +3 315 327 326 cyan +3 326 327 328 cyan +3 326 328 329 cyan +3 325 326 329 cyan +3 325 329 330 cyan +3 324 325 330 cyan +3 324 330 331 cyan +3 323 324 331 cyan +3 323 331 332 cyan +3 322 323 332 cyan +3 322 332 333 cyan +3 321 322 333 cyan +3 321 333 334 cyan +3 320 321 334 cyan +3 320 334 335 cyan +3 319 320 335 cyan +3 319 335 336 cyan +3 317 319 336 cyan +3 317 336 337 cyan +3 318 317 337 cyan +3 318 337 338 cyan +3 339 340 129 cyan +3 339 129 133 cyan +3 340 341 130 cyan +3 340 130 129 cyan +3 341 342 131 cyan +3 341 131 130 cyan +3 342 343 132 cyan +3 342 132 131 cyan +3 343 302 128 cyan +3 343 128 132 cyan +3 302 344 125 cyan +3 302 125 128 cyan +3 344 345 124 cyan +3 344 124 125 cyan +3 345 346 123 cyan +3 345 123 124 cyan +3 346 347 122 cyan +3 346 122 123 cyan +3 347 348 126 cyan +3 347 126 122 cyan +3 329 328 348 cyan +3 329 348 347 cyan +3 330 329 347 cyan +3 330 347 346 cyan +3 331 330 346 cyan +3 331 346 345 cyan +3 332 331 345 cyan +3 332 345 344 cyan +3 333 332 344 cyan +3 333 344 302 cyan +3 334 333 302 cyan +3 334 302 343 cyan +3 335 334 343 cyan +3 335 343 342 cyan +3 336 335 342 cyan +3 336 342 341 cyan +3 337 336 341 cyan +3 337 341 340 cyan +3 338 337 340 cyan +3 338 340 339 cyan +3 116 126 349 cyan +3 116 349 120 cyan +3 350 133 116 cyan +3 115 350 116 cyan +3 351 352 353 cyan +3 351 353 354 cyan +3 352 172 173 cyan +3 352 173 353 cyan +3 184 355 356 cyan +3 184 356 185 cyan +3 355 357 358 cyan +3 355 358 356 cyan +3 357 359 360 cyan +3 357 360 358 cyan +3 359 351 354 cyan +3 359 354 360 cyan +3 360 354 361 cyan +3 360 361 362 cyan +3 358 360 362 cyan +3 358 362 363 cyan +3 356 358 363 cyan +3 356 363 364 cyan +3 185 356 364 cyan +3 185 364 186 cyan +3 353 173 194 cyan +3 353 194 365 cyan +3 354 353 365 cyan +3 354 365 361 cyan +3 366 367 352 cyan +3 366 352 351 cyan +3 367 40 172 cyan +3 367 172 352 cyan +3 7 368 355 cyan +3 7 355 184 cyan +3 368 369 357 cyan +3 368 357 355 cyan +3 369 370 359 cyan +3 369 359 357 cyan +3 370 366 351 cyan +3 370 351 359 cyan +3 367 366 370 cyan +3 367 370 369 cyan +3 367 369 368 cyan +3 371 372 373 cyan +3 206 373 372 cyan +3 205 372 371 cyan +3 374 375 376 cyan +3 374 376 377 cyan +3 186 364 373 cyan +3 186 373 206 cyan +3 378 377 376 cyan +3 378 376 379 cyan +3 371 378 379 cyan +3 371 379 380 cyan +3 205 371 380 cyan +3 205 380 263 cyan +3 381 275 276 cyan +3 381 276 382 cyan +3 374 381 382 cyan +3 374 382 375 cyan +3 383 384 381 cyan +3 383 381 374 cyan +3 373 385 378 cyan +3 373 378 371 cyan +3 385 386 377 cyan +3 385 377 378 cyan +3 386 383 374 cyan +3 386 374 377 cyan +3 362 361 383 cyan +3 362 383 386 cyan +3 363 362 386 cyan +3 363 386 385 cyan +3 364 363 385 cyan +3 364 385 373 cyan +3 365 194 258 cyan +3 365 258 384 cyan +3 361 365 384 cyan +3 361 384 383 cyan +3 384 387 381 cyan +3 381 387 275 cyan +3 387 384 258 cyan +3 98 172 23 cyan +3 114 42 184 cyan +3 375 382 388 cyan +3 375 388 389 cyan +3 382 276 307 cyan +3 382 307 388 cyan +3 263 380 390 cyan +3 263 390 316 cyan +3 380 379 391 cyan +3 380 391 390 cyan +3 379 376 392 cyan +3 379 392 391 cyan +3 376 375 389 cyan +3 376 389 392 cyan +3 389 388 393 cyan +3 389 393 394 cyan +3 388 307 318 cyan +3 388 318 393 cyan +3 316 390 395 cyan +3 316 395 327 cyan +3 390 391 396 cyan +3 390 396 395 cyan +3 391 392 397 cyan +3 391 397 396 cyan +3 392 389 394 cyan +3 392 394 397 cyan +3 397 394 398 cyan +3 397 398 399 cyan +3 396 397 399 cyan +3 396 399 400 cyan +3 395 396 400 cyan +3 395 400 401 cyan +3 327 395 401 cyan +3 327 401 328 cyan +3 393 318 338 cyan +3 393 338 402 cyan +3 394 393 402 cyan +3 394 402 398 cyan +3 403 404 350 cyan +3 403 350 115 cyan +3 404 339 133 cyan +3 404 133 350 cyan +3 348 405 349 cyan +3 348 349 126 cyan +3 405 406 120 cyan +3 405 120 349 cyan +3 406 407 119 cyan +3 406 119 120 cyan +3 407 403 115 cyan +3 407 115 119 cyan +3 399 398 403 cyan +3 399 403 407 cyan +3 400 399 407 cyan +3 400 407 406 cyan +3 401 400 406 cyan +3 401 406 405 cyan +3 328 401 405 cyan +3 328 405 348 cyan +3 402 338 339 cyan +3 402 339 404 cyan +3 398 402 404 cyan +3 398 404 403 cyan +3 127 408 128 cyan +3 127 409 408 cyan +3 127 410 409 cyan +3 127 411 410 cyan +3 127 412 411 cyan +3 127 413 412 cyan +3 127 414 413 cyan +3 127 121 414 cyan +3 128 408 134 cyan +3 408 409 134 cyan +3 409 410 134 cyan +3 410 411 134 cyan +3 411 412 134 cyan +3 412 413 134 cyan +3 413 414 134 cyan +3 414 121 134 cyan +3 415 139 135 cyan +3 416 415 135 cyan +3 417 416 135 cyan +3 418 417 135 cyan +3 419 418 135 cyan +3 420 419 135 cyan +3 421 420 135 cyan +3 422 421 135 cyan +3 423 422 135 cyan +3 424 423 135 cyan +3 135 137 424 cyan +3 138 139 415 cyan +3 138 415 416 cyan +3 138 416 417 cyan +3 138 417 418 cyan +3 138 418 419 cyan +3 138 419 420 cyan +3 138 420 421 cyan +3 138 421 422 cyan +3 138 422 423 cyan +3 138 423 424 cyan +3 424 137 138 cyan +3 155 425 144 cyan +3 425 426 144 cyan +3 426 427 145 cyan +3 427 428 145 cyan +3 428 429 152 cyan +3 429 430 152 cyan +3 430 431 153 cyan +3 431 432 153 cyan +3 432 433 149 cyan +3 433 434 149 cyan +3 434 154 148 cyan +3 144 426 145 cyan +3 145 428 152 cyan +3 152 430 153 cyan +3 153 432 149 cyan +3 149 434 148 cyan +3 155 144 148 cyan +3 162 435 168 cyan +3 162 436 435 cyan +3 161 437 436 cyan +3 161 438 437 cyan +3 166 439 438 cyan +3 166 440 439 cyan +3 167 441 440 cyan +3 167 442 441 cyan +3 165 443 442 cyan +3 165 444 443 cyan +3 164 169 444 cyan +3 161 436 162 cyan +3 166 438 161 cyan +3 167 440 166 cyan +3 165 442 167 cyan +3 164 444 165 cyan +3 164 162 168 cyan +3 160 445 446 cyan +3 146 445 160 cyan +3 146 447 445 cyan +3 146 172 447 cyan +3 160 446 184 cyan +3 40 367 368 cyan +3 40 368 7 cyan +3 445 447 446 cyan +3 40 7 184 cyan +3 40 184 172 cyan +3 184 446 447 cyan +3 184 447 172 cyan +3 233 231 202 cyan +3 233 202 282 cyan +3 233 282 234 cyan +3 227 232 229 cyan +3 226 225 230 cyan +3 226 230 232 cyan +3 226 232 227 cyan +3 222 220 224 cyan +3 222 224 228 cyan +3 220 208 224 cyan +3 217 221 218 cyan +3 217 215 219 cyan +3 217 219 221 cyan +3 215 214 219 cyan +3 210 209 213 cyan +3 222 228 223 cyan +3 211 216 212 cyan +3 211 210 213 cyan +3 211 213 216 cyan +3 231 206 202 cyan +3 278 277 257 cyan +3 278 257 261 cyan +3 260 278 261 cyan +3 256 262 255 cyan +3 259 252 251 cyan +3 255 262 259 cyan +3 255 259 251 cyan +3 254 253 246 cyan +3 254 246 248 cyan +3 253 236 246 cyan +3 245 249 243 cyan +3 249 247 240 cyan +3 249 240 243 cyan +3 247 241 240 cyan +3 242 235 237 cyan +3 250 254 248 cyan +3 239 244 238 cyan +3 244 242 237 cyan +3 244 237 238 cyan +3 277 258 257 cyan +3 448 449 372 cyan +3 449 206 372 cyan +3 450 448 372 cyan +3 451 450 372 cyan +3 452 451 372 cyan +3 453 452 372 cyan +3 454 453 372 cyan +3 455 454 372 cyan +3 456 455 372 cyan +3 457 456 372 cyan +3 372 205 207 cyan +3 372 207 457 cyan +3 457 207 203 cyan +3 203 456 457 cyan +3 203 455 456 cyan +3 203 454 455 cyan +3 203 453 454 cyan +3 203 452 453 cyan +3 203 451 452 cyan +3 203 450 451 cyan +3 203 448 450 cyan +3 203 449 448 cyan +3 203 206 449 cyan +3 430 429 428 cyan +3 430 428 427 cyan +3 430 427 426 cyan +3 430 426 425 cyan +3 430 425 155 cyan +3 430 155 154 cyan +3 430 154 434 cyan +3 430 434 433 cyan +3 430 433 432 cyan +3 430 432 431 cyan +3 441 442 443 cyan +3 441 443 444 cyan +3 441 444 169 cyan +3 441 169 168 cyan +3 441 168 435 cyan +3 441 435 436 cyan +3 441 436 437 cyan +3 441 437 438 cyan +3 441 438 439 cyan +3 441 439 440 cyan +3 458 284 387 cyan +3 284 275 387 cyan +3 387 459 458 cyan +3 387 460 459 cyan +3 387 461 460 cyan +3 387 462 461 cyan +3 387 463 462 cyan +3 387 464 463 cyan +3 387 465 464 cyan +3 387 466 465 cyan +3 387 467 466 cyan +3 387 258 467 cyan +3 283 284 458 cyan +3 458 459 283 cyan +3 459 460 283 cyan +3 460 461 283 cyan +3 461 462 283 cyan +3 462 463 283 cyan +3 463 464 283 cyan +3 464 465 283 cyan +3 465 466 283 cyan +3 466 467 283 cyan +3 467 258 283 cyan diff --git a/coords/SharkT.txt b/coords/SharkT.txt deleted file mode 100644 index a852979..0000000 --- a/coords/SharkT.txt +++ /dev/null @@ -1,734 +0,0 @@ -3 0 1 2 -3 3 2 4 -3 5 6 7 -3 8 9 10 -3 11 12 9 -3 13 14 15 -3 16 17 14 -3 18 19 20 -3 21 22 23 -3 24 25 21 -3 26 27 24 -3 28 29 26 -3 30 31 28 -3 32 33 30 -3 34 35 32 -3 36 37 34 -3 38 39 36 -3 40 41 38 -3 42 43 44 -3 44 45 46 -3 46 47 48 -3 48 49 50 -3 50 51 52 -3 52 53 54 -3 54 55 56 -3 56 57 58 -3 58 59 60 -3 60 61 7 -3 62 63 64 -3 64 65 66 -3 66 67 68 -3 68 69 70 -3 70 71 72 -3 72 73 74 -3 75 76 77 -3 78 79 75 -3 80 81 78 -3 82 83 80 -3 74 84 82 -3 85 86 87 -3 88 89 85 -3 90 91 88 -3 92 93 90 -3 94 95 92 -3 96 97 94 -3 98 99 96 -3 100 101 102 -3 102 103 104 -3 104 105 106 -3 106 107 108 -3 108 109 110 -3 110 111 112 -3 112 113 114 -3 115 116 117 -3 115 117 118 -3 118 119 115 -3 120 117 116 -3 120 118 117 -3 120 119 118 -3 121 122 116 -3 121 123 122 -3 121 124 123 -3 121 125 124 -3 116 122 126 -3 127 125 121 -3 127 125 121 -3 127 128 125 -3 116 129 121 -3 129 130 121 -3 130 131 121 -3 131 132 121 -3 133 129 116 -3 134 132 121 -3 121 132 134 -3 132 128 134 -3 135 136 137 -3 137 136 138 -3 139 140 135 -3 136 135 141 -3 141 135 140 -3 138 142 139 -3 143 138 136 -3 142 138 143 -3 144 145 146 -3 144 146 147 -3 148 144 147 -3 149 148 147 -3 149 147 150 -3 146 145 151 -3 151 145 152 -3 151 152 153 -3 151 153 150 -3 153 149 150 -3 154 155 148 -3 156 157 158 -3 159 157 156 -3 160 161 162 -3 163 160 162 -3 163 162 164 -3 163 164 165 -3 159 163 165 -3 157 161 160 -3 166 161 157 -3 167 166 157 -3 159 167 157 -3 159 165 167 -3 164 168 169 -3 170 146 160 -3 170 160 171 -3 172 146 151 -3 172 151 173 -3 147 174 175 -3 147 175 150 -3 174 176 177 -3 174 177 175 -3 176 178 179 -3 176 179 177 -3 178 180 181 -3 178 181 179 -3 180 182 183 -3 180 183 181 -3 182 163 159 -3 182 159 183 -3 160 184 185 -3 160 185 157 -3 157 185 186 -3 157 186 158 -3 183 159 156 -3 183 156 187 -3 181 183 187 -3 181 187 188 -3 179 181 188 -3 179 188 189 -3 177 179 189 -3 177 189 190 -3 175 177 190 -3 175 190 191 -3 150 175 191 -3 150 191 192 -3 151 150 192 -3 151 192 193 -3 173 151 193 -3 173 193 194 -3 170 195 147 -3 170 147 146 -3 195 196 174 -3 195 174 147 -3 196 197 176 -3 196 176 174 -3 197 198 178 -3 197 178 176 -3 198 199 180 -3 198 180 178 -3 199 200 182 -3 199 182 180 -3 200 201 163 -3 200 163 182 -3 201 171 160 -3 201 160 163 -3 201 195 170 -3 201 170 171 -3 196 195 201 -3 196 201 200 -3 197 196 200 -3 197 200 199 -3 198 197 199 -3 202 203 204 -3 204 203 205 -3 203 202 206 -3 207 205 203 -3 208 209 186 -3 158 186 209 -3 158 209 210 -3 156 158 210 -3 156 210 211 -3 187 156 211 -3 187 211 212 -3 213 209 214 -3 213 214 215 -3 216 213 215 -3 216 215 217 -3 212 216 217 -3 212 217 218 -3 219 214 208 -3 219 208 220 -3 221 219 220 -3 221 220 222 -3 218 221 222 -3 218 222 223 -3 224 208 225 -3 224 225 226 -3 224 226 227 -3 224 227 228 -3 228 227 229 -3 228 229 223 -3 230 225 206 -3 230 206 231 -3 232 233 234 -3 232 234 229 -3 230 231 233 -3 230 233 232 -3 187 229 234 -3 187 223 229 -3 187 218 223 -3 187 212 218 -3 206 208 186 -3 206 225 208 -3 194 235 236 -3 237 235 194 -3 237 194 193 -3 238 237 193 -3 238 193 192 -3 239 238 192 -3 239 192 191 -3 240 241 235 -3 240 235 242 -3 243 240 242 -3 243 242 244 -3 245 243 244 -3 245 244 239 -3 246 236 241 -3 246 241 247 -3 248 246 247 -3 248 247 249 -3 250 248 249 -3 250 249 245 -3 251 252 236 -3 251 236 253 -3 254 255 251 -3 254 251 253 -3 250 256 255 -3 250 255 254 -3 257 258 252 -3 257 252 259 -3 256 260 261 -3 256 261 262 -3 262 261 257 -3 262 257 259 -3 260 256 191 -3 256 250 191 -3 250 245 191 -3 245 239 191 -3 194 236 258 -3 236 252 258 -3 204 205 263 -3 204 263 264 -3 265 204 264 -3 265 264 266 -3 267 265 266 -3 267 266 268 -3 140 267 268 -3 140 268 141 -3 269 142 143 -3 269 143 270 -3 271 269 270 -3 271 270 272 -3 273 271 272 -3 273 272 274 -3 275 273 274 -3 275 274 276 -3 277 278 271 -3 277 271 273 -3 278 260 269 -3 278 269 271 -3 260 279 142 -3 260 142 269 -3 279 280 139 -3 279 139 142 -3 280 281 140 -3 280 140 139 -3 281 234 267 -3 281 267 140 -3 234 282 265 -3 234 265 267 -3 282 202 204 -3 282 204 265 -3 188 187 234 -3 188 234 281 -3 189 188 281 -3 189 281 280 -3 190 189 280 -3 190 280 279 -3 191 190 279 -3 191 279 260 -3 235 241 236 -3 214 209 208 -3 273 283 277 -3 275 283 273 -3 258 277 283 -3 283 275 284 -3 285 286 287 -3 288 289 290 -3 291 288 290 -3 291 290 292 -3 293 294 295 -3 296 297 298 -3 299 296 298 -3 299 298 300 -3 301 302 303 -3 301 303 304 -3 305 301 304 -3 276 274 306 -3 276 306 307 -3 274 272 308 -3 274 308 306 -3 272 270 309 -3 272 309 308 -3 270 143 310 -3 270 310 309 -3 143 136 311 -3 143 311 310 -3 136 141 312 -3 136 312 311 -3 141 268 313 -3 141 313 312 -3 268 266 314 -3 268 314 313 -3 266 264 315 -3 266 315 314 -3 264 263 316 -3 264 316 315 -3 307 306 317 -3 307 317 318 -3 306 308 319 -3 306 319 317 -3 308 309 320 -3 308 320 319 -3 309 310 321 -3 309 321 320 -3 310 311 322 -3 310 322 321 -3 311 312 323 -3 311 323 322 -3 312 313 324 -3 312 324 323 -3 313 314 325 -3 313 325 324 -3 314 315 326 -3 314 326 325 -3 315 316 327 -3 315 327 326 -3 326 327 328 -3 326 328 329 -3 325 326 329 -3 325 329 330 -3 324 325 330 -3 324 330 331 -3 323 324 331 -3 323 331 332 -3 322 323 332 -3 322 332 333 -3 321 322 333 -3 321 333 334 -3 320 321 334 -3 320 334 335 -3 319 320 335 -3 319 335 336 -3 317 319 336 -3 317 336 337 -3 318 317 337 -3 318 337 338 -3 339 340 129 -3 339 129 133 -3 340 341 130 -3 340 130 129 -3 341 342 131 -3 341 131 130 -3 342 343 132 -3 342 132 131 -3 343 302 128 -3 343 128 132 -3 302 344 125 -3 302 125 128 -3 344 345 124 -3 344 124 125 -3 345 346 123 -3 345 123 124 -3 346 347 122 -3 346 122 123 -3 347 348 126 -3 347 126 122 -3 329 328 348 -3 329 348 347 -3 330 329 347 -3 330 347 346 -3 331 330 346 -3 331 346 345 -3 332 331 345 -3 332 345 344 -3 333 332 344 -3 333 344 302 -3 334 333 302 -3 334 302 343 -3 335 334 343 -3 335 343 342 -3 336 335 342 -3 336 342 341 -3 337 336 341 -3 337 341 340 -3 338 337 340 -3 338 340 339 -3 116 126 349 -3 116 349 120 -3 350 133 116 -3 115 350 116 -3 351 352 353 -3 351 353 354 -3 352 172 173 -3 352 173 353 -3 184 355 356 -3 184 356 185 -3 355 357 358 -3 355 358 356 -3 357 359 360 -3 357 360 358 -3 359 351 354 -3 359 354 360 -3 360 354 361 -3 360 361 362 -3 358 360 362 -3 358 362 363 -3 356 358 363 -3 356 363 364 -3 185 356 364 -3 185 364 186 -3 353 173 194 -3 353 194 365 -3 354 353 365 -3 354 365 361 -3 366 367 352 -3 366 352 351 -3 367 40 172 -3 367 172 352 -3 7 368 355 -3 7 355 184 -3 368 369 357 -3 368 357 355 -3 369 370 359 -3 369 359 357 -3 370 366 351 -3 370 351 359 -3 367 366 370 -3 367 370 369 -3 367 369 368 -3 371 372 373 -3 206 373 372 -3 205 372 371 -3 374 375 376 -3 374 376 377 -3 186 364 373 -3 186 373 206 -3 378 377 376 -3 378 376 379 -3 371 378 379 -3 371 379 380 -3 205 371 380 -3 205 380 263 -3 381 275 276 -3 381 276 382 -3 374 381 382 -3 374 382 375 -3 383 384 381 -3 383 381 374 -3 373 385 378 -3 373 378 371 -3 385 386 377 -3 385 377 378 -3 386 383 374 -3 386 374 377 -3 362 361 383 -3 362 383 386 -3 363 362 386 -3 363 386 385 -3 364 363 385 -3 364 385 373 -3 365 194 258 -3 365 258 384 -3 361 365 384 -3 361 384 383 -3 384 387 381 -3 381 387 275 -3 387 384 258 -3 98 172 23 -3 114 42 184 -3 375 382 388 -3 375 388 389 -3 382 276 307 -3 382 307 388 -3 263 380 390 -3 263 390 316 -3 380 379 391 -3 380 391 390 -3 379 376 392 -3 379 392 391 -3 376 375 389 -3 376 389 392 -3 389 388 393 -3 389 393 394 -3 388 307 318 -3 388 318 393 -3 316 390 395 -3 316 395 327 -3 390 391 396 -3 390 396 395 -3 391 392 397 -3 391 397 396 -3 392 389 394 -3 392 394 397 -3 397 394 398 -3 397 398 399 -3 396 397 399 -3 396 399 400 -3 395 396 400 -3 395 400 401 -3 327 395 401 -3 327 401 328 -3 393 318 338 -3 393 338 402 -3 394 393 402 -3 394 402 398 -3 403 404 350 -3 403 350 115 -3 404 339 133 -3 404 133 350 -3 348 405 349 -3 348 349 126 -3 405 406 120 -3 405 120 349 -3 406 407 119 -3 406 119 120 -3 407 403 115 -3 407 115 119 -3 399 398 403 -3 399 403 407 -3 400 399 407 -3 400 407 406 -3 401 400 406 -3 401 406 405 -3 328 401 405 -3 328 405 348 -3 402 338 339 -3 402 339 404 -3 398 402 404 -3 398 404 403 -3 127 408 128 -3 127 409 408 -3 127 410 409 -3 127 411 410 -3 127 412 411 -3 127 413 412 -3 127 414 413 -3 127 121 414 -3 128 408 134 -3 408 409 134 -3 409 410 134 -3 410 411 134 -3 411 412 134 -3 412 413 134 -3 413 414 134 -3 414 121 134 -3 415 139 135 -3 416 415 135 -3 417 416 135 -3 418 417 135 -3 419 418 135 -3 420 419 135 -3 421 420 135 -3 422 421 135 -3 423 422 135 -3 424 423 135 -3 135 137 424 -3 138 139 415 -3 138 415 416 -3 138 416 417 -3 138 417 418 -3 138 418 419 -3 138 419 420 -3 138 420 421 -3 138 421 422 -3 138 422 423 -3 138 423 424 -3 424 137 138 -3 155 425 144 -3 425 426 144 -3 426 427 145 -3 427 428 145 -3 428 429 152 -3 429 430 152 -3 430 431 153 -3 431 432 153 -3 432 433 149 -3 433 434 149 -3 434 154 148 -3 144 426 145 -3 145 428 152 -3 152 430 153 -3 153 432 149 -3 149 434 148 -3 155 144 148 -3 162 435 168 -3 162 436 435 -3 161 437 436 -3 161 438 437 -3 166 439 438 -3 166 440 439 -3 167 441 440 -3 167 442 441 -3 165 443 442 -3 165 444 443 -3 164 169 444 -3 161 436 162 -3 166 438 161 -3 167 440 166 -3 165 442 167 -3 164 444 165 -3 164 162 168 -3 160 445 446 -3 146 445 160 -3 146 447 445 -3 146 172 447 -3 160 446 184 -3 40 367 368 -3 40 368 7 -3 445 447 446 -3 40 7 184 -3 40 184 172 -3 184 446 447 -3 184 447 172 -3 233 231 202 -3 233 202 282 -3 233 282 234 -3 227 232 229 -3 226 225 230 -3 226 230 232 -3 226 232 227 -3 222 220 224 -3 222 224 228 -3 220 208 224 -3 217 221 218 -3 217 215 219 -3 217 219 221 -3 215 214 219 -3 210 209 213 -3 222 228 223 -3 211 216 212 -3 211 210 213 -3 211 213 216 -3 231 206 202 -3 278 277 257 -3 278 257 261 -3 260 278 261 -3 256 262 255 -3 259 252 251 -3 255 262 259 -3 255 259 251 -3 254 253 246 -3 254 246 248 -3 253 236 246 -3 245 249 243 -3 249 247 240 -3 249 240 243 -3 247 241 240 -3 242 235 237 -3 250 254 248 -3 239 244 238 -3 244 242 237 -3 244 237 238 -3 277 258 257 -3 448 449 372 -3 449 206 372 -3 450 448 372 -3 451 450 372 -3 452 451 372 -3 453 452 372 -3 454 453 372 -3 455 454 372 -3 456 455 372 -3 457 456 372 -3 372 205 207 -3 372 207 457 -3 457 207 203 -3 203 456 457 -3 203 455 456 -3 203 454 455 -3 203 453 454 -3 203 452 453 -3 203 451 452 -3 203 450 451 -3 203 448 450 -3 203 449 448 -3 203 206 449 -3 430 429 428 -3 430 428 427 -3 430 427 426 -3 430 426 425 -3 430 425 155 -3 430 155 154 -3 430 154 434 -3 430 434 433 -3 430 433 432 -3 430 432 431 -3 441 442 443 -3 441 443 444 -3 441 444 169 -3 441 169 168 -3 441 168 435 -3 441 435 436 -3 441 436 437 -3 441 437 438 -3 441 438 439 -3 441 439 440 -3 458 284 387 -3 284 275 387 -3 387 459 458 -3 387 460 459 -3 387 461 460 -3 387 462 461 -3 387 463 462 -3 387 464 463 -3 387 465 464 -3 387 466 465 -3 387 467 466 -3 387 258 467 -3 283 284 458 -3 458 459 283 -3 459 460 283 -3 460 461 283 -3 461 462 283 -3 462 463 283 -3 463 464 283 -3 464 465 283 -3 465 466 283 -3 466 467 283 -3 467 258 283 \ No newline at end of file diff --git a/cubeExample.py b/cubeExample.py deleted file mode 100755 index 997f7a0..0000000 --- a/cubeExample.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -### Cube ### - -import graphics.engine - -points = [[-1,-1,-1],[-1,-1,1],[-1,1,1],[-1,1,-1],[1,-1,-1],[1,-1,1],[1,1,1],[1,1,-1]] -triangles = [[0,1,3],[1,2,3],[1,2,6],[1,5,6],[0,1,4],[1,4,5],[4,5,6],[4,7,6],[0,3,4],[3,4,7],[2,3,6],[3,6,7]] -test = graphics.engine.Engine3D(points, triangles, title='Cube') - -def animation(): - test.clear() - test.rotate('y', 1) - test.rotate('x', 1) - test.render() - test.screen.after(100, animation) - -animation() -test.screen.window.mainloop() - -############ diff --git a/dragExample.py b/dragExample.py old mode 100644 new mode 100755 index 86f66d1..d25fc19 --- a/dragExample.py +++ b/dragExample.py @@ -1,29 +1,13 @@ -### Shark ### +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""2 coordinates axes rotations with mouse.""" -import graphics.engine +from graphics.engine import read_data_file, Engine3D -points = [] -triangles = [] +vertices = read_data_file('coords/SharkV.txt', 'V') +polygons = read_data_file('coords/SharkP.txt', 'P') +test = Engine3D(vertices, polygons, scale=100, title='Shark') -with open('coords/SharkV.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - points.append([float(coords[0]), float(coords[1]), float(coords[2])]) - f.close() - -with open('coords/SharkT.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - newCoords = [] - for coord in coords[1:4]: - newCoords.append(int(coord)) - triangles.append(newCoords) - f.close() - -test = graphics.engine.Engine3D(points, triangles, scale=100, title='Shark') -test.render() -test.screen.window.mainloop() - -############## +if __name__ == '__main__': + test.render() + test.screen.window.mainloop() diff --git a/foldExample.py b/foldExample.py index 2eadb79..1d5d0a9 100755 --- a/foldExample.py +++ b/foldExample.py @@ -42,11 +42,10 @@ engine is changed for a more complex and strict one, folded models may need to be turn around to be correctly drawn and understood. -- Some patterns contains faces that are not triangles, but the current engine -only manages triangles. Until other polygones ares managed by main engine, -patterns would use a uniq color to show each rigid polygon (So 2 consecutive -same color triangles do not fold in beetween in the final model - but they can -fold a bit during folding for gaining light paper twist). +- Some patterns contains faces that are not triangles. Patterns would use a uniq +color to show each rigid polygon (So 2 consecutive same color triangles do not +fold in beetween in the final model - but they can fold a bit during folding for +gaining light paper twist). - There is no management for polygons intersections during fold visualisation so there might be vertices that moves a little through faces. During real paper @@ -61,78 +60,81 @@ T = .5 # box thickness S = .01 # paper thickness causing a little shift on some faces (pre calculated in flat pattern). -points = [ - [-2.5*W-2*T+S, -.5*W, .5*T], [-1.5*W-2*T+S, -.5*W, .5*T], [-1.5*W-T, -.5*W, .5*T], # 0 1 2 - [-.5*W-T, -.5*W, .5*T], [-.5*W, -.5*W, .5*T], [.5*W, -.5*W, .5*T+S/2], # 3 4 5 - [.5*W+T-S, -.5*W, .5*T+S/2], [1.5*W+T-S, -.5*W, .5*T+S/2], [1.5*W+2*T-3*S, -.5*W, .5*T+S/2], # 6 7 8 - [-2.5*W-2*T+S, .5*W, .5*T], [-1.5*W-2*T+S, .5*W, .5*T], [-1.5*W-T, .5*W, .5*T], # 9 10 11 - [-.5*W-T, .5*W, .5*T], [-.5*W, .5*W, .5*T], [.5*W, .5*W, .5*T-S/2], # 12 13 14 - [.5*W+T-S, .5*W, .5*T-S/2], [1.5*W+T-S, .5*W, .5*T-S/2], [1.5*W+2*T-3*S, .5*W, .5*T-S/2], # 15 16 17 - [-2*W-2*T+S, 0, .5*T], [-1.5*W-1.5*T+S, 0, .5*T], [-1*W-T, 0, .5*T], # 18 19 20 - [-.5*W-.5*T, 0, .5*T], [0, 0, .5*T], [.5*W+.5*T, 0, .5*T], # 21 22 23 - [W+T-S, 0, .5*T], [1.5*W+1.5*T-S, 0, .5*T], # 24 25 - ] - -quads = [ - [0, 1, 18, 'pink'], [0, 9, 18, 'pink'], [1, 10, 18, 'pink'], [9, 10, 18, 'pink'], - [1, 2, 19, 'red'], [1, 10, 19, 'red'], [2, 11, 19, 'red'], [10, 11, 19, 'red'], - [2, 3, 20, 'orange'], [2, 11, 20, 'orange'], - [3, 12, 20, 'gold'], [11, 12, 20, 'gold'], - [3, 4, 21, 'lime'], [3, 12, 21, 'lime'], [4, 13, 21, 'lime'], [12, 13, 21, 'lime'], - [4, 5, 22, 'green'], [4, 13, 22, 'green'], [5, 14, 22, 'green'], [13, 14, 22, 'green'], - [5, 6, 23, 'cyan'], [5, 14, 23, 'cyan'], [6, 15, 23, 'cyan'], [14, 15, 23, 'cyan'], - [6, 15, 24, 'royal blue'], [15, 16, 24, 'royal blue'], - [6, 7, 24, 'blue'], [7, 16, 24, 'blue'], - [7, 8, 25, 'purple'], [7, 16, 25, 'purple'], [8, 17, 25, 'purple'], [16, 17, 25, 'purple'], - ] +vertices = [ + [-2.5*W-2*T+S, -.5*W, .5*T], [-1.5*W-2*T+S, -.5*W, .5*T], [-1.5*W-T, -.5*W, .5*T], # 0 1 2 + [-.5*W-T, -.5*W, .5*T], [-.5*W, -.5*W, .5*T], [.5*W, -.5*W, .5*T+S/2], # 3 4 5 + [.5*W+T-S, -.5*W, .5*T+S/2], [1.5*W+T-S, -.5*W, .5*T+S/2], [1.5*W+2*T-3*S, -.5*W, .5*T+S/2], # 6 7 8 + [-2.5*W-2*T+S, .5*W, .5*T], [-1.5*W-2*T+S, .5*W, .5*T], [-1.5*W-T, .5*W, .5*T], # 9 10 11 + [-.5*W-T, .5*W, .5*T], [-.5*W, .5*W, .5*T], [.5*W, .5*W, .5*T-S/2], # 12 13 14 + [.5*W+T-S, .5*W, .5*T-S/2], [1.5*W+T-S, .5*W, .5*T-S/2], [1.5*W+2*T-3*S, .5*W, .5*T-S/2], # 15 16 17 + [-2*W-2*T+S, 0, .5*T], [-1.5*W-1.5*T+S, 0, .5*T], [-1*W-T, 0, .5*T], # 18 19 20 + [-.5*W-.5*T, 0, .5*T], [0, 0, .5*T], [.5*W+.5*T, 0, .5*T], # 21 22 23 + [W+T-S, 0, .5*T], [1.5*W+1.5*T-S, 0, .5*T], # 24 25 +] + +polygons = [ + [0, 1, 18, 'pink'], [0, 9, 18, 'pink'], [1, 10, 18, 'pink'], [9, 10, 18, 'pink'], + [1, 2, 19, 'red'], [1, 10, 19, 'red'], [2, 11, 19, 'red'], [10, 11, 19, 'red'], + [2, 3, 20, 'orange'], [2, 11, 20, 'orange'], + [3, 12, 20, 'gold'], [11, 12, 20, 'gold'], + [3, 4, 21, 'lime'], [3, 12, 21, 'lime'], [4, 13, 21, 'lime'], [12, 13, 21, 'lime'], + [4, 5, 22, 'green'], [4, 13, 22, 'green'], [5, 14, 22, 'green'], [13, 14, 22, 'green'], + [5, 6, 23, 'cyan'], [5, 14, 23, 'cyan'], [6, 15, 23, 'cyan'], [14, 15, 23, 'cyan'], + [6, 15, 24, 'royal blue'], [15, 16, 24, 'royal blue'], + [6, 7, 24, 'blue'], [7, 16, 24, 'blue'], + [7, 8, 25, 'purple'], [7, 16, 25, 'purple'], [8, 17, 25, 'purple'], [16, 17, 25, 'purple'], +] PA = 15 # small angle to visualise paper marks in pre-fold + folds = [ - [ # pre mark for any final fold - (PA, 1, 10, [0, 9, 18]), # pink/red - (PA, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange - (PA, 11, 3, [0, 1, 2, 9, 10, 18, 19]), # orange/yellow - (PA, 12, 3, [0, 1, 2, 9, 10, 11, 18, 19, 20]), # yellow/lime - (PA, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green - (PA, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan - (PA, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue - (PA, 6, 16, [7, 8, 17, 25]), # lightblue/blue - (PA, 16, 7, [8, 17, 25]), # blue/purple - ], [ # first step-fold: outside pre 90° folds for bottom - (90-PA, 1, 10, [0, 9, 18]), # pink/red - (90-PA, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange - (90-PA, 16, 7, [8, 17, 25]), # blue/purple - ], [ # second step-fold: diagonals for triangle crossing in front part - # (not 180° to avoid face identity when draw) - (179-PA, 11, 3, [0, 1, 2, 9, 10, 18, 19]), # orange/yellow - (179-PA, 6, 16, [7, 8, 17, 25]), # lightblue/blue - ], [ # third step-fold: face bottom parts, left "outside" side - (30, 1, 9, [0]), # pink/pink - (10, 1, 10, [0, 9, 18]), # pink/red - (30, 11, 2, [0, 1, 9, 10, 18, 19]), # red/orange - (90-PA, 12, 3, [0, 1, 2, 9, 10, 11, 18, 19, 20]), # yellow/lime - (60-PA, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green - ], [ # fourth step-fold: face bottom parts, right "inside" side - (35, 5, 13, [6, 7, 8, 14, 15, 16, 17, 23, 24, 25]), # green/green - (45-PA, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan - (20, 6, 14, [7, 8, 15, 16, 17, 24, 25]), # cyan/cyan - (75-PA, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue - (60, 24, 7, [8, 16, 17, 25]), # blue/blue - (45, 16, 7, [8, 17, 25]), # blue/purple - ], [ # fifth step-fold: slide into bottom and complete box - (30, 9, 1, [0]), # pink/pink - (10, 10, 1, [0, 9, 18]), # pink/red - (30, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange - (30, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green - (35, 13, 5, [6, 7, 8, 14, 15, 16, 17, 23, 24, 25]), # green/green - (45, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan - (20, 14, 6, [7, 8, 15, 16, 17, 24, 25]), # cyan/cyan - (15, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue - (60, 7, 24, [8, 16, 17, 25]), # blue/blue - (45, 7, 16, [8, 17, 25]), # blue/purple - ] - ] - -test = graphics.engine.Engine3D(points, quads, folds, title='Fold') -test.render() -test.screen.window.mainloop() + [ # pre mark for any final fold + (PA, 1, 10, [0, 9, 18]), # pink/red + (PA, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange + (PA, 11, 3, [0, 1, 2, 9, 10, 18, 19]), # orange/yellow + (PA, 12, 3, [0, 1, 2, 9, 10, 11, 18, 19, 20]), # yellow/lime + (PA, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green + (PA, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan + (PA, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue + (PA, 6, 16, [7, 8, 17, 25]), # lightblue/blue + (PA, 16, 7, [8, 17, 25]), # blue/purple + ], [ # first step-fold: outside pre 90° folds for bottom + (90-PA, 1, 10, [0, 9, 18]), # pink/red + (90-PA, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange + (90-PA, 16, 7, [8, 17, 25]), # blue/purple + ], [ # second step-fold: diagonals for triangle crossing in front part + # (not 180° to avoid face identity when draw) + (179-PA, 11, 3, [0, 1, 2, 9, 10, 18, 19]), # orange/yellow + (179-PA, 6, 16, [7, 8, 17, 25]), # lightblue/blue + ], [ # third step-fold: face bottom parts, left "outside" side + (30, 1, 9, [0]), # pink/pink + (10, 1, 10, [0, 9, 18]), # pink/red + (30, 11, 2, [0, 1, 9, 10, 18, 19]), # red/orange + (90-PA, 12, 3, [0, 1, 2, 9, 10, 11, 18, 19, 20]), # yellow/lime + (60-PA, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green + ], [ # fourth step-fold: face bottom parts, right "inside" side + (35, 5, 13, [6, 7, 8, 14, 15, 16, 17, 23, 24, 25]), # green/green + (45-PA, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan + (20, 6, 14, [7, 8, 15, 16, 17, 24, 25]), # cyan/cyan + (75-PA, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue + (60, 24, 7, [8, 16, 17, 25]), # blue/blue + (45, 16, 7, [8, 17, 25]), # blue/purple + ], [ # fifth step-fold: slide into bottom and complete box + (30, 9, 1, [0]), # pink/pink + (10, 10, 1, [0, 9, 18]), # pink/red + (30, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange + (30, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green + (35, 13, 5, [6, 7, 8, 14, 15, 16, 17, 23, 24, 25]), # green/green + (45, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan + (20, 14, 6, [7, 8, 15, 16, 17, 24, 25]), # cyan/cyan + (15, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue + (60, 7, 24, [8, 16, 17, 25]), # blue/blue + (45, 7, 16, [8, 17, 25]), # blue/purple + ] +] + +test = graphics.engine.Engine3D(vertices, polygons, folds, title='Fold') + +if __name__ == '__main__': + test.render() + test.screen.window.mainloop() diff --git a/galleonExample.py b/galleonExample.py old mode 100644 new mode 100755 index c020e01..8071e5e --- a/galleonExample.py +++ b/galleonExample.py @@ -1,28 +1,12 @@ -### Galleon ### +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""Complex model example: Galleon""" -import graphics.engine +from graphics.engine import read_data_file, Engine3D -points = [] -triangles = [] - -with open('coords/GalleonV.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - points.append([float(coords[0])/150, float(coords[1])/150, float(coords[2])/150]) - f.close() - -with open('coords/GalleonT.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - newCoords = [] - for coord in coords[1:4]: - newCoords.append(int(coord)) - triangles.append(newCoords) - f.close() - -test = graphics.engine.Engine3D(points, triangles, distance=100, title='Galleon') +vertices = read_data_file('coords/GalleonV.txt', 'V', scale=1/150) +polygons = read_data_file('coords/GalleonP.txt', 'P') +test = Engine3D(vertices, polygons, distance=100, title='Galleon') def animation(): test.clear() @@ -30,7 +14,6 @@ def animation(): test.render() test.screen.after(1, animation) -animation() -test.screen.window.mainloop() - -################ +if __name__ == '__main__': + animation() + test.screen.window.mainloop() diff --git a/graphics/__pycache__/__init__.cpython-37.pyc b/graphics/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 9d1dbf70b20482aac97c294f3c33450c1b95f58b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmZ?b<>g`kf=@z|V?p#|5CH>>K!yVl7qb9~6oz01O-8?!3`HPe1o6vVKeRZts8~O> zq%qvpt2+*KQEvtKPxr4q*y<_D6t?TGr8C=wH(gYkB`sH%PfhH X*DI*J#bJ}1pHiBWY6r5Q7>F4FC_yMt diff --git a/graphics/__pycache__/engine.cpython-37.pyc b/graphics/__pycache__/engine.cpython-37.pyc deleted file mode 100644 index 3bb6a221e5c9482012b2e2cb2d4fcd0eaa047b5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2613 zcmZuy-EQ1O6rSZOC+8E@f2LnEjO&h6L7_M#_P=wwdFJ8nKN_#zH`pj%uJQx`T3vUU-YLK z`-^_cM_}?4U-}Vs^)6&Yak<+7ZU^KW=qkqdGWD}lTwmoQGrcjR@9Re1yQ zR!s1D(rPE_(RS0p_4Lq4-)HzzGO@*S7QqVe^G2PUxu`r7Mf+ME)g9xes=I4Eb)=H) zSEfnjf1j*>mnxmEtL#v=<0M<(?j0xHUM$n~{gd*B^_GtJ_u5UcSv}VFPr~Ua(kfNi zwvJnLQ))HigQfD&+69J7Y7@6r`$tT2)?vDlvmuu}=N*UsrL)48;qaU6%;Dg`o{K$U z_q;26?isT@o*n51aJF#I*cpDq@Dt4;YP1Amcz;Acbzf8XjjwxIoGDE%)B&w{&8~_y zHdG>&t~=VLEsqFkUXTiAp&vyO)&o{7t${G^^ILcWyo0$5eju)i3rOt51^4k&M6Q1) z=iBVX@~L&fkY`Ru4Bgy0<7b?+gWB^+Y(3-e_u5I88b99Ohn6NN;}iNvN@uDc`rq5J zE(-1EAjWw1)DT7%90@za0jV!5NjO7KUw;QsBLt{f8TSL}Pos8$sYsB@X z(D!m@=tvktvFfm)lZlQy^!{g_XpG3+#)U;Eb>B>78mMe_Rcb_6C3+s4n$!&4-MFbj z_Y2U{%IkD8C{J89bk^GNZFwIt+r%kst&zPqCNaCrJNg?z8~p)WPqkZnnZ84ucR`GowX?1=)t$KcvZZ^6iM$%IAd1>aJBy-s!Jks-nd5U`Eb&F) zb5T^qU||xmlDA3OO%IJ!lWeJ(#RRTIDWNh^R!K*{k99o*Qs;%@6u$Emw_9siDyo|^ zn4QS8Ria7BOb>yUN`w`52b2CPi9|^UTP{Gb=Qgy-MHUQ zL(f89FVgN6g^2l6d?`s}PVHi$DN5PI0d$fon$_t~Oj_)e_dgixwTeQ+p%?NJD}+S% z%%X})4LC)A7i%6Y_~8^-?XcYK_$xr^cplLFhIJ}-ri#C5G|`*v)EirDPr!1w18zHl z4}aC%+x2W&d;FYb)43S8SoaqPa_{8=Qg2(Swc$)oZIl0mo`4x&u|477x3L%f#)v{N zvAGQTGc2ZLd=8CPs3|%PP4(aU6T!Ci{<3dPu+fcQ?Z|j@n@;0ngS(S>7wuqequWCQ zrJI-(ylA!Jr7Aj1eYS`wK{c%GcH=BV%_6iHxVH(xW5WlA?-<@hujzGr=rw5%Ra;s# zhO6<$RMLH!B7l+0z0%WHg95dDPT7xMyT?z}Y> zMl~Q~6}O$ZKp53i`;au70){4qibb^`5 ds%;79OhqrWhu@h%M6B-GfxN1Z!x{sToPF8u%i diff --git a/graphics/__pycache__/engine.cpython-38.pyc b/graphics/__pycache__/engine.cpython-38.pyc deleted file mode 100644 index 1abc82b767cde683189acd313375f84a0e3eaafa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8960 zcmcgxO>i8?b)J7L7QX~R{E!r7GL*%oM1ViCrPwe`E0k=<608#G{A|Rm7Tbg60*l>c z&wvEC7L|kKl3cD-#mD#r9C7o>RY|4Fm8$rVdk(2N_>xO-$t5=(qI}<*o!J>IK#7&A z?ACP8yna3X-s|_*Z+UsPw*4Eiy3R?VUxSLf6m`Uy3!7SKI(X^>U-*{dgW8IJgdH`UIpZwx~59#=jw*K zu3l5Gs~c)bEpLpdo9Y(u=GAR=2jdIs4fQSbi|X6zP4ws0Tk4O|Ur^ss-$j2>tw1KL zQQ@6dz0vaT+^bn&Kl$;V*Pq}DxGi;~XH+2d`^KTURx+chN;0of>1hASp%poS-`t2? z|B2rU4-H+wtS{~@KWcCL%iE2|%lF!~oox&S%RkkPdUd<8+^L4T-3peU++OZHOJ28J z*VWFWMlD$Og|Ma0v+`J_qW!=R@9AotyA=qjW_LE3w3I;@;={uX;p1c6^o&hIul0<5 zQ<*(;)8ezT7L5gH$_3-VGJ%0H2V=I3xyQzw14D3J>G=j=*72TLIwfx{GM{M^OC8Ok ziOk(2K9oG|@X^!lup0V$91og;joez(uWAhVE#+(Na)7dnn^D}Ay-G!ab)pBHXqcXP z5&r`I-KmTah?V1?yi;Pdo!}23ZbW;9jJ#VeOf9W6ug5YW^qI zJ>%i+Jv;MsWzXqZ`)&{NTQqw1JZ5ud&zUzitOL_D9^ZX@`!jRH6pJbJ@P<#!J-6r9 zjV=4{OdToEQ1L*=$bO**%Um=LOh85fDdHMkG=5=xW?=pZEUti+3!j*L2XMwPKE@fm z9Anc`oHc&Icniu}vC>h{lO26?Fp81>Tst?{mbn~_=cc1FHy$mfb0>0hCuA;1(pw!5lt^F>FCmd*-jK$Iks&1!3%?8_jAM z`Ym6TtjJor8JYf}si|87C5?(J%|;N`+S{Gg3w$+)JxIQ2bYID+D4c{}3zt@!?OL@N ztl}n_HAE#z7b>sdMyNc$XNqcI6QLRqc&r*RwI%!XH_Rn(nA|f%82IN`?n3Xu$car0}jm*Mn?djPq*y4tGy=~C-@5%A|N zbwoQpx<;&vXin!B@iUg#TvlQ|F{Hk!U}AJJo3G#zdgFF|-42d%{u;(k;5^lWP5n*2 zOhN#?zbIU8Qe&7KD)NFFpY^Mpl13N(5*{P3+UX#=L}xQWd%OL_ zukJPiJwpt)f#9>7Lx>F(3wg4MK`!LWOqyk6cFRSqjF|Qw(g=h(aSMz&<%v!^2pa2+ zW+QC)fnESib7vxVqrKBo!eYse_gZEN?Go_{l}fxmsSBtq24dYs%P}YMzhcdpMZ~}v zYusG0E}7}ynltCj?wKKb%*8|+AFnjGK_-wyZ);6t2k*87j1z~{U4QEI@clzi-z3GdFBC)Bp$h9M0;k!~`eU<6ZKn)9BGyjl zO$-Kv8|Ex@1bI_dOJbb=Csux^zfDR{BDWZmtJ+Un-y0(MY(~XMFtLV6W`Gds(>Qxf zgW#+r5s}2UpS)V^C7FkWfry`T_t4gy^wkpWw%gl{maIavHDHm)n#HJCQie zP1A3&IZ0SBM6T1`34a6>$v66>WR0rWI0xU4}NzP_e zpuQNhL^18P(}NHFoP>|*J;|u{5k!t<8=4^|@)UBRFb$SY6AtvGp!WgEOtOvcs~I&= zI2E0iPQkN^!SJ+v+?z>27Do$>OJ4Fmmx)b;&J~U{t8od|kRVfgzlQm=cUrWIaH*`f zaPC;)){4HNw^O~d`-$oqOgeN#9&zY;zCDjuDz)miuaRwRg!f5stbw!Cz;hYN46t5= z;5SbtSbrCb=@m97>Ec8}7ml`%!oN61*xV3dg7zYmJztbe_ccX%I)&KiSSCB2hsVgv zZgYb3BD6h6YV=~K)0FNeUD^6Es)l!S$l=j`sj%XTD0He{h-kivgTa=eAA}4r4i5!g#;wT)>$UDp?>lE-37Q1fs|1`)<>U-Dcn3kNy*@Ns3n*jfxxXrmDm_ zlifrXhK#1Ef;ihMR$GnjN)Y;;AhvV2x`7jaWFr-h<})dnyoAU|p5T1b#3{~*$k-qY zWDTU{?}imlqRZ}E>NK41wR|NcMa%6WWkrk6$x4}94y4qV7^HMlq-5_qp{pnrt1l%F z_al^&vKMID&H)YsIP1^$Wo5@+Tx8|;O`Gvw1om#Jpuf)tCZqaoHuQg*r09EW-eL0t zHt(_-W}PJ_VSO9psgs&Cm-4KqXb)=SH~H~>%t(dz4czb`^ziPU-LpS(_MAO;&)Xa6 zp&GJf>1#cQd|oj2oYr{H855o26YD}4b9-KI<~h``#L1PcwFjjUVK|!Z zR5dmaDSD+}0U9{EI2b&II<=pcr*}FE`cP>o#D;3H6+n2R859rdlI?OK*jX2Ki(DKZ zn||4;?)tZ+y{(xU9hcu^MMPKWt6Bh*fO$1j>TzC3qi4{=h0bR@RaQNRREZ>sIIrP` z(XJ8;bwLyeq6)1|s8J6kAt?$KsT!J_QgUM=Z{R*EB-OsMhg>f7cgxeHJ&<>AMevm z{WZ?B{ZkRVK*j9Ak5(*bzEQDz@B#Y2&v)c7m?jgpmM&{GVjE~}xsUou#nVs%bf6@mivIjTr48P^hYNn#Vb0c2&9ulzC z?#RlAOn6pHS7N^|ZeASuACW*gPf+c};g`MpagE|ffRvqeIJ{g@fz|7{N#b9ZSA*#K%c{ zj?g5%&T$mu?VbR8b^@%Mdtq`y%q<+BbM;TSBa8t0r)WyWjH{(Dl1Lo6Pa7(HRQ4YE z++m&WXXJ*B5K*VNUaf7_by~@Z{T5S<2&e8ws}WWzzr<6(q}i}MxGT@*HH%=w+RY65 z%%5X~Xa6=1B3ACC9=|tt_=2w*)N>~B04qWON}_NabgVe#kf1v#M@phWlI76*TinF; z9IHE-215BflS?P)>3Il{_{Ul)7eqoa&4hxdJ(wz-%42U3^Q<`Lk-Cy2;%2-?_3g)i z=&NjmmH|OT{YPAK@G~rU`N4;tID@E>hU7=r%@l_bHeh{WaD?qSJivm!OZ*J8k2uXk zZ4aLlq_>gy+Msr(pXlafi_kInSis6RedI$F(RpI-p$eKU2%ExWzmTbyfql|x_MZVC zoMvyNaz36Qo%D$SpC87uITW*lq~u6RM&=J9^X*vH1EHp;UHwDg{4QDFK((;Dcp2^)tn)@V&SaY( z*p>aa7S=>j1%Kz~5S-{K*Phs)?AiQ?_;ZTYRvz?}R`nav(~*1uCh-AM5+L_IsnO$$ z7%IB&;aSY9WX5q!1e{7aDy%fC+v}>j`tLyeZ(K(Aa;g^bXW6VW#<=)=V{iG-j_{4` z%eegiGA5R$V!tYBt0aAw0gdCJcu?`LtPp9&(YPFL*2-?J-E89{aL`5)tm0@n8JE?Q z%r8+J(Gz*i8r}dm@}yoq?mVV3@~^mpOK9kOi{^RTL3HLf6eBv*nGsM!scT(@34^w#o(kj*@)YwM-&UzG>f?AJJ`u|J2ib44J=^g8mAh& zP$*nP%fE-ei+|k4cV2NEkdcMg3XY7q@`jREo=OfUOZ{&v%w)wf_&rWW`B diff --git a/graphics/__pycache__/face.cpython-37.pyc b/graphics/__pycache__/face.cpython-37.pyc deleted file mode 100644 index 9bf0ba7ffcf21c3418aeed15ebf7de243ea26d52..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 479 zcmYjNy-ve05cXe6sM-bb5Oiq<#D-7>1-34TB?4K-c1xr*DRv4fN+v4ag;!wZExfYw z1WeqeD(XewcX!TrKlXXQ-z8x0KcDws;J-218i!y6@CQKG#1KQ*fH#&B!*0lcYdHTm z2GI!M4}mO6sUayd)UY*4x#6G}L0ld2-id}ayb(=Qvzka!b6{Ev zU{*)K+z{wQC(w+lKpz6tA<|`Dxgp@`2$6MWaR(= diff --git a/graphics/__pycache__/face.cpython-38.pyc b/graphics/__pycache__/face.cpython-38.pyc deleted file mode 100644 index 04aa2b7b783e910bd2742ecc406a112dab7ee481..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 504 zcmY*VOHRWu5Vf78gsNqMI0W6)5^NEwpunyy5Ss|egxGB@3seiPKJCW6!+ zFs*%HRtLbIByby@z=bq+^v%)41xb+>X3%lIRp~SeSISg6QP!ZD!EFrMm;mUDm?KEP zH+)`Xif4Mk$3?QtR9;#BX!I=3G%w@I6uITA3tq18@|n)n<(SV*T+Vf3`4kozmTMOZ zp>tgcfj+kVr>sXi?epHpb%*;3oEOUTI8#Ent`J!vmnoimLM)bXy8B{|aZViYfI^fM c2w~AHq^+I|cKM*TZN&x`UhOQdv1Ti7YAn_#O#6+ zL{LS#=L3$2q)npS`rFxgSxzPg`i{Z{7E6~zy$+YlJDA(vgFxS<%6hDZ507rk`v_BcCO(T<&>~L=?C}=v!NT6#hy&HP;{Hb5za7tmIkt(Ouvq|Yh4HxL z*Ubq!ngY5jR2so|{hmT*ne+OEQr)l`TLt9AT;qH6T~O{Wu#;Muj4E}OS7jXP`*<9T zDrg_HD63SZ9ZenWIhwg3t12x_-H4TXcq7ZPhJNHqVrGNmNa!;r*mUQb+f}XgtqhUk zLW_WFhOs>IwE&iJFzdl%9mi9pVzvSu2&tr%F|EOFg7GsYQ@sOu3{ERy)8@K92L3e` zOX4KdWpT1rW$_PKvg^XM12ykJ%=u{_#u>P)`SENqlrHLz%gh#4xdB1HgfChkn*iz@ zojAl%EYqP(64ywQVI{^2{brJU8K-I$(T^a3evaw|D$IGK4g%IlzQ#x5TMTwJqERCX aBd|5&_|NGQMZ&$V7VGC-o5&H`)mJ~<; diff --git a/graphics/__pycache__/screen.cpython-38.pyc b/graphics/__pycache__/screen.cpython-38.pyc deleted file mode 100644 index 8e7fa583f7568d9c9ab57910d7a571ce65782cda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1682 zcmZuxJ#!m35Cw1_JW-S!JGK+qPR1^;F=yh|}cQV}@@2a5%EiQV^haewUW^cluq|Lp$BJjTA#=Js%~d5zgT zf{;w|f<^2dlR`RQm~=jih)e!~h3+-%Y?P9`Jp?wdF`JhViou&jLUJj-u*i{)bg{b9 zlRj2Y_GEz7ms_%rwI{db0Baz35MkH&A5yJUl_JlZLAsCm7PC2kXxRc8J!YRdG(;jT z6AKpeR$Mrj44S)O6ZgVfIG3EWR!n@_FZe<%Tq(|Bje9uhT?Chm12bYfqiX^ZI>tN6 zWji+hSmoKcjl^LVZW$-9TI0=?t{c;9kFira5(me|KglaupBS&r+d@VD+obxGG{(!z zBvX+)P157gGj5}bBkdx9CODcZV)}O%i$9dWe8%y2u>8T0gIIr?HjwxVct1lio zeLmn1`TR~t@$;2WO7&lj9+Uvna{V_HVtS9Hu+rIM4ioImIdjjzuC=iVdS;LPz_2GT z+GEAu-LQlEHM_TA_tx#1e@1oV6S447XY|myv#gds(j3`clh6bp@(v54S{U~zFN&yF z&)Nb6g^ngndYgQ9!BEnwcv=^ySzU!aJ;1T?r#0${nx%D7Yr_-64-HQvKdoym8(W!9 z+#&bnEeASJs;p2{w}$$Y@h3ux`GY0DU96SY8q3rIH!Rbuxy^FNF0nY_ONKjMJ2pEG z1$r89>)fYz*>R!o;-XOKdsreb(Yihf-46Hm5;qZ|DRAVzd4KR*=vn;wdz|R|Bp#4> zNP4He)uNKTr})P+%uVF>juAdlc=c6MsyH_NI4)~BD@Y&2@yA(GbQVn|&_9wO z5;Y;S5cN~i{%6~2)a`mjV?#LxJm?3#z@?wH015Sz)xY(36TIv)c}1OIQxC*{b5>Nh diff --git a/graphics/__pycache__/vertex.cpython-37.pyc b/graphics/__pycache__/vertex.cpython-37.pyc deleted file mode 100644 index ddfb3d56304336f92f86cd36deddda056819fe6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1288 zcmZ`(J8#rL5Z;GhIY@XYQh=nmg2occNl?%r6hR`oYY$euj=n3-?q+x_-lOip$Pw2!~Oz5C!2@)IX#jl*C8 zzUl!OK?Kc7L|zfW1V18zAF_xF`kI8!Dfmf0MSIp53>M(49)ghsB1yyq73_#aTyWt) z?+90T(7VD1l)!k)QfaxLVlFnQhhPma;j6k}YWkKptl^DQvzo-D=3r^3>}58aVnXw8Fx@-g;ofq95e|0nWzA|-%opQDygcT)I*Uah3+kudqrL*qUsF} zmWuVPkWUtS>na&+WNFpgwI$9E4oncoS&`{DM#u`W2TT6t~8P8)LX- zv;YH5YO+adHjO>2*$kNlmeb^rHr)F7e|-*c=4-5F>==&p&Y4-Fp{qQ=H*S?Cxio>u zDxDOmj5-5VZpu_kv3hB|Vh^J=6PV|(<%!m^xB-(2kqDckb96K{rZ#q;GxH$=*;!_f zDBKm?_AF>+8aQsks9~BMgK|!QSxtqr#Z(TQf#osW<_U0ynF}+oo!ujF%k9dAAEU?q z8Pd4m_ZzSH0(dUqeg7xkzlaAs8-Lw?fagIzXsd_-&)Z_3sG7o+D;ZZ2u|izAu0lj~ z8@C8_ApAr6zSSzPp_16G!5jNlw?RMq0cUpl6;ALJc=q1e&wqSW1_yPM>h=qCGF z6;2puJJB144Kk4Vj%xL7cv@Cg3Wir%VPQ;XImw4|NvTqWek%(HF^roO>$!|vOn)3X zh1^@QcGcSGZ%ufr)QOgNpg#Mo3A;->G+^zh*n$+nDR z(~0BlQVeq(-;Cp(VUo8Vg?~zF3e9~q__{6`RH(vZ!gpoW3ETUDXV*feutGb&lw%>R Rw1a2urqAKTNrf;0`vY*W7IOdq diff --git a/graphics/__pycache__/vertex.cpython-38.pyc b/graphics/__pycache__/vertex.cpython-38.pyc deleted file mode 100644 index a9b79a827a332886a25d31015c6d66a46dbc0890..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3114 zcmb7G&2QX96rUM?th3pqUnxmxK~@i_ZqcRo8NomZ|3Ie49{Ob z&wtlwF!nc1_CE$D*U-{8K_rvB$6D-DCWSN}GimIK7MFaDdFBi7*=n2U{zqVP4J~~i zBxI0gEg`uSk6Fu*hBVQe(vmiMOV*@=-j*}6j=m;mp}A4ocS4ng+ilV{c`OXbwwq|F z3zGBuMj;BLFmsVJpXCN9&rMJv*&2J!S3RTT+a=#A`N*?MGYxy4(i$XDoGB9;6zNnp z$aAJ<(EW33c_ZnE%l&9``Bu^%_QNG*yWN15-_M^Xobi8{COj*e8GH762na%u9AIkZK)cnyP$<*dtd zu|U1Z#UeWmw-?whFAU8yUdb~N1fwI?m?G_-SsLW=p0nC_&r&roODk;$y|8p-lx9KP z4qNqsO1fb?3+26i-B&85CafYAaqxrFeWA*|6NQ|t|{+;DG zLIC45ptS%`yBHNB=hAp6)C2N2V^87VGx&>{iJ4W+mRNzK)+Wm8XFU`@az#51T6j<+Sx76dvye2Jg&8|pP1?Ks zd#>RtGJ+)7lTrLA=ta_1Nfu;L61%~6lzL8S_JeGr z6oW_$mqt5D_3@WR8pT>mS-%tXhT(0c66M(y6inJ(T0y+t3tMI!Zr#=No~EtC0I>B( z!(*^3JqyCbap4G;yWHWEzFy6RQ-ObOjE!pN0ca3VscC3@jR6A9ad1mHGNKEhe82>9 zJid%|f%S`e9jT$$dF*1Hfb*GNN2=&`f$*Z@PMjcY+y=n?SMHI`ThP6DOIo{T~DLdzK4v5bKb7Isl9oXkY7 z*wQ?~@*2@amOEAdj2AP6@zX3byY>Pr>X5DFb*#_kCdLkp^VuA{dC4y2n8d}oD{djCzo5E%_Nt<72lSAg zge|Rykh+eDemh_ACrGJNY?l2bHci|Nblqv=r-omW1N{_SwCMoz3j8y*#@X>|; z@!rT(-NC2 zEwOc}6x(P!ms(C=kndzp=)N$IkK!j33f89G)MbSX|m;8FkZ)oi$AGD0? zH@1oF5E-?M`1*}jV3n>ppEvqqC-2|nWjAb|E6RGGmkdT ziF5pIKF{mCDb9$|@s~rq>N(0IOV1OzK!pCS)Da>}MCgZHk=A`*-3y?i=n!5~G6a#U fIkt1ksq1x5D2j|8ziM;oT&WK2Dg|06n', self.__zoom_in) + self.screen.window.bind('', self.__zoom_out) + self.screen.window.bind('', self.__camera_up) + self.screen.window.bind('', self.__camera_down) + self.screen.window.bind('', self.__camera_left) + self.screen.window.bind('', self.__camera_right) + + # folding animation + self.fold_index = 0 + self.screen.window.bind('n', self.__next_fold) + self.screen.window.bind('p', self.__prev_fold) + + # grabbing + self.__reset_drag() + self.screen.window.bind('', self.__drag) + self.screen.window.bind('', self.__reset_drag) + + # model edition + self.__selected = None + self.screen.window.bind('', self.__select) + self.screen.window.bind('', self.__deselect) + self.screen.window.bind('x', self.__select_x) + self.screen.window.bind('y', self.__select_y) + self.screen.window.bind('z', self.__select_z) + self.screen.window.bind('+', self.__move_down) + self.screen.window.bind('-', self.__move_up) + + def __reset_drag(self, event=None): self.__prev = [] def __drag(self, event): @@ -15,87 +78,78 @@ def __drag(self, event): self.render() self.__prev = [event.x, event.y] + def __build_axis(self, selection, direction, orientation): + res = copy.deepcopy(selection) + setattr(res, direction, getattr(res, direction) + 40 * orientation / self.scale) + res.flatten(self.scale, self.distance) + return (res.get_flat()[0] + self.screen.zeros[0], res.get_flat()[1] + self.screen.zeros[1]) + def __select(self, event): zeros = self.screen.zeros - event = (event.x - zeros[0], event.y - zeros[1]) - - possibilities = [] - for a in range(-6, 5): - for b in range(-6, 5): - possibilities.append((event[0] + a, event[1] + b)) - - found = [e for e in possibilities if e in self.flattened] - if found != []: + ex, ey = event.x - zeros[0], event.y - zeros[1] + exm, exp, eym, eyp = ex - 6, ex + 5, ey - 6, ey + 5 + possible_vertices = [i for i,v in enumerate(self.vertices) + if exm < v.flat_x < exp and eym < v.flat_y < eyp] + if possible_vertices != []: self.__moveaxis = None - self.__selected = self.flattened.index(found[0]) - - i = self.points[self.__selected] - self.__axis = [[copy.deepcopy(i) for a in range(2)] for b in range(3)] - - self.__axis[0][0].x -= 40 / self.scale - self.__axis[0][1].x += 40 / self.scale - self.__axis[1][0].y -= 40 / self.scale - self.__axis[1][1].y += 40 / self.scale - self.__axis[2][0].z -= 40 / self.scale - self.__axis[2][1].z += 40 / self.scale - - self.__axis = [[point.flatten(self.scale, self.distance) for point in i] for i in self.__axis] - self.__axis = [[[i[0] + zeros[0], i[1] + zeros[1]] for i in j] for j in self.__axis] - self.__axis = [self.screen.createLine(self.__axis[0], 'red'), self.screen.createLine(self.__axis[1], 'green'), self.screen.createLine(self.__axis[2], 'blue')] + self.__selected = self.vertices[possible_vertices[0]] + axis = [[self.__build_axis(self.__selected, d, o) for o in [-1,1]] for d in 'xyz'] + self.__axis = [self.screen.create_arrow(a, self.axis_colors[i]) for i,a in enumerate(axis)] - def __selectx(self, event): + def __select_x(self, event): self.__moveaxis = 'x' - def __selecty(self, event): + def __select_y(self, event): self.__moveaxis = 'y' - def __selectz(self, event): + def __select_z(self, event): self.__moveaxis = 'z' - def __moveup(self, event): + def __move_up(self, event): if self.__selected != None and self.__moveaxis != None: - self.points[self.__selected].move(self.__moveaxis, 0.1) + self.__selected.move(self.__moveaxis, 0.1) self.clear() self.render() - def __movedown(self, event): + def __move_down(self, event): if self.__selected != None and self.__moveaxis != None: - self.points[self.__selected].move(self.__moveaxis, -0.1) + self.__selected.move(self.__moveaxis, -0.1) self.clear() self.render() - def __zoomin(self, event): + def __deselect(self, event): + if self.__selected != None: + self.__selected = None + for line in self.__axis: + self.screen.delete(line) + self.__axis = [] + + def __zoom_in(self, event): self.scale += 2.5 self.clear() self.render() - def __zoomout(self, event): + def __zoom_out(self, event): self.scale -= 2.5 self.clear() self.render() - def __deselect(self, event): - if self.__selected != None: - self.__selected = None - self.__axis = [self.screen.delete(line) for line in self.__axis] - self.__moveaxis = None - - def __cameraleft(self, event): + def __camera_left(self, event): self.screen.zeros[0] -= 5 self.clear() self.render() - def __cameraright(self, event): + def __camera_right(self, event): self.screen.zeros[0] += 5 self.clear() self.render() - def __cameraup(self, event): + def __camera_up(self, event): self.screen.zeros[1] -= 5 self.clear() self.render() - def __cameradown(self, event): + def __camera_down(self, event): self.screen.zeros[1] += 5 self.clear() self.render() @@ -114,109 +168,45 @@ def __prev_fold(self, event): def __fold_animate(self, folds, do=True): for subfolds in folds: - angle, axe1, axe2, points = subfolds + angle, axe1, axe2, vertices = subfolds if do == True: angle = angle / self.anim_steps else: angle = -angle / self.anim_steps - self.part_free_rotate(angle, axe1, axe2, points) + self.part_free_rotate(angle, axe1, axe2, vertices) self.clear() self.render() self.screen.window.update_idletasks() - def writePoints(self, points): - self.points = [] - for point in points: - self.points.append(graphics.vertex.Vertex(point)) - - def writeTriangles(self, triangles): - self.triangles = [] - for triangle in triangles: - if len(triangle) != 4: - triangle.append('gray') - self.triangles.append(graphics.face.Face(triangle)) - - def __init__(self, points, triangles, folds=[], width=1000, height=700, distance=6, scale=100, title='3D', background='white'): - # folding animation parameters - self.anim_steps = 20 - self.fold_index = 0 - self.folds = folds - - #object parameters - self.distance = distance - self.scale = scale - - #initialize display - self.screen = graphics.screen.Screen(width, height, title, background) - self.screen.window.bind('', self.__drag) - self.__prev = [] - self.screen.window.bind('', self.__resetDrag) - - self.screen.window.bind('', self.__zoomin) - self.screen.window.bind('', self.__zoomout) - self.screen.window.bind('w', self.__cameraup) - self.screen.window.bind('s', self.__cameradown) - self.screen.window.bind('a', self.__cameraleft) - self.screen.window.bind('d', self.__cameraright) - self.screen.window.bind('n', self.__next_fold) - self.screen.window.bind('p', self.__prev_fold) - - # this is for editing the model - self.__selected = None - self.__axis = [] - self.__moveaxis = None - self.screen.window.bind('', self.__select) - self.screen.window.bind('', self.__deselect) - self.screen.window.bind('x', self.__selectx) - self.screen.window.bind('y', self.__selecty) - self.screen.window.bind('z', self.__selectz) - self.screen.window.bind('', self.__movedown) - self.screen.window.bind('', self.__moveup) - - #store coordinates - self.writePoints(points) - self.flattened = [] - #store faces - self.writeTriangles(triangles) - - def clear(self): - #clear display - self.screen.clear() - def rotate(self, axis, angle): - #rotate model around axis - for point in self.points: + # rotate model around axis + for point in self.vertices: point.rotate(axis, angle) - def part_free_rotate(self, angle, A, B, points): - #rotate part of model around free vector (from self.points[A] to self.points[B]) - for point in [self.points[index] for index in points]: - point.free_rotate(angle, self.points[A], self.points[B]) + def part_free_rotate(self, angle, A, B, vertices): + # rotate part of model around free vector (from self.vertices[A] to self.vertices[B]) + for point in [self.vertices[index] for index in vertices]: + point.free_rotate(angle, self.vertices[A], self.vertices[B]) def free_rotate(self, angle, A, B): - #rotate model around free vector (from self.points[A] to self.points[B]) - for point in self.points: - point.free_rotate(angle, self.points[A], self.points[B]) + # rotate model around free vector (from self.vertices[A] to self.vertices[B]) + for point in self.vertices: + point.free_rotate(angle, self.vertices[A], self.vertices[B]) + + def clear(self): + # clear display + self.screen.clear() def render(self): - #calculate flattened coordinates (x, y) - self.flattened = [] - for point in self.points: - self.flattened.append(point.flatten(self.scale, self.distance)) - - #get coordinates to draw triangles - triangles = [] - for triangle in self.triangles: - avgZ = (self.points[triangle.a].z + self.points[triangle.b].z + self.points[triangle.c].z) #/ 3 - triangles.append((self.flattened[triangle.a], - self.flattened[triangle.b], - self.flattened[triangle.c], triangle.color, avgZ)) - - #sort triangles from furthest back to closest - triangles = sorted(triangles,key=lambda x: x[4]) - - #draw triangles - for triangle in triangles[::-1]: - self.screen.createTriangle(triangle[0:3], triangle[3]) + # flatten vertices into screen positions + for vert in self.vertices: + vert.flatten(self.scale, self.distance) + + # calculate polygons average depth (z) + for poly in self.polygons: + poly.depth = sum([self.vertices[v_i].z for v_i in poly.vertices]) + # draw flattent polygons from furthest to closest + for poly in reversed(sorted(self.polygons, key=lambda x: x.depth)): + self.screen.create_polygon([self.vertices[v].get_flat() for v in poly.vertices], poly.color) diff --git a/graphics/face.py b/graphics/face.py deleted file mode 100644 index 80fa5f3..0000000 --- a/graphics/face.py +++ /dev/null @@ -1,8 +0,0 @@ -class Face: - def __init__(self, vertices): - #store point indexes - (a, b, c, color) = vertices - self.a = a - self.b = b - self.c = c - self.color = color diff --git a/graphics/screen.py b/graphics/screen.py index f294120..52f3a71 100644 --- a/graphics/screen.py +++ b/graphics/screen.py @@ -1,4 +1,5 @@ import tkinter +import itertools class Screen: def __init__(self, width, height, title, background): @@ -10,15 +11,14 @@ def __init__(self, width, height, title, background): self.window.title(title) self.image = tkinter.Canvas(self.window, width=width, height=height, bg=background) self.image.pack() - - def createTriangle(self, points, color): - a, b, c = points[0], points[1], points[2] - #create coordinates starting in center of screen - coords = [a[0] + self.zeros[0], a[1] + self.zeros[1], b[0] + self.zeros[0], b[1] + self.zeros[1], c[0] + self.zeros[0], c[1] + self.zeros[1]] - #draw triangle on screen + + def create_polygon(self, vertices, color): + # create coordinates starting in center of screen + coords = list(itertools.chain(*[[v0 + self.zeros[0], v1 + self.zeros[1]] for v0,v1 in vertices])) + # draw triangle on screen self.image.create_polygon(coords, fill=color, outline="black") - def createLine(self, points, color): + def create_arrow(self, points, color): a, b = points[0], points[1] return self.image.create_line(a[0], a[1], b[0], b[1], fill=color, arrow=tkinter.BOTH) @@ -28,7 +28,6 @@ def clear(self): def delete(self, item): self.image.delete(item) - return None def after(self, time, function): #call tk.Tk's after() method diff --git a/graphics/vertex.py b/graphics/structures.py similarity index 85% rename from graphics/vertex.py rename to graphics/structures.py index 69bdbbe..2660d14 100644 --- a/graphics/vertex.py +++ b/graphics/structures.py @@ -1,5 +1,17 @@ import math + +class Polygon: + def __init__(self, *args): + #store point indexes + if isinstance(args[-1], str): + self.vertices = args[:-1] + self.color = args[-1] + else: + self.vertices = args + self.color = "grey" + + class Vertex: def __init__(self, point): #store x, y, z coordinates @@ -10,9 +22,11 @@ def __init__(self, point): def flatten(self, scale, distance): #calculate 2D coordinates from 3D point - projectedY = int(((self.y * distance) / (self.z + distance)) * scale) - projectedX = int(((self.x * distance) / (self.z + distance)) * scale) - return (projectedX, projectedY) + self.flat_x = int(((self.x * distance) / (self.z + distance)) * scale) + self.flat_y = int(((self.y * distance) / (self.z + distance)) * scale) + + def get_flat(self): + return (self.flat_x, self.flat_y) def rotate(self, axis, angle): #rotate point around axis diff --git a/pyramidExample.py b/pyramidExample.py new file mode 100755 index 0000000..dd7f790 --- /dev/null +++ b/pyramidExample.py @@ -0,0 +1,19 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""Animated pyramid example""" + +from graphics.engine import Engine3D + +vertices = [[0,0,0],[0,-1,0],[-1,1,-1],[-1,1,1],[1,1,1],[1,1,-1]] +polygons = [[2,3,4,5],[1,2,3],[1,3,4],[1,4,5],[1,2,5]] +test = Engine3D(vertices, polygons, title='Cube') + +def animation(): + test.clear() + test.free_rotate(.75, 0, 1) # angle in degree, axe defined by 2 vertices + test.render() + test.screen.after(10, animation) + +if __name__ == '__main__': + animation() + test.screen.window.mainloop() diff --git a/sharkExample.py b/sharkExample.py old mode 100644 new mode 100755 index 895ceef..0d5bb3c --- a/sharkExample.py +++ b/sharkExample.py @@ -1,28 +1,12 @@ -### Shark ### +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""Complex model example: Shark""" -import graphics.engine +from graphics.engine import read_data_file, Engine3D -points = [] -triangles = [] - -with open('coords/SharkV.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - points.append([float(coords[0]), float(coords[1]), float(coords[2])]) - f.close() - -with open('coords/SharkT.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - newCoords = [] - for coord in coords[1:4]: - newCoords.append(int(coord)) - triangles.append(newCoords) - f.close() - -test = graphics.engine.Engine3D(points, triangles, scale=100, title='Shark') +vertices = read_data_file('coords/SharkV.txt', 'V') +polygons = read_data_file('coords/SharkP.txt', 'P') +test = Engine3D(vertices, polygons, scale=100, title='Shark') def animation(): test.clear() @@ -30,7 +14,6 @@ def animation(): test.render() test.screen.after(1, animation) -animation() -test.screen.window.mainloop() - -############## +if __name__ == '__main__': + animation() + test.screen.window.mainloop()