XYZ aus UV berechnen

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Thoem

Betreff: XYZ aus UV berechnen

BeitragSa, Jan 22, 2011 21:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo...

Kennt jemand von euch einen gängigen Algorithmus XYZ Koordinaten aus UV's innerhalb eines Dreiecks zu berechnen.
Gegeben seien die XYZ- sowie die UV-Texturkoordinaten der Deiecksecken. Ich möchte nun die 3D-Position eines Punktes im 3D-Raum anhand seiner UV-Pendants bestimmen.
Thoem...

Vertex

BeitragSo, Jan 23, 2011 0:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Mein Ansatz (aber noch nicht zu Ende gedacht) benutzt die Parameterdarstellung einer Ebene:
user posted image (Parameterdarstellung)
Die Ebene sei die jenige, auf der das Dreieck liegt. Die Ortsvektoren der Eckpunkte des Dreiecks nenne ich mal e1, e2 und e3
Dabei ist
- q der Ortsvektor Deines gesuchten Punktes
- p ein Punkt auf der Ebene. Beispielsweise wissen wir von e1, dass dieser auf der Ebene liegt also p = e1
- v1 und v2 sind die Spannvektoren nehmen wir v1 = (e2 - e1) und v2 = (e3 - e1)
- s und t die Parameter, um den Punkt q auf Ebene zu beschreiben.

Mit der Annahme, dass der 3D-Raum linear in den UV-Raum abgebildet werden kann, machen wir so eine Parameterdarstellung auch für die "UV-Ebene":
q' = p' + s*v1' + t*v2' mit:
- q' deine gegebenen UV-Koordinaten
- p' den UV-Koordinaten vom Eckpunkt 1
- v1' = UV-Koordinaten von Eckpunkt 2 - UV-Koordinaten von Eckpunkt 1
- v2' = UV-Koordinaten von Eckpunkt 3 - UV-Koordinaten von Eckpunkt 1

Die Gleichung musst Du nach s und t umstellen und dann setzt Du s und t in die erste Ebenengleichung ein und erhälst q, also Deine gesuchten XYZ-Koordinaten.

Das ist allerdings jetzt aus dem Bauch heraus entstanden, also keine Garantie, dass es funktioniert Smile

Ciao Olli

Vertex

BeitragSo, Jan 23, 2011 3:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, funktioniert tatsächlich. Hatte irgendwie Lust das mal umzusetzen (Dein Glück Smile ) und das kam dabei heraus.

BlitzBasic: [AUSKLAPPEN]
Type TVector3f
Field X#
Field Y#
Field Z#
End Type

