cybton.com
Über uns | Jobs | Werbung | Sitemap | AGB | Impressum | Hilfe ?
 Kostenlos anmelden)
Forum
Aktuellste Beiträge
Forenregeln

Community
BB-Codes
Tags
Chat
Suche (Web)
Wer ist online?
Top-User

Basar


Statistik
Mitglieder gesamt: 68162
Mitglieder online: 7
Gäste online: 1
mehr...

Anzeige
Forum » Forum: Website & Webprogrammierung » Thread: JS: Brauche komplizierte math. Flächenberechnung

Thread: JS: Brauche komplizierte math. Flächenberechnung

Seite 2 von 212

16.05.2008 08:10 Uhr

 

Status: offline
Morgen zusammen!

Ich frage mich nun langsam wieso ich eigentlich über die Fläche eines Dreiecks rede, wenn ich doch dann Vielecke berechnen müsste, das versch. Zonen im Spielbereich aus Dreiecksvermaschung total umständlich wären.

Es gibt auch Techniken, mehreckige Fläche auf diese Weise zu berechnen. Jedoch bräuchte ich ein Verfahren, dass auch Flächen mit Nuten, Einsparungen, etc. berechnen kann.
16.05.2008 09:22 Uhr

 

Status: offline
Ob ein Punkt innerhalb oder außerhalb eines Beliebigen 2D-Körpers bzw 2D-Polygons liegt kann man recht einfach berechnen. Hab da in meiner Ausbildung mal so einen Algorithmus in VisualBasic6 für meinen Ausbilder geschrieben. Leider kann ich den hier nicht mehr auf meinem Rechner finden (vielleicht reiche ich den später noch nach). Aber ich erklär den mal kurz:

Du benötigst erst mal die Koordinaten des Punktes der geprüft werden soll, weiter brauchst du jeden Punkt des Polygons. Anschließend bildest du (wenn ich mich recht erinner, mit dem zu testenden Punkt als Koordinatenursprung) die Summe über den Winkel zu den Punkten des Polygons mittels arcsin(). Als Lösung kannst du zwei unterschiedliche Werte des Gesamtwinkels erhalten: Beträgt dieser Winkel nun 360°, so liegt der Punkt innerhalb des Polygons, ist der Winkel 0°, so liegt der Punkt außerhalb.
Zu beachten dabei ist, dass ein Computer nur fehlerbehaftet mit Fließkommazahlen rechnen kann, so dass man durchaus Abweichungen von mehreren Grad erhalten kann, und dass bei der Verwendung von arcsin() den Winkel in Rad zurückgibt und du den Wert erst noch in Grad umrechnen musst, falls du lieber mit Grad rechnest.
___________________________
Programmieren ist eine Sucht deren Rausch ein Gefühl der Macht ist... sofern man den Computer bezwingt. Gefährliche Nebenwirkungen: Verstärkter Kaffee-Konsum, erhöhter Ehrgeiz und ggf. Wutausbrüche und verknotete Gehirnwindungen.
16.05.2008 09:59 Uhr

 

Status: offline
Danke Hangman!

Das klingt interessant und scheint eine geeignete Lösung zu sein. Also ich habe alles nochmal durchgedacht, ich nehme keine Dreiecke, sondern gleich Flächen mit beliebig vielen Punkten, wozu auch Dreiecke? ja vielleicht findest du noch den Script, wenn nicht könntest du mir ja die genaue Bezeichnung des Verfahrens nennen oder auf andere Seiten, die sowas erklären verweisen. Übrigens, funktioniert diese Methode bei absolut jeder Flächenform? zB. auch wenn Zick-Zacks an der Seite sind und sowas ? Sonst hab ich am Schluss noch Tausend Bugs im Spiel!  :tongue: 
1 mal bearbeitet
16.05.2008 11:41 Uhr

 

Status: offline
Du kannst das Verfahren natürlich auch auf kleinere Bereiche anwenden, indem du zB irgendwie Beziehungen zwischen einzelnen Flächen herstellst. Dadurch brauchst du dann nicht alle Flächen berechnen, was die Performance heben könnte. Also zB eine Fläche mit wenigen Ecken, die wiederum mehrere Flächen mit vielen Polygonen enthalten kann. Liegt der Punkt außerhalb der Fläche mit wenig Punkten, so liegt der Punkt natürlich auch außerhalb aller enthaltenen Flächen

Name des Verfahrens: KA. Ist mir irgendwann mal in der Mittagspause eingefallen :)

Das Verfahren sollte bei jeder beliebigen Form funktionieren.

UND: Du hast Glück. Hab den Code in meinen Backups gefunden
+ diff:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
Option Explicit
 
Public Type Vector
    x As Single
    y As Single
End Type
 
Dim loPolygon() As Vector
Dim loTest As Vector
Dim liPolysize As Long
Dim lbTestSet As Boolean
 
Public Sub init()
    loTest.x = 0
    loTest.y = 0
    liPolysize = -1
    lbTestSet = False
End Sub
 
Public Sub clearPolygon()
    ReDim loPolygon(0)
    liPolysize = -1
    lbTestSet = False
    Form1.picGrid.Cls
    drawGrid
