; Philip Schwartz, Leibnizschule 2010 Global NewList punktX.l() Global NewList punktY.l() Global PixelProEinheit = 30 Global xmin.d = -0.5 Global xmax.d = 10 Global ymin.d = -0.5 Global ymax.d = 18.4 Global imWidth.d = (xmax - xmin) * PixelProEinheit Global imHeight.d = (ymax - ymin) * PixelProEinheit Global xminInt.l = xmin Global xmaxInt.l = xmax Global yminInt.l = ymin Global ymaxInt.l = ymax Global NewList huelle.l() Procedure.d winkel(x.d, y.d) alpha.d = 0 If x > 0 ; x positiv If y >= 0 ; y positiv oder 0 alpha = ATan(y / x) Else ; y negativ alpha = ATan(y / x) + 2 * #PI EndIf ElseIf x = 0 If y > 0 ; y positiv alpha = #PI / 2 ElseIf y < 0 ; y negativ alpha = #PI * 3 / 2 EndIf Else ; x negativ alpha = #PI + ATan(y / x) EndIf ProcedureReturn alpha EndProcedure Procedure.b PosInHuelle(PunktIndex.l) ResetList(huelle()) ForEach huelle() If PunktIndex = huelle() ProcedureReturn ListIndex(huelle()) EndIf Next huelle() ProcedureReturn -1 EndProcedure Procedure findeHuelle() ClearList(huelle()) minY.l = ymaxInt + 1 minYPos.l = -1 ForEach punktY() If punktY() < minY minY = punktY() minYPos = ListIndex(punktY()) EndIf Next punktY() punkteAnzahl = ListIndex(punktY()) + 1 If punkteAnzahl = 0 ProcedureReturn EndIf AddElement(huelle()) huelle() = minYPos geschlossen = 0 BlickWinkel.d = 0 Repeat LastElement(huelle()) aktuellerPunkt.l = huelle() SelectElement(punktX(), aktuellerPunkt) SelectElement(punktY(), aktuellerPunkt) aktuellX.l = punktX() aktuellY.l = punktY() minWinkel.d = 3 * #PI minWinkelPos.l = -1 ResetList(punktX()) ResetList(punktY()) While NextElement(punktX()) NextElement(punktY()) untersuchtesElement.l = ListIndex(punktX()) If (PosInHuelle(untersuchtesElement) < 0) Or (untersuchtesElement = minYPos And ((Not untersuchtesElement = aktuellerPunkt) Or punkteAnzahl = 1)) testwinkel.d = winkel(punktX() - aktuellX, punktY() - aktuellY) - BlickWinkel If testwinkel < 0 testwinkel = testwinkel + 2 * #PI EndIf If testwinkel < minWinkel minWinkel = testwinkel minWinkelPos = untersuchtesElement EndIf EndIf Wend LastElement(huelle()) AddElement(huelle()) huelle() = minWinkelPos BlickWinkel = BlickWinkel + minWinkel If minWinkelPos = minYPos geschlossen = 1 EndIf Until geschlossen EndProcedure Procedure.l PointPosition(x.l, y.l) ResetList(punktX()) ResetList(punktY()) While NextElement(punktX()) NextElement(punktY()) xalt.l = punktX() yalt.l = punktY() If x = xalt And y = yalt ProcedureReturn ListIndex(punktX()) EndIf Wend ProcedureReturn -1 EndProcedure Procedure deletePoint() position = GetGadgetState(0) If position < 0 ProcedureReturn EndIf SelectElement(punktX(), position) DeleteElement(punktX()) SelectElement(punktY(), position) DeleteElement(punktY()) RemoveGadgetItem(0, position) findeHuelle() EndProcedure Procedure.d punkt2pixelX(punkt.d) pixel.d = (punkt - xmin) * PixelProEinheit ; PixelProEinheit Pixel sind eine Einheit, der Ursprung ist xmin vom linken Rand entfernt ProcedureReturn pixel EndProcedure Procedure.d pixel2punktX(pixel.d) punkt.d = pixel / PixelProEinheit + xmin ProcedureReturn punkt EndProcedure Procedure.d punkt2pixelY(punkt.d) pixel.d = imHeight - (punkt - ymin) * PixelProEinheit ; PixelProEinheit Pixel sind eine Einheit, der Ursprung ist ymin vom unteren Rand entfernt, unterer Rand hat y = imWidth ProcedureReturn pixel EndProcedure Procedure.d pixel2punktY(pixel.d) punkt.d = (imHeight - pixel) / PixelProEinheit + ymin ProcedureReturn punkt EndProcedure Procedure deletePointMaus() x.l = pixel2punktX(WindowMouseX(0) - 10) ; Image beginnt 10 Pixel rechts vom Fensterrand, nur ganzzahlige Koordinaten erlaubt y.l = pixel2punktY(WindowMouseY(0) - 10) ; Image beginnt 10 Pixel unter dem Fensterrand, nur ganzzahlige Koordinaten erlaubt position = PointPosition(x, y) If position < 0 ProcedureReturn EndIf SelectElement(punktX(), position) DeleteElement(punktX()) SelectElement(punktY(), position) DeleteElement(punktY()) RemoveGadgetItem(0, position) findeHuelle() EndProcedure Procedure zeichnen() StartDrawing(ImageOutput(0)) Box(0, 0, imWidth, imHeight, RGB(255, 255, 255)) ; Weißer Hintergrund LineXY(0, punkt2pixelY(0), imWidth, punkt2pixelY(0), 0) ; x-Achse For x = xminInt To xmaxInt LineXY(punkt2pixelX(x), punkt2pixelY(0.1), punkt2pixelX(x), punkt2pixelY(-0.1), 0) ; Einteilung x-Achse Next x LineXY(punkt2pixelX(0), 0, punkt2pixelX(0), imHeight, 0) ; y-Achse For y = yminInt To ymaxInt LineXY(punkt2pixelX(0.1), punkt2pixelY(y), punkt2pixelX(-0.1), punkt2pixelY(y), 0) ; Einteilung y-Achse Next y ResetList(punktX()) ResetList(punktY()) While NextElement(punktX()) NextElement(punktY()) xP.d = punktX() yP.d = punktY() Circle(punkt2pixelX(xP), punkt2pixelY(yP), 5, 0) If ListIndex(punktX()) = GetGadgetState(0) ; der in der Liste markierte Punkt Circle(punkt2pixelX(xP), punkt2pixelY(yP), 5, RGB(0, 0, 255)) ; wird blau EndIf Wend mausX.l = pixel2punktX(WindowMouseX(0) - 10) ; Image beginnt 10 Pixel rechts vom Fensterrand, nur ganzzahlige Koordinaten erlaubt mausY.l = pixel2punktY(WindowMouseY(0) - 10) ; Image beginnt 10 Pixel unter dem Fensterrand, nur ganzzahlige Koordinaten erlaubt farbe = RGB(0, 255, 0) ; normalerweise ist der Maus-Kreis grün If PointPosition(mausX, mausY) > -1 farbe = RGB(255, 0, 0) ; wenn der Punkt schon existiert, ist der Maus-Kreis rot EndIf Circle(punkt2pixelX(mausX), punkt2pixelY(mausY), 5, farbe) If FirstElement(huelle()) And FirstElement(punktX()) SelectElement(punktX(), huelle()) SelectElement(punktY(), huelle()) altX.l = punktX() altY.l = punktY() While NextElement(huelle()) SelectElement(punktX(), huelle()) SelectElement(punktY(), huelle()) neuX.l = punktX() neuY.l = punktY() LineXY(punkt2pixelX(altX), punkt2pixelY(altY), punkt2pixelX(neuX), punkt2pixelY(neuY), 0) altX = neuX altY = neuY Wend EndIf StopDrawing() SetGadgetState(7, ImageID(0)) EndProcedure Procedure addPoint(x.d, y.d) If PointPosition(x, y) > -1 SetGadgetState(0, PointPosition(x, y)) zeichnen() MessageRequester("Fehler", "Punkt schon vorhanden!") ProcedureReturn EndIf LastElement(punktX()) AddElement(punktX()) punktX() = x LastElement(punktY()) AddElement(punktY()) punktY() = y AddGadgetItem(0, -1, "( " + Str(x) + " | " + Str(y) + " )") findeHuelle() EndProcedure Procedure addPointButton() If Str(Val(GetGadgetText(2))) <> GetGadgetText(2) Or Str(Val(GetGadgetText(4))) <> GetGadgetText(4) MessageRequester("Fehler", "Bitte Zahlen für x und y eingeben!") ProcedureReturn EndIf x = Int(ValD(GetGadgetText(2))) y = Int(ValD(GetGadgetText(4))) If x >= xminInt And x <= xmaxInt And y >= yminInt And y <= ymaxInt addPoint(x, y) Else MessageRequester("Fehler", "x muss zwischen " + Str(xminInt) + " und " + Str(xmaxInt) + " und y zwischen " + Str(yminInt) + " und " + Str(ymaxInt) + " liegen!") EndIf SetGadgetText(2, "") SetGadgetText(4, "") EndProcedure Procedure addPointMaus() mausX.l = pixel2punktX(WindowMouseX(0) - 10) ; Image beginnt 10 Pixel rechts vom Fensterrand, nur ganzzahlige Koordinaten erlaubt mausY.l = pixel2punktY(WindowMouseY(0) - 10) ; Image beginnt 10 Pixel unter dem Fensterrand, nur ganzzahlige Koordinaten erlaubt addPoint(mausX, mausY) EndProcedure OpenWindow(0, 0, 0, imWidth + 130, imHeight + 20, "Hüllenproblem", #PB_Window_ScreenCentered | #PB_Window_SystemMenu) ListViewGadget(0, imWidth + 20, 10, 100, imHeight - 90) TextGadget(1, imWidth + 20, imHeight - 70, 15, 15, " x:") StringGadget(2, imWidth + 35, imHeight - 70, 25, 20, "") ; x-Koordinate TextGadget(3, imWidth + 70, imHeight - 70, 15, 15, " y:") StringGadget(4, imWidth + 85, imHeight - 70, 25, 20, "") ; y-Koordinate ButtonGadget(5, imWidth + 20, imHeight - 45, 100, 25, "Punkt hinzufügen") ButtonGadget(6, imWidth + 20, imHeight - 15, 100, 25, "Punkt entfernen") CreateImage(0, imWidth, imHeight) ImageGadget(7, 10, 10, imWidth, imHeight, ImageID(0)) zeichnen() While Not YetTheEndOfTheWorld Ereignis = WindowEvent() If Ereignis Select Ereignis Case #PB_Event_CloseWindow End Case #PB_Event_Gadget Select EventGadget() Case 5 ; hinzufügen addPointButton() zeichnen() Case 6 ; entfernen deletePoint() zeichnen() Case 7 ; Grafik Select EventType() Case #PB_EventType_LeftClick addPointMaus() Case #PB_EventType_RightClick deletePointMaus() EndSelect EndSelect EndSelect EndIf zeichnen() Wend ; IDE Options = PureBasic 4.31 (Windows - x86) ; CursorPosition = 1 ; Folding = AQ9 ; EnableXP