abbrechen
Suchergebnisse werden angezeigt für 
Stattdessen suchen nach 
Meintest du: 
abbrechen
Suchergebnisse werden angezeigt für 
Stattdessen suchen nach 
Meintest du: 

Wir schätzen Ihren Input!
Bitte nehmen Sie an der Umfrage zu Archicad 28 Startbildschirm und Lerninhalte/Schnell-Tutorials teil

Programmierung
Alles über Programmierung in GDL und Python

Schnittpunkt 2 er Linien

Hmooslechner
Moderator
Ich steh einfach "auf dem Schlauch".


Wenn ich 2 Linien gegeben habe - müßte es doch einfach möglich sein, deren Schnittpunkt zu finden - über Vektorrechnung.

line2 x11, y11, x12, y12
line2 x21, y21, x22, y22


Ich habe es über die Winkelfunktionen versucht aber mir kocht schon das Hirn... 😐
Bei einer Linienfolge gehts hier um die Quadranten(Richtungen) und da steig ich dann aus..


Vielleicht hat bei Euch jemand eine einfache Lösung.
AC5.5-AC27EduAut, PC-Win10, MacbookAirM1, MacbookM1Max, Win-I7+Nvidia
7 ANTWORTEN 7
Anonymous
Nicht anwendbar
In deinem Code sind beide Linien mit der Nr. 2 versehen und nach dem was die Folge zeigt handelt es sich auch um ein und dieselbe Linie.
Also kann es keinen Schnittpunkt geben.
Zur Schnittpunktberechnung würde ich eine Funktion der Vektoren einzeln aufstellen und diese dann gleichsetzen, nach x auflösen und das Ergbniss in eine der Funktionen einsetzen und fertig.

Ich hoffe das ich das Problem verstanden habe, sonst will ich nichts gesagt haben.
Hmooslechner
Moderator
Leider nein - falsch verstanden.

Beide Linien haben jeweils ihre eigenen Koordinatenpaare

Offenbar gibt es - gab es folgendes:

http://www.graphisoft.com/ftp/techsupport/documentation/developer_docs/BasicLibraryDoc/10/Window-Mac...

Was aber nicht funktioniert.

Das APX scheint bei mir nicht zu arbeiten - und eigentlich sollt es ja auch in GDL direkt gehen. Wenn jemand mein GDL nutzen will und das APX ist nicht auf Seinem Rechner bringts ja auch nichts.
AC5.5-AC27EduAut, PC-Win10, MacbookAirM1, MacbookM1Max, Win-I7+Nvidia
Anonymous
Nicht anwendbar
Das Makro ist ab ca. AC14 (?) aus der Basic Library geflogen, weil es statt dessen jetzt ein AddOn gibt, das immer mitinstalliert wird.

Dein Problem findet sich auf jeder 2. Mathehilfeseite ausführlich beschrieben. Zwei Gleichungen mit 2 Unbekannten. Nach einer auflösen, in die andere einsetzen. Du musst bei einer der unendlich googlebaren Lösungen die Variablennamen substituieren.
Hmooslechner
Moderator
Wenns stattdessen ein Addon gibt - wie greife ich auf dessen Funktion zurück? Mit den Aufrufen der alten API gehts nicht.

Und Gleichungen mit 2 Unbekannten - da bin ich 40 Jahre davon entfernt..Die Mathe-Seiten habe ich schon durch aber da verstehe ich "Bahnhof" oder "Flughafen". GDL muß ich mir immer alles "zu Fuß " rausausknobeln, dann versteh ich auch - aber Mathe? Das genau ist ja mein Problem! 😁
AC5.5-AC27EduAut, PC-Win10, MacbookAirM1, MacbookM1Max, Win-I7+Nvidia
Anonymous
Nicht anwendbar
Das "alte" ist kein API, sondern eine Bibliothek mit Makroobjekten. Die Basic Library. Ist auch immer noch so. Das Addon ist tatsächlich ein echtes API. Schau mal hier: selfgdl
Das ist aber eine ziemliche Kanone um auf den Spatz "Linie verschneiden" zu schießen!

