Vektoren / Vertexnormal in Kugel
Übersicht

KrischanBetreff: Vektoren / Vertexnormal in Kugel |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Mal eine Verständnisfrage:
Ich habe eine perfekte Kugel (keine B3D Sphere - ist zusammengesetzt aus 24 einzelnen Patches!) bei der ich alle Vertexkoordinaten in einer Schleife durchgehe. Ich möchte jetzt die UpdateNormals-Funktion umgehen (wegen der unschönen Patchränder bei der Beleuchtung) und jeden Vertexnormal direkt berechnen. Das Zentrum der Kugel ist bei 0,0,0 und der Radius ist 1. Es ändern sich also nur die Vertexkoordinaten. Wie muss die Formel aussehen, damit ich für jeden X,Y,Z Vertexpunkt die NX/NY/NZ Werte herausfinde? Ich vermute die Lösung ist sehr einfach, komme aber nicht drauf... |
||
![]() |
ToeB |
![]() Antworten mit Zitat ![]() |
---|---|---|
Kann man das nicht mit Winkel machen oder verstehe ich da was nicht ?
Also so : Code: [AUSKLAPPEN] nx# = Atan2(vy,vz)
ny# = Atan2(vx,vz) nz# = Atan2(vy,vx) Musste mal testen... mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
![]() |
darth |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bei einer Perfekten Kugel ist jeder Punkt gleich weit weg vom Mittelpunkt. (Ist ja klar...)
Ich verstehe nicht genau was du mit dem Patches meinst (eine Perfekte Kugel hat keine Trigs, meiner Meinung nach), aber prinzipiell lässt sich sagen: die Normale jedes Punktes ist einfach der Vektor vom Mittelpunkt zu dem Vertex. Wenn du die Allgemeine Normale des Trigs (=Patch?) willst, dann ist das das Kreuzprodukt zweier Vektoren auf dieser Trig-Ebene, aber das wird mit Vertex-Normals auch so berechnet, also nehme ich nicht an, dass du das willst. Von daher würde ich bei der Behauptung stehen: nimm einfach den Vektor vom Mittelpunkt zum Vertex, der steht senkrecht auf der Tangentialebene zur Kugel an diesem Punkt. |
||
Diese Signatur ist leer. |
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Klappt so nicht bzw. verstehe ich bei darth nur Bahnhof. Ich geb Euch mal den Code, es handelt sich hierbei um einen etwas anderen, vertexbasierenden Planetengenerator. Es ist etwas schwer zu erklären und ich lasse das wieso und warum ich das so gemacht habe mal weg aber es macht durchaus Sinn, glaubt mir ![]() Stellt Euch einen unterteilten Würfel vor, der aus 6 Seiten besteht, jede Seite ist bei mir ein Patch mit X*X Vertices (also z.B: 32x32). Nehmt drei der Seiten weg und kopiert und ordnet diesen dreiseitigen Teilwürfel so an, dass aus 8 dieser Würfel wieder ein neuer, grosser Würfel entsteht (also nur die Aussenseiten). Dieser Würfel bzw. die einzelnen Patches werden dann mittels einer Funktion "spherized", so dass nachher aus 24 Patches ein perfekte Kugel entsteht, je nach Patchgrösse mehr oder weniger detailliert. Und dass das auch klappt könnt ihr sehen wenn Ihr den Code ausführt ![]() Lange Rede kurze Sinn: wir haben also einen Haufen Vertices im Raum die eine Kugel bilden und ich diese blöden Nahtstellen zwischen den Patches loswerden will. Wenn man eine size von 64 oder 128 ansetzt gehen die zwar auch weg aber nur weil sie dann zu klein sind um sichtbar zu sein. Hier der auf das wesentliche reduzierte Code, die Normalberechnung sollte in der Funktion CalcSphereNormals() stattfinden, darin befindet sich auch schon der auskommentierte Teilcode von ToeB. Mit der Maus und den Pfeiltasten könnt Ihr die Kugel drehen oder näher ran / weiter weg (und wie immer bei mir: SPACE = Wireframe) Code: [AUSKLAPPEN] ms=MilliSecs()
Const size=16 Global maps%=0 Local patch[2] Dim VertexBuffer%(128,128),MeshPart%(23) Graphics3D 800,600,32,2 ; planet pivot pivot=CreatePivot() campivot=CreatePivot() cam=CreateCamera(campivot) PositionEntity cam,3,2,-5 CameraRange cam,0.1,120 CameraZoom cam,3 patch[0]=CreatePatch(size,1.0/(size)) : RotateMesh patch[0], 0,180, 0 : PositionMesh patch[0],0.5,0.5,-0.5 patch[1]=CreatePatch(size,1.0/(size)) : RotateMesh patch[1], 0,270, 0 : PositionMesh patch[1],0.5,0.5,-0.5 patch[2]=CreatePatch(size,1.0/(size)) : RotateMesh patch[2],270, 0, 0 : PositionMesh patch[2],0.5,0.5,-0.5 For i=0 To 7 For j=0 To 2 If counter<12 Then MeshPart(counter)=AddSpherePart(patch[j],pivot, 0, i*90,0) Else MeshPart(counter)=AddSpherePart(patch[j],pivot,180, i*90,0) EndIf counter=counter+1 Next Next FreeEntity patch[0] FreeEntity patch[1] FreeEntity patch[2] CalcSphereNormals() ; light source light=CreateLight(1) AmbientLight 16,16,16 MoveMouse 400,300 ende=MilliSecs()-ms While Not KeyHit(1) If KeyHit(57) Then wf=1-wf : WireFrame wf ; turn planet with mouse mxs#=MouseXSpeed() mys#=MouseYSpeed() TurnEntity pivot,0,-0.005+mxs,0 TurnEntity campivot,mys,0,mys MoveEntity cam,(KeyDown(205)-KeyDown(203))*2.0/30,0,(KeyDown(200)-KeyDown(208))*1.0/30 PointEntity cam,pivot RenderWorld Text 0, 0,"Tris.......: "+TrisRendered() Text 0,15,"Calc time..: "+ende+"ms" Flip 1 Wend End Function AddSpherePart(mesh%,pivot%,rx#=0,ry#=0,rz#=0) Local m%=CopyMesh(mesh,pivot) Cube2Sphere(m) EntityFX m,2 RotateMesh m,rx,ry,rz maps=maps+1 Return m 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 ; 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),SphericalY(vx,vy,vz),SphericalZ(vx,vy,vz) Next Next End Function Function CalcSphereNormals() For i=0 To maps-1 surf=GetSurface(MeshPart(i),1) For v=0 To CountVertices(surf)-1 VertexColor surf,v,255,255,255 vx#=VertexX(surf,v) vy#=VertexY(surf,v) vz#=VertexZ(surf,v) ;nx# = ATan2(vy,vz) ;ny# = ATan2(vx,vz) ;nz# = ATan2(vy,vx) ;VertexNormal surf,v,nx,ny,nz Next UpdateNormals MeshPart(i) Next End Function Function CreatePatch(size%,scale#) Local x%,z%,v#,u#,v0%,v1%,v2%,v3% ; create mesh and surface Local mesh%=CreateMesh() Local surf%=CreateSurface(mesh) For z=0 To size For x=0 To size ; calculate uv coordinates that the texture fits to the tile u=x*1.0/size v=z*1.0/size*-1 ; set vertexposition VertexBuffer(x,z)=AddVertex (surf,-((size)/2.0)+x,-((size)/2.0)+z,size/2,u,v) VertexColor surf,VertexBuffer(x,z),255,255,255,1.0 Next Next ; set triangles For z=0 To size-1 For x=0 To size-1 v0=VertexBuffer(x,z) v1=VertexBuffer(x+1,z) v2=VertexBuffer(x+1,z+1) v3=VertexBuffer(x,z+1) AddTriangle (surf,v0,v2,v1) AddTriangle (surf,v0,v3,v2) Next Next ; position, scale and fx ScaleMesh mesh,scale,scale,scale FlipMesh mesh Return mesh End Function |
||
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wie Darth bereits erklärte, ist bei einer Kugel die Normale eines Vertex einfach der Vektor vom Mittelpunkt zum Vertex ![]() Deine Funktion sähe also folgendermassen aus Code: [AUSKLAPPEN] Function CalcSphereNormals()
For i=0 To maps-1 surf=GetSurface(MeshPart(i),1) For v=0 To CountVertices(surf)-1 VertexColor surf,v,255,255,255 VX#=VertexX(surf,v) VY#=VertexY(surf,v) VZ#=VertexZ(surf,v) TFormNormal VX#, VY#, VZ#, 0, 0 VertexNormal surf,v, TFormedX(), TFormedY(), TFormedZ() Next Next End Function Das TFormNormal habe ich da reingeschrieben, damit der Richtungsvektor von Mittelpunkt zu Vertex sicher die Länge 1 hat, da du ansonsten unter Umständen Grafikfehler bekommst. |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ja super, genau das ist es! Ich wusste es hat was mit Tformdingsbums zu tun, stehe aber mit Vektoren immer ein wenig auf Kriegsfuss ![]() ![]() |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group