Drehung von Verbindungen zweier Punkte [gelöst]

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

BlitzMoritz

Betreff: Drehung von Verbindungen zweier Punkte [gelöst]

BeitragDo, Sep 01, 2011 18:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Zwei beliebige Punkte im dreidimensionalen Raum (stellvertretend dargestellt durch zwei Kugeln) sollen durch einen länglichen Quader verbunden werden, d.h. zwischen den Kugeln befindet sich ähnlich wie im Gerüstbau eine Verbindungsstange.
Diese zu positionieren und zu skalieren ist kein Problem, man nehme einfach die Mitte der beiden Punkte, norme zwei Größen konstant und passe die dritte Skalierung der Entfernung an.
Das Problem jedoch ist, mit welchen Werten eine solche Stange per RotateEntity gedreht werden muss.
Man erhält zwar über ATan2 diverse Werte, so wie sie in 2D nützlich sind, aber in 3D habe ich noch nicht herausbekommen, ob sie etwas nützen und wie sie zu verarbeiten sind:
BlitzBasic: [AUSKLAPPEN]
Graphics3D 1000,700,0,2
Local camera = CreateCamera()
PositionEntity(camera,0,0,-30)
Local light = CreateLight()

Local Kugel1 = CreateSphere(12)
EntityColor(Kugel1, 96,0,0)
EntityShininess(Kugel1, 1)
Local x1# = Rand(-4,4)
Local y1# = Rand(-4,4)
Local z1# = Rand(-4,4)
PositionEntity(Kugel1, x1,y1,z1)

Local Kugel2 = CreateSphere(12)
EntityColor(Kugel2, 0,128,0)
EntityShininess(Kugel2, 1)
Local x2# = Rand(-20, 20)
Local y2# = Rand(-20, 20)
Local z2# = Rand(-20, 20)
PositionEntity(Kugel2, x2,y2,z2)

Local Entfernung# = 0.5 * Sqr( (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 )
Dim Mitte#(3)
Mitte(0) = 0.5 * (x2+x1)
Mitte(1) = 0.5 * (y2+y1)
Mitte(2) = 0.5 * (z2+z1)
Dim Winkel#(2)
Winkel(0) = ATan2( y2-y1, x2-x1 )
Winkel(1) = ATan2( y2-y1, z2-z1 )
Winkel(2) = ATan2( z2-z1, x2-x1 )

Local Stange = CreateCube()
EntityColor(Stange, 0,0,128)
EntityShininess(Stange, 1)
ScaleEntity(Stange, Entfernung, 0.25, 0.25)
PositionEntity(Stange, Mitte(0), Mitte(1), Mitte(2))
RotateEntity(Stange, Winkel(0), Winkel(1), Winkel(2))

Repeat
;---------------------------------------------------------------------
If MouseHit(1) Then

x1# = Rand(-4,4)
y1# = Rand(-4,4)
z1# = Rand(-4,4)
PositionEntity(Kugel1, x1,y1,z1)

x2# = Rand(-20, 20)
y2# = Rand(-20, 20)
z2# = Rand(-20, 20)
PositionEntity(Kugel2, x2,y2,z2)

