zufälliger Punkt im Dreieck
Übersicht

![]() |
juse4proBetreff: zufälliger Punkt im Dreieck |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,,
ich habe mir schon sehr lange gedanken gemacht über mein problem: 'Auf welche Art und Weise erhalte ich einen zufälligen Punkt in einem Dreieck, welches auf 3 Punkten beschrieben ist...' Gibts da eine Art Algorythmus? Hoffe ihr könnt mir helfen |
||
Portfolio |LinkedIn |XING |
![]() |
ChaosCoder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bist du mit Vektoren vertraut?
Wenn ja, wäre folgende Methode recht einfach: Suche dir den Punkt A des Dreiecks aus. Zusätzlich benötigst du die Vektoren (ab, ac) von diesem Punkt zu den anderen Eckpunkten. Du berechnest einen zufälligen Wert r zwischen 0 und 1 und einen zufälligen Wert s zwischen 0 und 1-r. Einen zufälligen Punkt bekommst du dann durch: (Vektor a)+r*ab+s*ac Ich weiß grad nicht ob jeder Punkt gleichwahrscheinlich ist... Ich denke mal, dass es zu den Ecken des Dreiecks immer unwahrscheinlicher wird... Aber vielleicht hilft dir das ja trotzdem schonmal weiter. |
||
Projekte: Geolaria | aNemy
Webseite: chaosspace.de |
![]() |
juse4pro |
![]() Antworten mit Zitat ![]() |
---|---|---|
Öhm dankesehr, ich werds mal 'probieren'...
Vektoren hatten wir eigentlich noch nicht, aber nene paar Dinge weis ich (und ich finds nicht schwert) Vektoren sind Matrizen mit einer Spalte und werden meistens in der Physik in der Kinematik oder Dynamik zur Veranschaulichung von Kraft verwendet... Also wie ich die Vektoren ab und ac errechne wüsste ich jetzt spontan nicht ^^ |
||
Portfolio |LinkedIn |XING |
![]() |
ComNik |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also Vektoren sind so gesehen nur "Zahlen" (Skalare) die eben nicht nur einen Wert (die Länge des Vektors) sondern auch eine Richtung haben. Zu vergleichen vllt mit komplexen Zahlen...
ab und ac errechnen ist nicht schwer: BlitzMax: [AUSKLAPPEN]
Warum b - a und nicht a-b? Stell dir vor du müsstest den Vektor von a= (5,5) nach b=(10,10) errechnen. Wenn du jetzt ab = (10-5,10-5) rechnest, erhältst du ab = (5,5) und wenn du diesen Vektor nun mit a addierst: a + ab = (5,5) + (5,5) = (5+5,5+5) erhältst du (10,10) = b lg ComNik |
||
WIP: Vorx.Engine |
![]() |
juse4pro |
![]() Antworten mit Zitat ![]() |
---|---|---|
schonmal sehr praktisch für die kommende abitur phase ![]() Danke ich werd mal versuchen, es in einem Beispiel code zu verwirklichen mfg: juse |
||
Portfolio |LinkedIn |XING |
![]() |
Ana |
![]() Antworten mit Zitat ![]() |
---|---|---|
ich glaube die Verteilung ist recht unschön auf diese Art oder nicht?
Der Erwartungswert von von r wäre dann doch 0.5 und der von s 0.25 wäre der dann nicht "r - Seite - mitte" unteres Drittel? (mal von einem Gleichseitigen ausgehend) und sollte der Erwartungswert nicht zentral liegen? Kann aber auch sein das ich mich täusche aber wenn ich das so aufzeichne scheint mir das nicht stimmig (hoffe man erkennt was ich meine Meine Idee wäre ein Rechteck zu machen, das Rechteck diagonal zu teilen und jeden Punkt an der Diagonalen Spiegeln, der auf der "nicht-ausgesuchtes-Dreieck-Seite" ist (Das findet man raus in dem man schaut ob Y > X ist wenn du von links oben nach rechts unten teilst) Falls ja, X und Y vertauschen. Das geht nur bei rechtwinkligen, aber die verschiebung kann man ja noch nachträglich dazu addieren.(Hier bei drauf achten das sie nach oben/unten hin zu und ab nimmt) Macht das Sinn? Vielleicht ein wenig spät für sowas^^ |
||
![]() |
ComNik |
![]() Antworten mit Zitat ![]() |
---|---|---|
Meine Idee, wäre etwas Brute Force und nur für kleinere Dreicke geeignet:
AABB berechnen While kein Punkt gefunden zufälligen Punkt im Rechteck wählen Wenn Punkt im Dreieck liegt Return Punkt Ansonten Continue Wend Ich bin jetzt bisschen müde, aber wenn du dich dafür entscheides kann ich dir bei den Funktionen helfen. lg ComNik |
||
WIP: Vorx.Engine |
![]() |
juse4pro |
![]() Antworten mit Zitat ![]() |
---|---|---|
Okay, soweit sogut, aber diese Art von Methode möchte ich grade vermeiden (Einen ganz zufälligen Punkte wählen, und wenn er ausserhalb ist, das ganz nochmal [rekursiv])
Ich denke ich werde mich lieber mit der Vektoressache auseinandersetzten ![]() |
||
Portfolio |LinkedIn |XING |
![]() |
ComNik |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sehr ineffizent ist die Methode nicht, da die AABB ja das Dreieck ziemlich knapp einschliesst.
Aber der Vektor Ansatz ist eleganter, einfach warten bis sich ein Profi dazu äussert ![]() Ich bin jetzt allerdings zu müde, mir einen eleganten Ansatz auszudenken, tut mir leid.. lg ComNik |
||
WIP: Vorx.Engine |
![]() |
Ana |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich hab mal beide Varianten geschrieben und miteinander verglichen, und ja der Vektor ist nicht normalverteilt sondern hat die meisten in der richtung r, spiegeln geht gut, allerdings kommt halt der Fakt dazu, dass es zumindest so nur für Rechtwinklige geht.
Code: [AUSKLAPPEN] Dim vektorA0# (2)
Dim vektorAB# (2) Dim vektorAC# (2) Graphics 800,600 vektorA0 (0) = 1 vektorA0 (1) = 1 bx# = 1 by# = 5 cx# = 5 cy# = 5 SeedRnd MilliSecs() vektorAB (0) = bx - vektorA0(0) vektorAB (1) = by - vektorA0(1) vektorAC (0) = Cx - vektorA0(0) vektorAC (1) = Cy - vektorA0(1) ;(Vektor a)+r*ab+s*ac Punkte = 1000 p = punkte Line vektora0(0) * 100,vektora0(1) * 100,cx * 100,cy * 100 Line vektora0(0) * 100,vektora0(1) * 100,bx * 100,by * 100 Line bx * 100,by * 100,cx * 100,cy * 100 Line 100,100,500,100 Line 500,100,500,500 Color 255,0,255 Print "Vektormethode" Repeat Punkte = punkte - 1 r# = Rnd (0,1) s# = Rnd (0,(1-r)) x# = vektorA0(0) + r * vektorab(0) + s * vektorAC(0) y# = vektorA0(1) + r * vektorab(1) + s * vektorAC(1) x = x * 100 y = y * 100 Line x-1,y-1,x+1,y+1 Line x+1,y-1,x-1,y+1 Until punkte <= 0 Color 0,255,255 Print "Spiegelung" Repeat p = p - 1 x = Rand(100,500) y = Rand(100,500) If y > x Then h = x x = y y = h EndIf Line x-1,y-1,x+1,y+1 Line x+1,y-1,x-1,y+1 Until p <= 0 WaitKey() |
||
- Zuletzt bearbeitet von Ana am Mo, Jul 26, 2010 6:49, insgesamt einmal bearbeitet
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Methode von ChaosCoder ist durchaus richtig, wenn auch mit einem Schönheitsfehler: Man müsste sowohl r als auch s als Zufallszahl zwischen 0 und 1 generieren und sie neu berechnen lassen, wenn r + s > 1.
Damit werden zwar im Durchschnitt die Hälfte der Fälle nochmal neu durch den Zufallsgenerator geschickt, aber dafür hat man dann auch eine wunderschöne Verteilung. |
||
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 |
![]() |
Ana |
![]() Antworten mit Zitat ![]() |
---|---|---|
Naja das nimmt sich dann ja nicht viel dazu direkt nen Punkt zu machen und zu schauen ob der im Dreieck ist.
Und man muss doppelt soviele durchläufe machen oder nicht? Schließlich liegt der Werte bereich von r + s bei 2 und darf nicht > 1 sein |
||
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nun, schnell zwei Zahlen zu überprüfen geht relativ schnell, wenn man bedenkt, was ein Punkt-im-Dreieck Test an Zeit kosten würde.
Ist auf jeden Fall die effizienteste Methode. Klar könnte man es auch über deine Rechtecks-Methode machen, allerdings müsste man dann auch jeweils prüfen, ob der Punkt in der richtigen Hälfte liegt und ihn dann noch spiegeln, wenn dem nicht so ist. Für beliebig gedrehte Dreiecke keine leichte Aufgabe, zumal die Methode ja sowieso nur für rechtwinklige Dreiecke funktioniert. Zitat: Und man muss doppelt soviele durchläufe machen oder nicht?
Ich sagte ja, dass man ungefähr die Hälfte nochmal neu berechnen muss ![]() |
||
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 |
![]() |
Ana |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also ich hab mal die Laufzeiten verglichen von den beiden und Spiegeln ist konstant 1/9 schneller, aber stimmt schon wenn es kein Rechteck ist, muss man ein wenig mehr rechnen | ||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mein Ansatz wäre:
Die 3 Linien des Dreiecks als Geraden zu sehen und als grafische Funktion zu beschreiben Zitat: y=mx+t
Da sollte sich aus den jeweils 3 bekannten Punkten A,B bwz A,C bzw B,C eine Formel finden lassen. Nun errechnet man einen Punkt M als "Mittelpunkt" des Dreiecks. z.b. über den Schnittpunkt der Mittelsenkrechten, Winkelhalbierenden, etc um einen Punkt zu haben der 100% im Dreieck liegt. Dieser Punkt hat nun eine bestimmte Lage im Bezug zu jeder dieser Geraden. Nun muss man nur noch feststellen auf welcher Seite der 3 Geraden dieser Punkt M jeweils liegt. z.b. wäre sein y bei gleichem x kleiner als das entsprechende y der Gerade. Der Punkt erhält also die Beschreibung, z.b.: Zitat: Gerade AB:negativ
Gerade AC:positiv Gerade BC:positiv Ein gesuchter Punkt X müsste nun bei allen 3 Geraden auf "der selben Seite" liegen. Als die gleiche Beschreibung ergeben, dann wäre er 100% im Dreieck. |
||
![]() |
juse4pro |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ja Midimaste, das ist auch ein guter Ansatz, jedoch lege ich vorallem Wert auf Performance, und zu berechnen, was die Winkelhalbierenden oder sonstiges eines beliebigen Dreiecks sind, welches ausserdem nur aus Punkten beschrieben ist, würde hier zu lange dauern. ![]() Ich denke ich werde ChaosCoder's Methode probieren, Danke an alle ![]() Das scheint mir das einleuchtenste |
||
Portfolio |LinkedIn |XING |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Methode von ChaosCoder hat keine gleichmäßige Verteilung, erspart jedoch 50% Abfall der neu berechnet werden muss.
Code: [AUSKLAPPEN] Graphics 800,600,0,2
SetBuffer FrontBuffer() Dim DX(2) Dim DY(2) Local X# Local Y# Local C% Local W1# Local W2# While Not KeyHit(1) Color 96,96,96 DX(0)=Rand(0,799):DY(0)=Rand(0,599) DX(1)=Rand(0,799):DY(1)=Rand(0,599) DX(2)=Rand(0,799):DY(2)=Rand(0,599) Rect DX(0)-4,DY(0)-4,9,9,0 Rect DX(1)-4,DY(1)-4,9,9,0 Rect DX(2)-4,DY(2)-4,9,9,0 Line DX(0),DY(0),DX(1),DY(1) Line DX(1),DY(1),DX(2),DY(2) Line DX(2),DY(2),DX(0),DY(0) Color 240,240,240 For C=0 To 999 W1=Rnd(0,1) W2=Rnd(0,1-W1) X=DX(0)+(DX(1)-DX(0))*W1+(DX(2)-DX(0))*W2 Y=DY(0)+(DY(1)-DY(0))*W1+(DY(2)-DY(0))*W2 Plot X,Y Next ; Delay 2000 Flip 0 Cls Wend End Ansonsten: Code: [AUSKLAPPEN] For C=0 To 999
W1=Rnd(0,1) W2=Rnd(0,1) If (W1+W2)<1 Then X=DX(0)+(DX(1)-DX(0))*W1+(DX(2)-DX(0))*W2 Y=DY(0)+(DY(1)-DY(0))*W1+(DY(2)-DY(0))*W2 Plot X,Y End If Next |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
![]() |
juse4pro |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke hectic.. ![]() Aber das ist eigentlich garkein Problem, das mit der ungleichmäßgen Verteilung Kommt wenigstens nen bissl Abwechselung rein, in mein NPC-Spawn System |
||
Portfolio |LinkedIn |XING |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group