End Sub
 
Public Sub addPolyVector(x As Single, y As Single)
    Dim vec As Vector
    vec.x = x
    vec.y = y
    liPolysize = liPolysize + 1
    ReDim Preserve loPolygon(liPolysize)
    loPolygon(liPolysize) = vec
End Sub
 
Public Sub setTestVector(x As Single, y As Single)
    loTest.x = x
    loTest.y = y
    lbTestSet = True
End Sub
 
Public Sub drawGrid()
    Dim i As Integer
    Form1.picGrid.DrawWidth = 1
    Form1.picGrid.ForeColor = RGB(200, 200, 200)
    For i = 1 To Form1.picGrid.ScaleWidth - 1
        Form1.picGrid.Line (i, 0)-(i, Form1.picGrid.ScaleHeight)
    Next i
    For i = 1 To Form1.picGrid.ScaleHeight - 1
        Form1.picGrid.Line (0, i)-(Form1.picGrid.ScaleWidth, i)
    Next i
End Sub
 
 
Public Sub Repaint()
    Dim i As Integer
    Form1.picGrid.Cls
 
    drawGrid
    
    If (liPolysize >= 0) Then
        Form1.picGrid.ForeColor = RGB(0, 0, 0)
        Form1.picGrid.DrawWidth = 5
        Form1.picGrid.PSet (loPolygon(0).x, loPolygon(0).y)
        Form1.picGrid.DrawWidth = 1
        
        For i = 0 To UBound(loPolygon) - 1
            Form1.picGrid.DrawWidth = 5
            Form1.picGrid.PSet (loPolygon(i + 1).x, loPolygon(i + 1).y)
            Form1.picGrid.DrawWidth = 1
            Form1.picGrid.Line (loPolygon(i).x, loPolygon(i).y)-(loPolygon(i + 1).x, loPolygon(i + 1).y)
        Next i
        Form1.picGrid.Line (loPolygon(UBound(loPolygon)).x, loPolygon(UBound(loPolygon)).y)-(loPolygon(0).x, loPolygon(0).y)
    End If
    
    If (lbTestSet) Then
        If (isInPolygon()) Then
            Form1.picGrid.ForeColor = RGB(0, 200, 0)
            Form1.lblStatus.Caption = "Testpunkt (" & Round(loTest.x, 2) & ";" & Round(loTest.y, 2) & ") liegt innerhalb des Polygons"
 
        Else
            Form1.picGrid.ForeColor = RGB(200, 0, 0)
            Form1.lblStatus.Caption = "Testpunkt (" & Round(loTest.x, 2) & ";" & Round(loTest.y, 2) & ") liegt außerhalb des Polygons"
        End If
        Form1.picGrid.DrawWidth = 5
        Form1.picGrid.PSet (loTest.x, loTest.y)
    End If
End Sub
 
Public Function isInPolygon() As Boolean
    Dim i As Integer
    Dim a As Vector
    Dim b As Vector
    Dim phi As Double
    Dim nexti As Long
    Dim tmp As Double
    
    phi = 0
    
    If (liPolysize > 0) Then
        ' es werden ausgehend vom testpunkt jeweils zwei aufeinanderfolgende punkte im polygon betrachtet:
        ' nach ermitteln der richtungsvektoren der geraden zwischen dem testpunkt und punkt i im polygon,
        ' sowie testpunkt und punkt i+1 im polygon kann der schnittwinkel der beiden richtungsvektoren
        ' berechnet werden. alle winkel werden summiert. liegt der testpunkt innerhalb des polygons, so
        ' ergibt die summe aller winkel (+-)360°, da beim ermitteln der schnittwinkel einmal vollständig
        ' um den testpunkt gedreht werden muß.
        ' liegt der testpunkt außerhalb, so ergibt die summe aller winkel genau 0, da nach links genauso
        ' weit gedreht werden muß, wie nach rechts.
        For i = 0 To UBound(loPolygon)
            ' es werden immer 2 benachbarte punkte des polygons p0..pn benötigt, um im letzten schritt die
            ' punkte pn und p1 zu erhalten wird zunächst der folgevektor pi+1 mit hilfe des modulo operators
            ' ermittelt. dadurch erhält man im n-ten schritt wieder den vektor p0 des polygons
            nexti = (i + 1) Mod (UBound(loPolygon) + 1)
            
            ' richtungsvektor der geraden vom testpunkt zum i-ten punkt im polygon
            a.x = loPolygon(i).x - loTest.x
            a.y = loPolygon(i).y - loTest.y
            ' richtungsvektor der geraden vom testpunkt zum (i+1)-ten punkt im polygon
            b.x = loPolygon(nexti).x - loTest.x
            b.y = loPolygon(nexti).y - loTest.y
            
            ' die geraden mit richtungsvektoren a und b schneiden sich zwangsläufig im schnittpunkt loTest
            ' wodurch der schnittwinkel zwischen den richtungsvektoren a und b wie folgt berechnet werden
            ' kann:
            '              /  (a*b)  \          /           a.x*b.x + a.y*b.y           \
            ' phi = arccos | ------- | = arccos | ------------------------------------- |
            '              \ |a|*|b| /          \ sqrt(a.x^2+a.y^2) * sqrt(b.x^2+b.y^2) /
            ' da arccos das ergebnis in rad liefert muß anschließend noch durch PI/180 dividiert werden um
            ' das ergebnis in grad zu erhalten. da PI in vb nicht deklariert ist, wird der wert duch 4*arctan(1)
            ' ermittelt.
            tmp = arccos(((a.x * b.x + a.y * b.y) / ((a.x ^ 2 + a.y ^ 2) ^ (1 / 2) * (b.x ^ 2 + b.y ^ 2) ^ (1 / 2)))) / (4 * Atn(1) / 180)
            
            ' anschließend wird noch das vorzeichen des winkels benötigt. dies erhält man aus den koordinaten
            ' des testpunktes und der beiden punkte, die aktuell geprüft werden.
            tmp = tmp * Sign((loPolygon(i).x - loTest.x) * (loPolygon(nexti).y - loTest.y) - (loPolygon(i).y - loTest.y) * (loPolygon(nexti).x - loTest.x))
            
            ' nun nur noch den neu berechneten winkel auf die bisher berechnete summe addieren
            phi = phi + tmp
        Next i
        ' ist der winkel 0° (alle winkel heben sich auf), so liegt der punkt außerhalb des polygons, in allen
        ' anderen fällen beträgt der winkel 360° und der testpunkt liegt innerhalb des polygons.
        ' aufgrund der schlechten kondition bei der berechnung etwas spielraum erlauben. besser wäre es, den
        ' absoluten fehler zu berechnen und die toleranz nur in diesem bereich zu gestatten.
        isInPolygon = Not (phi < 5 And phi > -5)
    End If