Entfernung = 0.5 * Sqr( (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 )
Mitte(0) = 0.5 * (x2+x1)
Mitte(1) = 0.5 * (y2+y1)
Mitte(2) = 0.5 * (z2+z1)
ScaleEntity(Stange, Entfernung, 0.25, 0.25)
PositionEntity(Stange, Mitte(0), Mitte(1), Mitte(2))

Winkel(0) = ATan2( y2-y1, x2-x1 )
Winkel(1) = ATan2( y2-y1, z2-z1 )
Winkel(2) = ATan2( z2-z1, x2-x1 )

;Hier jetzt die Frage: Wie soll die Stange gedreht werden, damit sie beide Punkte verbindet?
RotateEntity(Stange, Winkel(0), Winkel(1), Winkel(2)) ;(so auf jeden Fall nicht ...)

End If
;---------------------------------------------------------------------
UpdateWorld()
RenderWorld()
Text 10, 10, "Mausklick!"
Flip
Until KeyDown(1)
Es wäre schön, wenn mir jemand helfen könnte.
  • Zuletzt bearbeitet von BlitzMoritz am Fr, Sep 02, 2011 18:08, insgesamt einmal bearbeitet

Lobby

BeitragDo, Sep 01, 2011 18:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Schon mit PointEntity versucht?
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux

ZEVS

BeitragDo, Sep 01, 2011 18:30
Antworten mit Zitat
Benutzer-Profile anzeigen
*mitFremdenFedernSchmück*
https://www.blitzforum.de/foru...457#297457
Noobody hat Folgendes geschrieben:
Pitch# = ATan2( VectorY#, Sqr( VectorX#*VectorX# + VectorZ#*VectorZ# ) )
Yaw# = ATan2( -VectorZ#, -VectorX# ) - 90

Dann einfach addieren und modulo 360.

ZEVS

ZaP

BeitragDo, Sep 01, 2011 18:37
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzBasic: [AUSKLAPPEN]
AlignToVector Stange, x2# - x1#, y2# - y1#, z2# - z1#, 1

So vielleicht? Also unter der Annahme, Du Stange soll beide Kugeln verbinden.
Starfare: Worklog, Website (download)

Xeres

Moderator

BeitragDo, Sep 01, 2011 19:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Skalierung ist nicht unwichtig, ich würde die Tiefe verlängern:
Code: [AUSKLAPPEN]
ScaleEntity(Stange, 0.25, 0.25, Entfernung)

Dann lassen sich Pitch & Yaw verwenden:
Code: [AUSKLAPPEN]
Winkel(0) = ATan2( y2-y1, Sqr( (x2-x1)*(x2-x1)+(z2-z1)*(z2-z1) ))
Winkel(1) = ATan2( -(z2-z1), -(x2-x1) ) - 90
RotateEntity(Stange, Winkel(0), Winkel(1), 0)

Die Berechnung für Yaw ist aber leider nicht perfekt, funktioniert nicht in allen fällen...

Edit: Uh, funktioniert doch, EntityYaw gibt bloß was anderes zurück.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Noobody

BeitragDo, Sep 01, 2011 19:59
Antworten mit Zitat
Benutzer-Profile anzeigen
ZaPs Vorschlag ist definitiv am einfachsten. Einfach das RotateEntity durch ein AlignToVector ersetzen und man hat eine stabile Lösung: BlitzBasic: [AUSKLAPPEN]
Graphics3D 1000,700,0,2
Local camera = CreateCamera()
PositionEntity(camera,0,0,-30)
Local light = CreateLight()

Local Kugel1 = CreateSphere(12)
EntityColor(Kugel1, 96,0,0)
EntityShininess(Kugel1, 1)
Local x1# = Rand(-4,4)
Local y1# = Rand(-4,4)
Local z1# = Rand(-4,4)
PositionEntity(Kugel1, x1,y1,z1)

Local Kugel2 = CreateSphere(12)
EntityColor(Kugel2, 0,128,0)
EntityShininess(Kugel2, 1)
Local x2# = Rand(-20, 20)
Local y2# = Rand(-20, 20)
Local z2# = Rand(-20, 20)
PositionEntity(Kugel2, x2,y2,z2)

Local Entfernung# = 0.5 * Sqr( (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 )
Dim Mitte#(3)
Mitte(0) = 0.5 * (x2+x1)
Mitte(1) = 0.5 * (y2+y1)
Mitte(2) = 0.5 * (z2+z1)
Dim Winkel#(2)
Winkel(0) = ATan2( y2-y1, x2-x1 )
Winkel(1) = ATan2( y2-y1, z2-z1 )
Winkel(2) = ATan2( z2-z1, x2-x1 )

Local Stange = CreateCube()
EntityColor(Stange, 0,0,128)
EntityShininess(Stange, 1)
ScaleEntity(Stange, Entfernung, 0.25, 0.25)
PositionEntity(Stange, Mitte(0), Mitte(1), Mitte(2))
;RotateEntity(Stange, Winkel(0), Winkel(1), Winkel(2))
AlignToVector Stange, x2 - x1, y2 - y1, z2 - z1, 1

Repeat
;---------------------------------------------------------------------
If MouseHit(1) Then

x1# = Rand(-4,4)
y1# = Rand(-4,4)
z1# = Rand(-4,4)
PositionEntity(Kugel1, x1,y1,z1)

x2# = Rand(-20, 20)
y2# = Rand(-20, 20)
z2# = Rand(-20, 20)
PositionEntity(Kugel2, x2,y2,z2)

Entfernung = 0.5 * Sqr( (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 )
Mitte(0) = 0.5 * (x2+x1)
Mitte(1) = 0.5 * (y2+y1)
Mitte(2) = 0.5 * (z2+z1)
ScaleEntity(Stange, Entfernung, 0.25, 0.25)
PositionEntity(Stange, Mitte(0), Mitte(1), Mitte(2))

Winkel(0) = ATan2( y2-y1, x2-x1 )
Winkel(1) = ATan2( y2-y1, z2-z1 )
Winkel(2) = ATan2( z2-z1, x2-x1 )

;Hier jetzt die Frage: Wie soll die Stange gedreht werden, damit sie beide Punkte verbindet?
;RotateEntity(Stange, Winkel(0), Winkel(1), Winkel(2)) ;(so auf jeden Fall nicht ...)
AlignToVector Stange, x2 - x1, y2 - y1, z2 - z1, 1

End If
;---------------------------------------------------------------------
UpdateWorld()
RenderWorld()
Text 10, 10, "Mausklick!"
Flip
Until KeyDown(1)
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

BlitzMoritz

BeitragDo, Sep 01, 2011 22:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Oohh, Danke, das klingt ja einfach ...
Aber eigentlich suche ich hier in fremden Gewässern und bin am BlitzMaxen mit minib3D. Dort wird die Zeile so nicht akzeptiert:
BlitzMax: [AUSKLAPPEN]
AlignToVector Stange, x2 - x1, y2 - y1, z2 - z1, 1

Leider ist minib3D-Wiki immer noch down und ich kann nicht nachschlagen.
Weiß jemand, wie man in minib3D den Befehl AlignToVector verwendet?

ZEVS

BeitragFr, Sep 02, 2011 14:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja: gar nicht. Der Befehl ist (leider) nicht implementiert, was mich auch tierisch nervt. Über eine funktionierende Alternative bin ich allen dankbar, das würde mein eingefrorenes Projekt wieder auftauen.

Deswegen ja auch mein oberer Beitrag, das ist das einzig vernünftige, was ich zu diesem Thema finden kann. An sich funktionsfähig, aber irgendwie klappt das bei mir nicht mit der beliebigen Rückrechnung auf den Vektor... Ist aber nicht der Thread dazu.

ZEVS

ZaP

BeitragFr, Sep 02, 2011 16:02
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzMax: [AUSKLAPPEN]

Function AlignToVector(e:TEntity, vx:Float, vy:Float, vz:Float, axis = 0, rate = 1)
e.RotateEntity(VectorPitch(vx, vy, vz), VectorYaw(vx, vy, vz), e.EntityRoll())
End Function


Hier meine Implementation für die Z-Achse (minib3d/inc/functions.bmx in Version 0.53). Du müsstest also die Stange auf der Z-Achse mit Entfernung skalieren, damit das funktioniert. Finde ich auch am meisten intuitiv. Smile
@ZEVS: Jetzt wollen wir aber auch was sehen Wink
Starfare: Worklog, Website (download)
  • Zuletzt bearbeitet von ZaP am Fr, Sep 02, 2011 16:05, insgesamt einmal bearbeitet

darth

BeitragFr, Sep 02, 2011 16:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

wenn man den Befehl bei Google eingibt, kommt man auf ein tolles Ergebnis im englischen BlitzBasic Forum.
KLICK
Danach kann man sich die Funktion klauen (sollte eigentlich fast 1:1 gehen), und dann frisch fröhlich AlignToVector in seinen Code schreiben. Nützlich, nich?

MfG,
Darth
Diese Signatur ist leer.

BlitzMoritz

BeitragFr, Sep 02, 2011 18:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Problem gelöst Smile , mein Beispiel, nun mit ZAP's einfacher Lösung (Danke) und der notwendigen z-Skalierung:
BlitzMax: [AUSKLAPPEN]
SuperStrict
Import sidesign.minib3d
Graphics3D 1000,700
Local camera:TCamera = CreateCamera()
PositionEntity(camera,0,0,-30)
Local light:TLight = CreateLight()

Local Kugel1:TEntity = CreateSphere(12)
EntityColor(Kugel1, 96,0,0)
EntityShininess(Kugel1, 1)
Local x1# = Rand(-4,4)
Local y1# = Rand(-4,4)
Local z1# = Rand(-4,4)
PositionEntity(Kugel1, x1,y1,z1)

Local Kugel2:TEntity = CreateSphere(12)
EntityColor(Kugel2, 0,128,0)
EntityShininess(Kugel2, 1)
Local x2# = Rand(-20, 20)
Local y2# = Rand(-20, 20)
Local z2# = Rand(-20, 20)
PositionEntity(Kugel2, x2,y2,z2)

Local Entfernung# = 0.5 * Sqr( (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 )
Local Mitte#[] = [ 0.5 * (x2+x1), 0.5 * (y2+y1), 0.5 * (z2+z1) ]

Local Stange:TEntity = CreateCube()
EntityColor(Stange, 0,0,128)
EntityShininess(Stange, 1)
ScaleEntity(Stange, 0.25, 0.25, Entfernung)
PositionEntity(Stange, Mitte[0], Mitte[1], Mitte[2])
RotateEntity(Stange, VectorPitch(x2 - x1, y2 - y1, z2 - z1), VectorYaw(x2 - x1, y2 - y1, z2 - z1), Stange.EntityRoll())

Repeat
If MouseHit(1) Then

x1# = Rand(-4,4)
y1# = Rand(-4,4)
z1# = Rand(-4,4)
PositionEntity(Kugel1, x1,y1,z1)

x2# = Rand(-20, 20)
y2# = Rand(-20, 20)
z2# = Rand(-20, 20)
PositionEntity(Kugel2, x2,y2,z2)

Entfernung = 0.5 * Sqr( (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 )
Mitte = [ 0.5 * (x2+x1), 0.5 * (y2+y1), 0.5 * (z2+z1) ]
ScaleEntity(Stange, 0.25, 0.25, Entfernung)
PositionEntity(Stange, Mitte[0], Mitte[1], Mitte[2])
RotateEntity(Stange, VectorPitch(x2 - x1, y2 - y1, z2 - z1), VectorYaw(x2 - x1, y2 - y1, z2 - z1), Stange.EntityRoll())

End If
UpdateWorld()
RenderWorld()
Flip
Until KeyDown(KEY_ESCAPE) Or AppTerminate()

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group