Und schau mal hier: openGDL
Hmooslechner
Moderator
Genau das wars - Danke! 😁 http://www.opengdl.org/Default.aspx?tabid=7746.

Mittlerweile habe ichs allerdings grafisch gelöst - .. brauche aber wesentlich mehr Zeilen als Deine Vektorlösung.
AC5.5-AC27EduAut, PC-Win10, MacbookAirM1, MacbookM1Max, Win-I7+Nvidia
Hmooslechner
Moderator
Doch anders gelöst - Mit Hilfe aus dem Internet:
Hier mal der Code für ein 2D - "Wand" - Element , das "sehr einfach" auf 3D zu erweitern wäre:

Der Vorteil: es verwendet keinerlei Koordinatenverschiebungen der Segmente - was bedeutet - alle Endpunkte sind als X und y Wert direkt verfügbar. Somit steht einer Verwendung in 3D auch mit Z-Werten nichts mehr im Weg. Ein echtes 3D-Geländer mit verschiedensten Segmenten wird möglich. (noch ohne Ausrundungen)

x,y, xp und yp sind als Anordnungen in der Parameterliste festzulegen
Breite als Distanzwert
nSeg als Anzahl der zu zeigenden Elemente

in der X-Anordnung ist es am Einfachsten - die Werte von 0 um 1 raufzuzählen.



uid = 1
eps = 0.0001

gosub "Polygonhotspots"
gosub "Linienzug"


end

"Polygonhotspots": !!! ========== hotspots ==========
for k = 1 to nSeg+1
!!! ----- X -----
hotspot2 0 , y[k], uid, x[k], 1+128 : uid = uid+1 ! centre
hotspot2 -1 , y[k], uid, x[k], 3 : uid = uid+1 ! ref
hotspot2 x[k], y[k], uid, x[k], 2 : uid = uid+1 ! moving


!!! ----- Y -----
hotspot2 x[k], 0 , uid, y[k], 1+128 : uid = uid+1 ! centre
hotspot2 x[k], -1 , uid, y[k], 3 : uid = uid+1 ! ref
hotspot2 x[k], y[k], uid, y[k], 2 : uid = uid+1 ! moving
next k

return





"Linienzug": !!! mal Führungslinie ohne Winkeldrehungen oder Koordinatenverschiebungen

for k = 1 to nSeg

line2 x[k],y[k], x[k+1],y[k+1] !! Nur reiner Linienzug

gosub "Parallele1"
gosub "Parallele2"
gosub "Schnittpunkte1"


gosub "Parallele Linien zeichnen"
next k

return !!!!Ende Führungslinie




"Parallele1":

x1=x[k] !!!Koordinaten im Segment rauspicken
x2=x[k+1]
y1=y[k]
y2=y[k+1]

dx = x2 - x1 !!!x+y Distanz der Punkte des Segmentes
dy = y2 - y1

if dx < 0 then dx = -dx
if dx = 0 then dx=eps

if dx < eps and dx < -eps then
Winkelsegment = 90
else
WinkelSegment = atn(dy/dx)
endif

RewinSeg = WinkelSegment - 90

Diagonale1 = sqr (dx^2+dy^2) !!!!Distanz der Punkte des Segmentes

P1x1 = -breite * cos(RewinSeg)+x1
P1y1 = -breite * sin(RewinSeg)+y1
p1x2 = -breite * cos(RewinSeg)+x2
p1y2 = -breite * sin(RewinSeg)+y2


if x2 < x1 then
P1y1 = breite * sin(RewinSeg)+y1
p1y2 = breite * sin(RewinSeg)+y2
else
endif


!line2 p1x1, p1y1, p1x2, p1y2

return





"Parallele2":

x11=x[k+1] !!!Koordinaten im Segment rauspicken
x21=x[k+2]
y11=y[k+1]
y21=y[k+2]

dx1 = x21 - x11 !!!x+y Distanz der Punkte des Segmentes
dy1 = y21 - y11

if dx1 < 0 then dx1 = -dx1
if dx1 = 0 then dx1=eps

if dx1 < eps and dx1 < -eps then
Winkelsegment1 = 90
else
WinkelSegment1 = atn(dy1/dx1)
endif

