Cube zu Sphere Transformation
Übersicht

KrischanBetreff: Cube zu Sphere Transformation |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Dies ist eine Demo einer Cube zu Sphere Transformation. Die sechs Seiten (Patches) eines unterteilten Cubes werden so verformt, dass der Cube wie eine Sphere aussieht, und zwar ohne Verzerrung an den Polen - und die Patches passen perfekt zusammen!
Es basiert auf einem Code from Birdie und etwas Mathematik von "Math Proofs". Man kann es es vielseitig verwenden, für eine sehr runde Sphere oder sogar einen prozeduralen Planeten mit fraktaler Unterteilung (ich weiss zwar nicht wie, aber Infinity verwendet diese Methode). Man kann damit auch sehr detaillierte Spheres durch Ändern der "detail" Variable erstellen. Wenn einer weiss, wie man das mit den fraktalen Planeten hierauf anwenden kann als her damit! Screenshot: ![]() Code: [AUSKLAPPEN] AppTitle "Cube to Sphere Transformation"
Graphics3D 800,600,32,2 ; detail of the cube/sphere detail=10 Global transform$[1] : transform[0]="Sphere" : transform[1]="Cube" pivot=CreatePivot() ; Camera cam=CreateCamera(pivot) CameraRange cam,0.01,1000 PositionEntity cam,0,0,-3 ; create segmented Cube cube=CreateSegCube(detail) EntityColor cube,0,255,0 EntityFX cube,1+16 MoveMouse 400,300 WireFrame 1 While Not KeyHit(1) ; movement / rotating mxs#=MouseXSpeed() mys#=MouseYSpeed() TurnEntity cube,0,mxs,0 TurnEntity pivot,mys,0,0 MoveEntity cam,0,0,(KeyDown(200)-KeyDown(208))*1.0/60 ; W = Wireframe If KeyHit(17) Then wf=1-wf : WireFrame 1-wf ; SPACE = transform If KeyHit(57) Then switch=1-switch If switch=1 Then ; transforms cube to sphere Cube2Sphere(cube) Else ; creates a new cube FreeEntity cube cube=CreateSegCube(detail) EntityColor cube,0,255,0 EntityFX cube,1+16 EndIf EndIf RenderWorld Text 0,0,TrisRendered()+" Tris" Text 0,15,"W for Wireframe" Text 0,30,"SPACE for "+transform[switch] Flip Wend End ; transform a cube patch to sphere patch Function Cube2Sphere(mesh%) Local s%,surf%,v% Local vx#,vy#,vz# For s=1 To CountSurfaces(mesh) surf=GetSurface(mesh,s) For v=0 To CountVertices(surf)-1 vx=VertexX(surf,v) vy=VertexY(surf,v) vz=VertexZ(surf,v) VertexCoords surf,v,SphericalX(vx,vy,vz)*1.333333,SphericalY(vx,vy,vz)*1.333333,SphericalZ(vx,vy,vz)*1.333333 Next Next End Function ; calculate spherical X Function SphericalX#(x#,y#,z#) Return x*Sqr(1.0-y*y*0.5-z*z*0.5+y*y*z*z*1.0/3) End Function ; calculate spherical Y Function SphericalY#(x#,y#,z#) Return y*Sqr(1.0-z*z*0.5-x*x*0.5+z*z*x*x*1.0/3) End Function ; calculate spherical Z Function SphericalZ#(x#,y#,z#) Return z*Sqr(1.0-x*x*0.5-y*y*0.5+x*x*y*y*1.0/3) End Function ; creates a segmented cube Function CreateSegCube(segs=1,parent=0) Local side%,surf% Local stx#,sty#,stp#,y# Local a%,x#,v#,b%,u# Local v0%,v1%,v2%,v3% Local mesh%=CreateMesh(parent) ; sides For side=0 To 3 surf=CreateSurface( mesh ) stx=-.5 sty=stx stp=Float(1)/Float(segs) y=sty For a=0 To segs x=stx v=a/Float(segs) For b=0 To segs u=b/Float(segs) AddVertex(surf,x,y,0.5,u,v) x=x+stp Next y=y+stp Next For a=0 To segs-1 For b=0 To segs-1 v0=a*(segs+1)+b:v1=v0+1 v2=(a+1)*(segs+1)+b+1:v3=v2-1 AddTriangle( surf,v0,v1,v2 ) AddTriangle( surf,v0,v2,v3 ) Next Next RotateMesh mesh,0,90,0 Next ;top and bottom RotateMesh mesh,0,90,90 For side=0 To 1 surf=CreateSurface( mesh ) stx#=-.5 sty#=stx stp#=Float(1)/Float(segs) y#=sty For a=0 To segs x#=stx v#=a/Float(segs) For b=0 To segs u#=b/Float(segs) AddVertex(surf,x,y,0.5,u,v) x=x+stp Next y=y+stp Next For a=0 To segs-1 For b=0 To segs-1 v0=a*(segs+1)+b:v1=v0+1 v2=(a+1)*(segs+1)+b+1:v3=v2-1 AddTriangle( surf,v0,v1,v2 ) AddTriangle( surf,v0,v2,v3 ) Next Next RotateMesh mesh,180,0,0 Next ; scale uniform to -1 to +1 space in X/Y/Z dimensions FitMesh mesh,-1,-1,-1,2,2,2,1 Return mesh End Function |
||
![]() |
Triton |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich hab mich auch schonmal mit sowas ähnlichem befasst und versucht eine Methode zu finden, eine
Kugel verzerrungsfrei aufzufalten. Also quasi der umgekehrte Weg. Bin dann letztendlich bei der Geosphere gelandet, die ja ein unterteiltes Tetraeder darstellt quasi. Die könnte man zwar verzerrungsfrei Auffalten, die UV-Map wäre dann aber nicht quadratisch, praktisch, gut, wie hier ![]() Jedenfalls eine elegante Lösung. Sehr schön. |
||
Coding: silizium-net.de | Portfolio: Triton.ch.vu |
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Achso wichtig ist noch, dass der Cube innerhalb der X/Y/Z-Koordinaten -1 bis 1 liegt, sonst klappt es nicht. | ||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hmm zum Thema "Kugel verzerrungsfrei auffalten" kann ich noch mit einer Formel aus dem Buch "Texturing and Modeling - A procedural approach" dienen, allerdings habe ich Probleme, diese korrekt zu lesen. Es handelt sich hierbei um das "equalangular mapping":
U=(TAN^-1(X,Y)) / (2*Pi) V=(SIN^-1(Z/SQR(x^2+y^2+z^2) / (2*Pi))+0.5 Originalseite (sofern das klappt): Auszug bei Google Books S. 198 Das sollte die korrekten UV-Koordinaten anhand der XYZ Koordinaten liefern. Ich bin mir jetzt aber nicht sicher, wie das im Code aussehen muss, also z.B. das TAN^-1(x,y)??? Umgekehrt sieht es wie folgt aus, das berechnet aus einer 2D-Karte die 3D Koordinaten auf der Kugel: X = COS((V-0.5)*2*Pi)*SIN(U*2*Pi) Y = COS((V-0.5)*2*Pi)*COS(U*2*Pi) Z = SIN((V-0.5)*2*Pi) |
||
![]() |
DaysShadow |
![]() Antworten mit Zitat ![]() |
---|---|---|
Edit: Hm, args, stimmt da war was....
MfG DaysShadow |
||
Blessed is the mind too small for doubt |
- Zuletzt bearbeitet von DaysShadow am Fr, Jul 24, 2009 11:45, insgesamt 3-mal bearbeitet
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Tan^-1 ist normalerweise der Arcustangenz (und so wie die Parameter dort stehen, also Komma getrennt, würd ich mal denken, dass du in Blitz dafür einfach ATan2![]() Und sin^-1 wäre dann wohl der Arcussinus, ASin ![]() mfG |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group