zufälliger Punkt im Dreieck

Übersicht Sonstiges Smalltalk

Neue Antwort erstellen

juse4pro

Betreff: zufälliger Punkt im Dreieck

BeitragSo, Jul 25, 2010 23:39
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jul 26, 2010 0:00
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jul 26, 2010 0:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Ö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

BeitragMo, Jul 26, 2010 0:27
Antworten mit Zitat
Benutzer-Profile anzeigen
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]

a:Vector2
b:Vector2
c:Vector2

ab = (b.x-a.x,b.y-a.y)
ac = (c.x-a.x,c.y-a.y)


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

BeitragMo, Jul 26, 2010 2:34
Antworten mit Zitat
Benutzer-Profile anzeigen
schonmal sehr praktisch für die kommende abitur phase Wink
Danke ich werd mal versuchen, es in einem Beispiel code zu verwirklichen

mfg: juse
Portfolio |LinkedIn |XING

Ana

BeitragMo, Jul 26, 2010 2:43
Antworten mit Zitat
Benutzer-Profile anzeigen
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
user posted image


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

BeitragMo, Jul 26, 2010 4:07
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jul 26, 2010 4:41
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink
Portfolio |LinkedIn |XING

ComNik

BeitragMo, Jul 26, 2010 4:44
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink
Ich bin jetzt allerdings zu müde, mir einen eleganten Ansatz auszudenken, tut mir leid..

lg
ComNik
WIP: Vorx.Engine

Ana

BeitragMo, Jul 26, 2010 6:29
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jul 26, 2010 6:49
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jul 26, 2010 6:50
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jul 26, 2010 6:59
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink
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

BeitragMo, Jul 26, 2010 7:10
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jul 26, 2010 8:52
Antworten mit Zitat
Benutzer-Profile anzeigen
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.
user posted image
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

BeitragMo, Jul 26, 2010 10:06
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Wink

Ich denke ich werde ChaosCoder's Methode probieren, Danke an alle Wink
Das scheint mir das einleuchtenste
Portfolio |LinkedIn |XING

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Jul 26, 2010 10:18
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jul 26, 2010 10:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke hectic.. Very Happy

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

Neue Antwort erstellen


Übersicht Sonstiges Smalltalk

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group