RewinSeg1 = WinkelSegment1 - 90

Diagonale2 = sqr (dx1^2+dy1^2) !!!!Distanz der Punkte des Segmentes

P2x1 = -breite * cos(RewinSeg1)+x11
P2y1 = -breite * sin(RewinSeg1)+y11
p2x2 = -breite * cos(RewinSeg1)+x21
p2y2 = -breite * sin(RewinSeg1)+y21


if x21 < x11 then
P2y1 = breite * sin(RewinSeg1)+y11
p2y2 = breite * sin(RewinSeg1)+y21
else
endif


!line2 p2x1, p2y1, p2x2, p2y2

return










"Schnittpunkte1": !!!!Nicht von mir erfunden!

getValues = 1
put p1x1, p1y1, p1x2, p1y2, p2x1, p2y1, p2x2, p2y2
gosub "Schnittpunkt zweier Linien - 2D"
if not(parallelLines~5) then

spx = x~5
spy = y~5
!circle2 spx, spy, 0.1

xp[k] = spx
yp[k] = spy

else
line2 0,0,1,0

endif

return






"Schnittpunkt zweier Linien - 2D": !!!!Nicht von mir erfunden!

if getValues then
x11~5 = get(1): y11~5 = get(1)
x12~5 = get(1): y12~5 = get(1)
x21~5 = get(1): y21~5 = get(1)
x22~5 = get(1): y22~5 = get(1)
getValues = 0
endif
u1x~5 = x12~5 - x11~5
u1y~5 = y12~5 - y11~5
u2x~5 = x22~5 - x21~5
u2y~5 = y22~5 - y21~5
!Prüfung ob parallel und Punkt finden
D~5 = u2x~5*u1y~5 - u1x~5*u2y~5
if abs(D~5) < eps then
parallelLines~5 = 1
else
parallelLines~5 = 0
endif

!Schnittpunkt von nicht parallelen Linien:
if not(parallelLines~5) then
t~5 = (u1x~5*(y21~5 - y11~5) - u1y~5*(x21~5 - x11~5))/D~5
x~5 = x21~5 + t~5*u2x~5
y~5 = y21~5 + t~5*u2y~5
endif

return



"Parallele Linien zeichnen":

P1x1 = -breite * cos(RewinSeg)+x1 !!Koordinaten für die
P1y1 = -breite * sin(RewinSeg)+y1 !!Parllelen - Enden
p1x2 = -breite * cos(RewinSeg)+x2
p1y2 = -breite * sin(RewinSeg)+y2

if x2 < x1 then !!Umkehrung verhindern
P1y1 = breite * sin(RewinSeg)+y1 !!bei x2 > x1
p1y2 = breite * sin(RewinSeg)+y2
else
endif

if k = 1 then
line2 x[k],y[k], p1x1, p1y1 !!Anfangsabschlußlinie
line2 p1x1, p1y1, xp[k], yp[k] !!Dann zum nächsten Schnittpunkt
line2 xp[k], yp[k], x[k+1],y[k+1] !!Winkelhalbierende
else
if k < nSeg then
line2 xp[k], yp[k], xp[k-1], yp[k-1] !!Von Schnittpunkt zu Schnittpunkt
line2 xp[k], yp[k], x[k+1],y[k+1] !!Winkelhalbierende
else
endif
endif
if k = nSeg then

line2 xp[k-1], yp[k-1], p1x2, p1y2 !!Von Schnittpunkt zu ReWi-Punkt
line2 x2, y2, p1x2, p1y2

else
endif
endif


return



Bei Prüfung zeigt es den Hinweis, " Die Verwendung von realen Typen kann zu Präzisionsproblemen...." - funktioniert aber trotzdem. Das kommt davon:
eps = 0.0001

und
	if dx = 0 then dx=eps

Damit verhindere ich, dass ein Punkt eines Wertes in X-Richtung genau einem Nachbarn entspricht. (Es wird ganz leicht schief gezeichnet, damit sich kein Tan 90° bildet. - Fällt aber nicht auf. 😁 .)
AC5.5-AC27EduAut, PC-Win10, MacbookAirM1, MacbookM1Max, Win-I7+Nvidia