 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Thorben
Anmeldungsdatum: 26.04.2005 Beiträge: 173 Wohnort: SH
|
Verfasst am: 31.10.2006, 13:38 Titel: Distanz zwischen Dreieck und Punkt |
|
|
Hallo
Wie kann ich die kürzeste Distanz zwischen einem Dreieck und einem Punkt im 3 Dimensionalen raum berechnen.
MFG Thorben |
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 31.10.2006, 14:50 Titel: |
|
|
Hallo!
Überprüfen, ob Schnittpunkt der Lotgeraden mit der Ebene, die das Dreieck bildet im Dreieck liegt.
Wenn ja:
Kürzester Abstand mit Schnittpunkt
Wenn Nein:
Überprüfen, ob Schnittpunkt mit Senkrechten auf Dreieckskante auf letzterer liegt.
Wenn ja:
Kürzester Abstand mit diesem Schnittpunkt
Wenn nein:
Kürzester Abstand mit Eckpunkt
Ich glaub, jetzt hab ich's, oder??
Grüsse |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 31.10.2006, 17:06 Titel: |
|
|
..wenn nicht google hat Folgendes geschrieben: | Ergebnisse 1 - 10 von ungefähr 1.200.000 für Abstand Punkt Ebene | ..oder den forumsinternen Suchdienst beauftragen
Gruß
ytwinky _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 31.10.2006, 18:13 Titel: |
|
|
thorben eventuell zähl ma auf welche fälle alle vorkommen können.. liegt der punkt immer über dem dreieck oder vielleich immer in der selben ebene mit dem dreieck oder liegen beide völlig unabhängig voneinander irgendwo? Und willst du die kürzeste distanz vom punkt zu dam nächsten punkt im dreieck oder reichts für einen speziellen punkt (eckpunkt, schwerpunkt, mittelpunkt, was auch immer)? _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Thorben
Anmeldungsdatum: 26.04.2005 Beiträge: 173 Wohnort: SH
|
Verfasst am: 31.10.2006, 19:09 Titel: |
|
|
Die Punkte sind unabhängig voneinander.
Es geht um eine Collisionserkennung zwischen einem Objekt das von einer Kugel umgeben ist und einer Wand( die aus Dreiecken besteht ).
Jetzt muss ich berechnen ob ein dreieck der Wand die Kugel schneidet.
Ich habe mir gedacht die kürzeste Distanz zwischen dem Dreieck und
dem punkt zu berechnen und dann die Distanz mit dem radius der kugel zu vergleichen. Daher muss ich die kürzeste distanz vom punkt zu dem nächsten punkt im Dreieck berechnen.
Also die kürzeste distanz zwischen der Ebene des Dreiecks und dem Punkt kann ich jetzt berechnen aber nun weiß ich auch nicht weiter.
Code: |
TYPE TYPE_3DVektor
x AS SINGLE
y AS SINGLE
z AS SINGLE
END TYPE
'---------------------------------------------------------------------------
DECLARE FUNCTION MatrixSub( Vek1 AS TYPE_3dVektor, Vek2 AS TYPE_3dVektor ) AS TYPE_3dVektor
DECLARE FUNCTION CrossProdukt( Vek1 AS TYPE_3dVektor, Vek2 AS TYPE_3dVektor ) AS TYPE_3dVektor
'---------------------------------------------------------------------------
'Punkt
DIM P AS TYPE_3DVektor
'Dreieck
DIM A AS TYPE_3DVektor
DIM B AS TYPE_3DVektor
DIM C AS TYPE_3DVektor
DIM la AS TYPE_3DVektor
DIM lb AS TYPE_3DVektor
DIM Nrm AS TYPE_3DVektor
DIM NrmLng AS SINGLE
'---------------------------------------------------------------------------
A.x = -1: B.x = 1: C.x = 0
A.y = 0: B.y = 0: C.y = 1
A.z = -1: B.z = -1: C.z = -1
P.x = 10
P.y = -50
P.z = 0
'Normalvektor berechnen
la = MatrixSub( B , A )
lb = MatrixSub( C , A )
Nrm = CrossProdukt( la , lb )
NrmLng = SQR( Nrm.x * Nrm.x + Nrm.y * Nrm.y + Nrm.z * Nrm.z )
Nrm.x = Nrm.x / NrmLng
Nrm.y = Nrm.y / NrmLng
Nrm.z = Nrm.z / NrmLng
'---------------------------------------------------------------------------
DIM Tmp AS TYPE_3DVektor
DIM Distance AS SINGLE
Tmp = MatrixSub( P , A )
Distance = ( Tmp.x * Nrm.x ) + ( Tmp.y * Nrm.y ) + ( Tmp.z * Nrm.z )
PRINT Distance
SLEEP: END
'---------------------------------------------------------------------------
FUNCTION MatrixSub( Vek1 AS TYPE_3DVektor, Vek2 AS TYPE_3DVektor ) AS TYPE_3DVektor
'---------------------------------------------------------------------------
DIM VekErg AS TYPE_3DVektor
VekErg.x = Vek1.x - Vek2.x
VekErg.y = Vek1.y - Vek2.y
VekErg.z = Vek1.z - Vek2.z
MatrixSub = VekErg
END FUNCTION
'---------------------------------------------------------------------------
FUNCTION CrossProdukt( Vek1 AS TYPE_3DVektor, Vek2 AS TYPE_3DVektor ) AS TYPE_3DVektor
'---------------------------------------------------------------------------
DIM VekErg AS TYPE_3DVektor
VekErg.x = ( Vek1.y * Vek2.z - Vek1.z * Vek2.y ) * -1
VekErg.y = ( Vek1.z * Vek2.x - Vek1.x * Vek2.z ) * -1
VekErg.z = ( Vek1.x * Vek2.y - Vek1.y * Vek2.x ) * -1
CrossProdukt = VekErg
END FUNCTION
|
Zuletzt bearbeitet von Thorben am 31.10.2006, 20:54, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 31.10.2006, 20:51 Titel: |
|
|
ehm eine grade wand? Dann nimm die ganze wand als ebene, das is dreihundert mal einfacher..
stellst im prinzip die ebenengleichung auf, lotgerade durch den mittelpunkt, und dann düfts schon passen oO
mathematisch:
E: x=A + r*(B-A) + s*(C-A)
g: x=M + t*( (B-A)x(C-A) )
die beiden teile dann gleichgesetzt, nach t aufgelöst, |t| durch den |(B-A)x(C-A)| geteilt und mit dem radius verglichen - wert=radius => berührt, wert>radius => berührt nicht, wert<radius => steckt drin - zu mehr hab ich grad keine lust x) AxB ist das Kreuzprodukt wenn du versuchst, dir das ganze alleine auszurechnen, siehe wikipedia oO
welche klasse bist du grade (nur für zukünftige antworten )? _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Thorben
Anmeldungsdatum: 26.04.2005 Beiträge: 173 Wohnort: SH
|
Verfasst am: 31.10.2006, 21:10 Titel: |
|
|
Danke für deine Mühe.
Aber leider ist es nicht immer eine gerade Wand. Mit der Ebenen gleichung hab ich schon rumexperiementiert. Meine erste Idee war
Den Schnitt punkt zwischen der Strecke alter Punkt zu neuer Punkt + Minimale Distanz mit dem Dreieck zu berechnen das hat auch wunderbar geklappt. Aber wenn das Objekt sich jetzt fast paralel zu der Wand( bzw Dreieck ) bewegte kam es langsam immer näher auf das Dreieck zu da sich die linie ja nie mit dem Dreieck schnitt. Und dann war es plötzlich so nah das sich das dreieck doch mit der Strecke schnitt und das objekt wurde um die Minimale Distance von dem Dreieck weg versetzt.
Das sieht nachher nicht schön aus. Deswegen hab ich mir das mit der Kugel ausgedacht.
Ich hoffe man verstehts. Ich hab die Letzten zwei Wochen Ferien damit verbracht mir das alles über wikipedia und durch ausprobieren beizubringen.
Ich gehe in die 11 Klasse.
MFG Thorben |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 01.11.2006, 00:15 Titel: |
|
|
was du im prinzip machst ist das:
du stellst dir vor, die wand wäre unendlich groß - eine eben eben. Für die stellst du die gleichung auf. Und du nimmst einen Vektor der senkrecht zu der ebene steht, das is das was du mit dem AxB ausrechnest, und kombinierst den mit dem mittelpunkt des kreises zu einer geraden. Dann schaust du, wo sich der punkt und die gerade schneiden (=gleichsetzen) und kannst anhand des geradenparameters dann den abstand rausfinden, ging auch irgendwie einfacher, hessche normalform..mom x)
hessesche normalform und einsetzen - hm, das is irgendwie schon über n jahr her.. x)
n=(AB)x(AC)
n0=n/|n|
d=OA*n0
s=OM*n0-d
3 und 4 zusammen => s=OM*n0-OA*n0=(OM-OA)*n0
also ausgerechnet ist das dann etwas mehr arbeit..
Code: | type vektor
x as single
y as singlee
z as single
end type |
ich gehe mal von so einem type aus..
Code: | 'a,b,c = verschiedene punkte der wand die nicht auf einer geraden liegen, type vektor.
dim as vektor ab, ac, n, n0
'differenzen
with ab
.x=a.x-b.x
.y=a.y-b.y
.z=a.z-b.z
end with
with ac
.x=a.x-c.x
.y=a.y-c.y
.z=a.z-c.z
end with
'kreuzprodukt
with n
.x=a.y*b.z-a.z*b.y
.y=a.z*b.x-a.x*b.z
.z=a.x*b.y-a.y*b.x
end with
'normalenvektor
with n0
.x=n.x/sqr(n.x*n.x+n.y*n.y+n.z*n.z)
.y=n.y/sqr(n.x*n.x+n.y*n.y+n.z*n.z)
.z=n.z/sqr(n.x*n.x+n.y*n.y+n.z*n.z)
end with
'm = mittelpunkt des kreises, ebenfalls type vektor und vordefiniert
'Abstand
dim s as single
s=(a.x-m.x)*n0.x+(a.y-m.y)*n0.y+(a.z-m.z)*n0.z |
wenn s negativ ist liegt der mittelpunkt auf der seite der wand auf der auch der Ursprung (0,0,0) ist, positiv => auf der anderen seite der wand, null => mittelpunkt liegt direkt in der wand.
Code: | if abs(s)=radius then
print "Kreis berührt die Ebene"
elseif abs(s)<radius then
print "Kreis 'steckt' in der Ebene"
elseif abs(s)>radius then
print "Kreis berührt die Ebene nicht."
else
print "diesen fall gibts nicht, hab nur alle anderen drei fälle je als"
print "elseif geschrieben damit du jeweils die bedingung siehst ;)"
end if |
ohne garantie, ungetestet, nur im kopf zusammengeschrieben x) hoffe du kannst was damit anfangen. _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 02.11.2006, 22:33 Titel: |
|
|
Das Beispiel von MatheNexus hat mir keine Ruhe gelassen
Also habe ich 'kurzerhand' ein FreeBASIC-Programm geschrieben, um es nachzuvollziehen: Code: | Option Explicit
'+------------------------------------------------------------------------------------------+
'| Header: Bestimmen der Übergabeparameter' |
'| AnzeigeCheck:|Il1 sind Alt-0124, Großes i, kleines L, Eins „ä”ö?üáߎę֚Üñ±¸©ø°|
Const Author="HNF.Bas v016bSE ©2006 by ytwinky, MD"' |
'| (Tastenkombination: keine) |
'| |
'| Zweck : Beispiel ans Laufen bringen, ganz ohne(?) WinAPI |
'+------------------------------------------------------------------------------------------+
Type Vektor3D
x As Single
y As Single
z As Single
End Type
Const Schranke=0.0001
Dim As Vektor3D P1, P2, A, B, C, n, n0
Dim As Single NrmLng, HNF
Declare Sub GetDist(byVal From As String, byVal P As Vektor3D, byVal n0 As Vektor3D, byVal A As Vektor3D)
Declare Sub PrVec(byVal Titel As String, byVal V As Vektor3D, byVal Flag As Long=0, Probe As String="", byVal Vk As Vektor3D=n)
Declare Function MatrixSub(byVal V1 As Vektor3D, byVal V2 As Vektor3D) As Vektor3D
Declare Function KreuzProdukt(byVal A As Vektor3D, byVal B As Vektor3D) As Vektor3D
Declare Function SkalarProdukt(byVal Faktor As Single, byVal V As Vektor3D) As Vektor3D
Declare Function VektorProduktSkalar(byVal V1 As Vektor3D, byVal V2 As Vektor3D) As Single
'Beispieldaten
P1.x=5: P1.y=2: P1.z=-3
P2.x=4: P2.y=1: P2.z=2
A.x=3: A.y=1: A.z=-2
B.x=2: B.y=1: B.z=-1
C.x=-3: C.y=1: C.z=-2
'Berechnung
n=KreuzProdukt(B, C)
HNF=VektorProduktSkalar(n, A)
If HNF<0 Then n=SkalarProdukt(-1, n)
NrmLng=Sqr(n.z*n.z+n.y*n.y+n.x*n.x)
n0=SkalarProdukt(1/Abs(NrmLng), n)
'Ausgabe
?Author
?"|n|=" &NrmLng
?"HNF=" & HNF
PrVec "nø=", n0
GetDist("A", A, n0, A)
GetDist("P1", P1, n0, A)
GetDist("P2", P2, n0, A)
Sleep
End
Function KreuzProdukt(byVal A As Vektor3D, byVal B As Vektor3D) As Vektor3D 'n. Bartsch, also okay
Dim KP As Vektor3D
KP.x=(a.y*b.z-b.y*a.z)
KP.y=(a.z*b.x-b.z*a.x)
KP.z=(a.x*b.y-b.x*a.y)
Return KP
End Function
Function MatrixSub(byVal A As Vektor3D, byVal B As Vektor3D) As Vektor3D 'hier kann kein Fehler sein
Dim dif As Vektor3D
dif.x=A.x-B.x
dif.y=A.y-B.y
dif.z=A.z-B.z
Return dif
End Function
Function SkalarProdukt(byVal Faktor As Single, byVal V As Vektor3D) As Vektor3D
V.x*=Faktor
V.y*=Faktor
V.z*=Faktor
Return V
End Function
Function VektorProduktSkalar(byVal A As Vektor3D, byVal B As Vektor3D) As Single
Return a.x*b.x+a.y*b.y+a.z*b.z
End Function
Sub GetDist(byVal From As String, byVal P As Vektor3D, byVal n0 As Vektor3D, byVal A As Vektor3D)
Dim c As Single=VektorProduktSkalar(n0, MatrixSub(P, A))
If c=0 Then
?"Der Punkt " &From &" liegt in der Ebene."
Else
If Abs(c)<=Schranke Then
?"Der Punkt " &From &" scheint in der Ebene zu liegen.."
Else
Select Case c
Case Is<0: ?From &" und Ursprung liegen auf derselben Ebenenseite."
Case Is>0: ?From &" und Ursprung liegen auf verschiedenen Ebenenseiten."
Case Else: ?"Zu Risiken und Nebenwirkungen fragen Sie Mircosoft oder Ihren Administrator"
End Select
End If
End If
?"|c|=" &Abs(c)
End Sub
Sub PrVec(byVal Titel As String, byVal V As Vektor3D, byVal Flag As Long=0, Probe As String="", byVal Vk As Vektor3D=n)
If Titel<>"" Then ?Titel;
If Flag Then
?"{" &V.x &", " &V.y &", " &V.z &"}";
If Probe<>"" Then ?Probe;
?"{" &Vk.x &", " &Vk.y &", " &Vk.z &"}"
Else
?"{" &V.x &", " &V.y &", " &V.z &"}"
End If
End Sub | Vielleicht wird ja noch was Ordentliches draus..
Wer mag, kann sich ja mein Bild mal ansehen(14Kb): http://ytwinky.freebasic.de/tuts/hnz.gif
Zum Spielen reicht dies erst mal aus
Gruß
ytwinky _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 05.11.2006, 16:14 Titel: |
|
|
Hi,
ich habe, weil ich ein mißtrauischer Mensch bin, meine Resultate mal
mit den Ergebnissen von einem schweizer Programm(mittlerweile Freeware) verglichen
und die Ausgabe übersichtlicher gestaltet, ohne die Ergebnisse zu ändern: Calc 3D Prof hat Folgendes geschrieben: | P1: (5; 2; -3) =P1
E2: x =(3; 1; -2) + t * (2; 1; -1) + s * (-3; 1; -2)
P1 liegt auf E2
Abstand: 0
-----------------------------------------------------------
P1: (4; 1; 2) =P2
E2: x =( 3; 1; -2) + t * (2; 1; -1) + s * (-3; 1; -2)
P1 liegt auf der anderen Seite von E2 wie der Nullpunkt.
Abstand: 2.19393
-----------------------------------------------------------
P1: ( 3; 1; -2) =A
E2: x =(3; 1; -2) + t * (2; 1; -1) + s * (-3; 1; -2)
P1 liegt auf E2
Abstand: 0
-----------------------------------------------------------
P1: (2; 1; -1) =B
E2: x =(3; 1; -2) + t * (2; 1; -1) + s * (-3; 1; -2)
P1 liegt auf der anderen Seite von E2 wie der Nullpunkt.
Abstand: 0.69282
-----------------------------------------------------------
P1: (-3; 1; -2) =C
E2: x =(3; 1; -2) + t * (2; 1; -1) + s * (-3; 1; -2)
P1 liegt auf der anderen Seite von E2 wie der Nullpunkt.
Abstand: 0.69282 | ..so falsch lag ich also gar nicht *freu*
Gruß
ytwinky _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 05.11.2006, 18:30 Titel: |
|
|
Danke für den Link, kann man gut gebrauchen!! |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|