Code: Alles auswählen
; Lage des Cursors in Bezug zu einer geschlossenen Kontur
;
; Autor : alter Mann
; Datum : 11.11.08
;
; Demo
;
Structure lPkt
X.l
Y.l
EndStructure
#LONG_MIN =(-2147483647 - 1) ; minimum (signed) long value
#LONG_MAX =2147483647 ; maximum (signed) long value
EnableExplicit
;##############################################################################
;Funkt.: Lage eine Punktes in Bezug auf eine geschlossene Kontur
;E.Par.: X,Y Punktkoordinate
; Anz Anzahl Punkte der Kontur
; Kontur(1).lPkt Feld mit Punkten der Punktfolge
; Abs Randgenauigkeit
;F.Code: -2 falsche Eingabe
; -1 Punkt liegt aussen
; 0 Punkt liegt auf Rand
; 1 Punkt liegt innen
;##############################################################################
Procedure.l PBGeo_PktInKontur (X.l, Y.l, Anz.l, Kontur.lPkt(1), Abs.l)
Protected Ret.l=0, A0.l, A1.l, A2.l, Vx.l, Vy.l, i.l
Protected Abs2.q=Abs, A3.q, A4.q, A.q, H.q, Vx1.q,Vy1.q,Vx2.q,Vy2.q
Abs2 = Abs2*Abs2 + 1
If Anz < 3 And Abs < 0
ProcedureReturn -2
EndIf
; Anfangspunkt auf gleicher Hoehe
A1 = Kontur(0)\X - X
A0 = A1
If A0 = 0
; suche Punkt auf anderer Hoehe
For i = Anz - 1 To 1 Step -1
A0 = Kontur(i)\X - X
If A0 <> 0
Break
EndIf
Next i
; alle Punkte auf gleicher Hoehe -> Punkt innerhalb ?
If A0 = 0
A1 = Kontur(0)\Y
A2 = A1
For i = 1 To Anz-1 Step 1
If Kontur(i)\Y < A1
A1 = Kontur(i)\Y
ElseIf Kontur(i)\Y > A2
A2 = Kontur(i)\Y
EndIf
If Y >= A1-Abs And Y <= A2+Abs
ProcedureReturn 0
EndIf
Next i
ProcedureReturn -1
EndIf
EndIf
For i=1 To Anz-1 Step 1
A2 = Kontur(i)\X - X
Vx = Kontur(i)\X - Kontur(i-1)\X
Vy = Kontur(i)\Y - Kontur(i-1)\Y
If A1 <> 0
A = A1
Else
A = A0
EndIf
If A * A2 < 0
H = A1 - A2
A3 = Kontur(i-1)\Y * H + A1 * Vy
A4 = Y * H
If (H >= 0 And A3 > A4) Or (H < 0 And A3 < A4 )
Ret = 1 - Ret
ElseIf A3 - Abs <= A4 And A3 + Abs >= A4
ProcedureReturn 0
EndIf
EndIf
If Vx <> 0 Or Vy <> 0
Vx1 = X - Kontur(i-1)\X
Vy1 = Y - Kontur(i-1)\Y
If Vx1 * Vx1 + Vy1 * Vy1 <= Abs2
ProcedureReturn 0
EndIf
Vx2 = X - Kontur(i)\X
Vy2 = Y - Kontur(i)\Y
A3 = Vx * Vy1 - Vy * Vx1
If A3 > #LONG_MIN And A3 < #LONG_MAX
If A3*A3 <= Abs2*(Vx*Vx+Vy*Vy) And Vx1*Vx + Vy1*Vy >= 0 And Vx2*Vx + Vy2*Vy <= 0
ProcedureReturn 0
EndIf
Else
Protected dA3.d = A3, dVx.d = Vx, dVy = Vy
If dA3*dA3 <= Abs2*(dVx*dVx+dVy*dVy) And Vx1*Vx + Vy1*Vy >= 0 And Vx2*Vx + Vy2*Vy <=0
ProcedureReturn 0
EndIf
EndIf
EndIf
A1 = A2
If A1 <> 0
A0 = A1
EndIf
Next i
ProcedureReturn Ret * 2 - 1
EndProcedure
#Image1 = 1
#Window = 2
#ImageGad = 3
#Button = 4
#Option1 = 5
#Option2 = 6
#Text = 7
#MaxX = 800
#MaxY = 600
#MaxAnz = 1000
Dim K.lPkt(#MaxAnz)
Define i.l,Px.l,Py.l,Abs.l
Define Anzahl.l = 0
Define Event.l
Define Aktion.l = #Option1
Define Input$
If CreateImage(#Image1,#MaxX,#MaxY) = 0
MessageRequester("Achtung!","Kann Image nicht erstellen")
End
EndIf
If OpenWindow(#Window,0,0,#MaxX+10,#MaxY+55,"Cursor in Kontur",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
If CreateGadgetList(WindowID(#Window))
ImageGadget (#ImageGad, 5,10, #MaxX,#MaxY,ImageID(#Image1))
ButtonGadget(#Button,5,#MaxY+20,100,25, "Schließen")
OptionGadget(#Option1,110,#MaxY+15,100,20,"Kontur eingeben")
OptionGadget(#Option2,110,#MaxY+35,100,20,"Lage des Cursors anzeigen")
TextGadget(#Text,250,#MaxY+30,200,30,"Lage : -")
EndIf
StartDrawing(ImageOutput(#Image1))
Box(0,0,#MaxX,#MaxY,RGB(50,50,50))
StopDrawing()
SetGadgetState(#ImageGad,ImageID(#Image1))
SetGadgetState(#Option1,1)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #ImageGad
If Aktion = #Option1 And EventType() = #PB_EventType_LeftClick And Anzahl < #MaxAnz
K(Anzahl)\X = WindowMouseX(#Window) - GadgetX(#ImageGad)
K(Anzahl)\Y = WindowMouseY(#Window) - GadgetY(#ImageGad)
Anzahl + 1
StartDrawing(ImageOutput(#Image1))
Box(0,0,#MaxX,#MaxY,RGB(50,50,50))
For i = 1 To Anzahl-1
LineXY(K(i-1)\X,K(i-1)\Y,K(i)\X,K(i)\Y,RGB(250,250,0))
Next
LineXY(K(i-1)\X,K(i-1)\Y,K(0)\X,K(0)\Y,RGB(250,250,0))
StopDrawing()
SetGadgetState(#ImageGad,ImageID(#Image1))
EndIf
Case #Button
Event = #PB_Event_CloseWindow
Case #Option1
If Aktion <> #Option1
Anzahl = 0
StartDrawing(ImageOutput(#Image1))
Box(0,0,#MaxX,#MaxY,RGB(50,50,50))
StopDrawing()
SetGadgetState(#ImageGad,ImageID(#Image1))
Aktion = #Option1
SetGadgetText(#Text,"Lage: - ")
EndIf
Case #Option2
If Aktion <> #Option2
If Anzahl > 2
Aktion = #Option2
K(Anzahl)\X = K(0)\X
K(Anzahl)\Y = K(0)\Y
Anzahl + 1
Repeat
Input$ = InputRequester("Randbreite","Breite (in Pixeln) (>=0)","2")
Abs = Val(Input$)
Until Abs > 0
Else
MessageRequester("Achtung!","zu wenig Punkte")
SetGadgetState(#Option1,1)
SetGadgetText(#Text,"Lage: - ")
EndIf
EndIf
EndSelect
EndSelect
If Aktion = #Option2
Px = WindowMouseX(#WindoW) - GadgetX(#ImageGad)
Py = WindowMouseY(#WindoW) - GadgetY(#ImageGad)
i = PBGeo_PktInKontur(Px,Py,Anzahl,K(),Abs)
If i = -1
SetGadgetText(#Text,"Lage ("+Str(Px)+","+Str(Py)+"): außen")
ElseIf i = 0
SetGadgetText(#Text,"Lage ("+Str(Px)+","+Str(Py)+"): Rand")
Else
SetGadgetText(#Text,"Lage ("+Str(Px)+","+Str(Py)+"): innen")
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
CloseWindow(#Window)