End Function
 
' arcus cosinus mit hilfe anderer trigonometrischen funktionen berechnen, da arccos in vb6 fehlt
Public Function arccos(n As Double) As Double
    arccos = Atn(-n / Sqr(-n * n + 1)) + 2 * Atn(1)
End Function
 
' funktion zum ermitteln des vorzeichens einer zahl (rückgabe: -1;0;1)
Public Function Sign(n As Double) As Integer
    If (n < 0) Then
        Sign = -1
    ElseIf (n > 0) Then
        Sign = 1
    Else
        Sign = 0
    End If
End Function
1 mal bearbeitet
___________________________
Programmieren ist eine Sucht deren Rausch ein Gefühl der Macht ist... sofern man den Computer bezwingt. Gefährliche Nebenwirkungen: Verstärkter Kaffee-Konsum, erhöhter Ehrgeiz und ggf. Wutausbrüche und verknotete Gehirnwindungen.
16.05.2008 11:46 Uhr

 

Status: offline
Wow Danke! Es geht nichts über Backups! :-)

Nun wirds spannend beim Übersetzten in Javascript.
16.05.2008 11:48 Uhr

 

Status: offline
Zitat:
Nun wirds spannend beim Übersetzten in Javascript.

Ja. Aber das ist ja dann nicht mehr mein Problem  :lol: 

Objektorientiert Javascript programmieren funktioniert besser als in VB6. Der Aufwand kann sich sehr in Grenzen halten.
1 mal bearbeitet
___________________________
Programmieren ist eine Sucht deren Rausch ein Gefühl der Macht ist... sofern man den Computer bezwingt. Gefährliche Nebenwirkungen: Verstärkter Kaffee-Konsum, erhöhter Ehrgeiz und ggf. Wutausbrüche und verknotete Gehirnwindungen.
16.05.2008 12:04 Uhr

 

Status: offline
ich seh's mal so, wenigstens hab ich jetzt was Job fürs Wochenende! :-)

Jetzt aber geh ich erst grillen!
2 mal bearbeitet
Seite 2 von 212
Ähnliche Threads Forum Ähnlichkeitsgrad
 Mikronation: Königreich Pektonien Das Promotion-Board 2
 Formular Spiel (mit Javascript) Website & Webprogrammierung 2
 Dateicontainer für HTML-Games-Server Softwareprogrammierung 2
 Kleines Javascript-Problem mit Menü Website & Webprogrammierung 2
 aufklappbares menü macht probleme Website & Webprogrammierung 2
 Mathematische Funktion für PHP aufbereiten Website & Webprogrammierung 2
 [gelöst] Mit Javascript automatisch in den Vollbildmodus wechseln - 200 cyDots Website & Webprogrammierung 1
Passende eBook-Abschnitte eBook Ähnlichkeitsgrad
Textabsätze XHTML 1
nach obennach oben

Copyright © 2009 cybton-network

Google
Partner: #Musik - Dein Internetradio - nexem. - .wir machen news - Your-Book.net - Dein kostenloses Gästebuch
ANEXIA - PHP Entwicklung - Dockers - s.Oliver Schuhe - Think Schuhe - der eigene Weg - Dorfen - Paul Green Schuhe - Bequeme Geox - Web-Entwicklung - Schueler.CC @ nexem