Function CreateVector3f.TVector3f(X#, Y#, Z#)
Local V.TVector3f = New TVector3f
Vector3fSetXYZ(V, X, Y, Z)
Return V
End Function

Function Vector3fSetXYZ(V.TVector3f, X#, Y#, Z#)
V\X = X
V\Y = Y
V\Z = Z
End Function

Type TVector2f
Field X#
Field Y#
End Type

Function CreateVector2f.TVector2f(X#, Y#)
Local V.TVector2f = New TVector2f
Vector2fSetXYZ(V, X, Y)
Return V
End Function

Function Vector2fSetXYZ(V.TVector2f, X#, Y#)
V\X = X
V\Y = Y
End Function

Local VertexPosition.TVector3f[2]
VertexPosition[0] = CreateVector3f( 5.0, 10.0, 0.0)
VertexPosition[1] = CreateVector3f(15.0, 1.0, 0.0)
VertexPosition[2] = CreateVector3f( 5.0, -5.0, 6.0)

Local VertexUV.TVector2f[2]
VertexUV[0] = CreateVector2f(0.0, 1.0)
VertexUV[1] = CreateVector2f(1.0, 0.0)
VertexUV[2] = CreateVector2f(0.0, 0.0)


Global UV.TVector2f = CreateVector2f(0.3, 0.2)

Global XYZ.TVector3f = New TVector3f

Global C#, S#, T#

C = -(VertexUV[2]\X - VertexUV[0]\X)/(VertexUV[2]\Y - VertexUV[0]\Y)

S = (UV\X + C*UV\Y) - (VertexUV[0]\X + C*VertexUV[0]\Y)
S = S/((VertexUV[1]\X - VertexUV[0]\X) + C*(VertexUV[1]\Y - VertexUV[0]\Y))

T = (UV\Y - VertexUV[0]\Y) - S*(VertexUV[1]\Y - VertexUV[0]\Y)
T = T/(VertexUV[2]\Y - VertexUV[0]\Y)

XYZ\X = VertexPosition[0]\X + S * (VertexPosition[1]\X - VertexPosition[0]\X) + T * (VertexPosition[2]\X - VertexPosition[0]\X)
XYZ\Y = VertexPosition[0]\Y + S * (VertexPosition[1]\Y - VertexPosition[0]\Y) + T * (VertexPosition[2]\Y - VertexPosition[0]\Y)
XYZ\Z = VertexPosition[0]\Z + S * (VertexPosition[1]\Z - VertexPosition[0]\Z) + T * (VertexPosition[2]\Z - VertexPosition[0]\Z)


Graphics3D(800, 600, 0, 2)

Local Mesh% = CreateMesh()
Local Surface% = CreateSurface(Mesh)
AddVertex(Surface, VertexPosition[0]\X, VertexPosition[0]\Y, VertexPosition[0]\Z, VertexUV[0]\X, VertexUV[0]\Y)
AddVertex(Surface, VertexPosition[1]\X, VertexPosition[1]\Y, VertexPosition[1]\Z, VertexUV[1]\X, VertexUV[1]\Y)
AddVertex(Surface, VertexPosition[2]\X, VertexPosition[2]\Y, VertexPosition[2]\Z, VertexUV[2]\X, VertexUV[2]\Y)
AddTriangle(Surface, 0, 1, 2)

Local Texture% = MakeTexture(UV\X, UV\Y)
EntityTexture(Mesh, Texture)
EntityFX(Mesh, 16)

Local Pivot% = CreatePivot()
Local Camera% = CreateCamera(Pivot)
PositionEntity(Camera, 0.0, 5.0, -30.0)

Local Marker% = CreateCube()
PositionEntity(Marker, XYZ\X, XYZ\Y, XYZ\Z)
ScaleMesh(Marker, 0.4, 0.4, 0.4)
EntityColor(marker, 255, 255, 0)
EntityAlpha(Marker, 0.5)

While Not KeyDown(1)
TurnEntity(Pivot, 0.0, 1.0, 0.0)

UpdateWorld()
RenderWorld()
Flip()
Wend

End

Function MakeTexture%(U#, V#)
Local Texture% = CreateTexture(256, 256)
Local Buffer% = TextureBuffer(Texture)
Local Width% = TextureWidth(Texture)
Local Height% = TextureHeight(Texture)

Color(127, 127, 127)
Rect(0, 0, Width, height)
Color(255, 0, 0)
Rect(U * Width - 5, V * Height - 5, 10, 10)
CopyRect(0, 0, Width, Height, 0, 0, BackBuffer(), TextureBuffer(Texture))

Return Texture
End Function


Also der rote Punkt auf der Textur markiert die gegebene UV-Koordinate, und der gelbe Cube Marker ist die ausgerechnete XYZ-Koordiante. Die Rechnungen für C (Hilfsfaktor), S und T entstammen einem simplen Gleichungssystem. q' = p' + s*v1' + t*v2' die erste Gelichung erhälst Du durch betrachten der aller X-komponenten und die zweite durch betrachten aller Y-Komponenten. Das Gleichungssystem habe ich dann gelöst, indem ich die zeite Gleichung mit C multipliziere und dann mit der ersten Gleichung addiere. C ist so gewählt, dass dabei die erste Unbekannte T verschwindet und ich nach S umstellen kann. Mit dem errechneten S kann man dann an T heran kommen.

Ciao Olli
vertex.dreamfall.at | GitHub

Thoem

BeitragSo, Jan 23, 2011 19:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab ganz vielen Dank.

Das ist genau das, was ich gesucht hatte. Ich war schon dabei, mich mit Baryzentrischen Koordinaten auseinanderzusetzen.
Thoem...

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group