![]() |
Minipaint - Kreis von Mittelpunkt aufziehen
Hallo!
Ich prorgrammiere gerade ein kleines Paintprogramm. Im Buch steht, man soll zum Programm die Funktion hinzufügen, dass man einen Kreis zeichnen kann, indem man ihn von seinem Mittelpunkt aufzieht. Das heißt, wenn ich die Maustaste drücke, dann wird der Kreismittelpunkt gesetzt und wenn ich dann die Maus bewege wird der Radius und damit der Kreis immer größer. Beim Loslassen der Maustaste wird der Kreis dann gezeichnet. Wisst ihr, wie man einen Kreis vom Mittelpunkt zeichnet? Gruß, kex |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
HiHo und willkommen in der DP!
da du ja Literatur zur Hand haben scheinst, denke ich, dass dir der Gebrauch von einem Canvas geläufig sein sollte. Gucke dir diesbezüglich einmal die Methode ![]() MfG, hanselmansel |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Zitat:
Leider hab ichs nicht hinbekommen. Ich krieg einfach nicht raus, wie man den Mittelpunkt des Kreises rausbekommt und schon gar nicht, wie man um einen Punkt herum ein immer größer werdendes Quadrat ziehen kann. Tut mir Leid, aber ich komm echt nicht mehr weiter! |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Moin. Für einen Kreis brauchst du 4 Punkte: Links oben/unten und rechts oben/unten. Wenn jemand auf das Image/Paintbox klickt, kannst du dir in einer Variablen den Punkt (wird im MouseDown in einer Variablen übergeben), auf den geklickt wurde, merken. Nun hast du deinen Mittelpunkt. Nun prüfst du im OnMouseMove Ereignis, ob sich die Maus bewegt und wie groß der absolute Abstand in x-Richtung zum Mittelpunkt (den du dir ja gemerkt hast) ist. Nun hast du auch den Radius des Kreises. Folglich hast du auch deine 4 Eckpunkte:
Links oben: (y_Mittelpunkt - Radius; x_Mittelpunkt - Radius) Links unten: (y_Mittelpunkt + Radius; x_Mittelpunkt - Radius) Rechts oben: (y_Mittelpunkt - Radius; x_Mittelpunkt + Radius) Rechts unten: (y_Mittelpunkt + Radius; x_Mittelpunkt + Radius) Ich hoffe, das hilft dir weiter. Man liest sich, Stanlay :hi: |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Das geht nicht.
Immer wenn ich was von den relativen Koordinaten abziehe oder was addiere funktioniert die "Gummilinie" nicht mehr! Das ist mein Code:
Delphi-Quellcode:
So kann ich eine Gummiellipse zeichnen.
private
mausgedrueckt: boolean; xa,xb,ya,yb: integer; public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin mausgedrueckt := true; xa := x; ya := y; xb := x; yb := y; end; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if mausgedrueckt then begin canvas.Pen.Mode := pmnotxor; canvas.ellipse(xa,ya,xb,yb); canvas.ellipse(xa,ya,x,y); xb := x; yb := y; Was muss ich nun verändern, damit ich einen Gummikreis bekomme? Also der abstand zwischen xa und x immer gleich dem Abstand zwischen ya und y entspricht. danach kann man ja immer noch gucken, wie man das hinbekommt, dass es um den mittelpunkt gezogen wird |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Delphi-Quellcode:
Was jedoch eine Gummilinie ist, musst du mir bei Zeiten und einem guten Bier ( :cheers: ) noch einmal erklären. :zwinker:
Var
Center :TPoint; ... procedure MouseDown; begin Center := Point(X,Y); end; procedure MouseUp; Var aRect :TRect; radius :Integer; begin //raduius mittels pytagodingsda ausrechnen aRect.Left := Center.X - distance; aRect.Top := Center.Y - distance; aRect.Right := Center.X + distance; aRect.Bottom := Center.Y + distance; Form1.Canvas.Ellipse(aRect); end; Gute Nacht, hanselmansel |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Hallo,
die Berechnung des Kreismittelpunkts ist einfach: Seitelänge des Quadrats ( um den Kreis ) a Punkt links unten P(x0,y0) Auf canvas bezogen: Pm(x0+(a div 2),y0-(a div 2)) das Minus im y Wert steht nur deshalb, weil die Null für die y Werte oben liegt und y positiv nach unten gezählt wird. das Ganze hat absolut nichts mit dem Pythagoras zu tun ( 8. Klasse Hauptschule ) Die Hypotenuse zum Quadrat ist gleich die Summe der Kathetenquadrate Rainer |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
:wall: Oh mann! Es geht doch nicht darum, von wo nach wo ein Canvas seine Pizel zählt.
Es geht einfach darum, dass die Distanz zwischen Anfangs- und Endpunkt (Kreismittelpunkt und ein Punkt auf der Kreislinie) berechnet wird :!: Und um diese Entfernung zu erhalten, muss man wohl oder übel die einzelnen Komponenten in X- bzw. Y-Richtung zusammenzählen. (mittels Pytagoras...) Cookie möchte am Ende ja Kreise und keine Ellipsen haben. Das heißt, es muss egal sein, in welche Richtung er die Maus vom Mittelpunkt aus bewegt, solange der Abstand konstant bleibt. :zwinker: MfG, hanselmansel |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Sorry, aber irgendwie klappt das alles nicht.
Wenn ich deinen Code nehmen, hanselmansel, dann meckert er an der Stelle aRect.Left := Center.X - distance; Und wie kann man in Delphi Wurzeln und Quadrate berechnen? |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
unit math
und power(x,y) ~ x^y sqrt(x) ~ wurzel(x) sqr(x) ~ x*x |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
HiHo,
es wäre ganz sinnig, zu schreiben, _wie_ Delphi meckert. Es kann nämlich schon mal sein, dass mindestens drei Variablen nicht deklariert sind. Und wenn ich Compiler wäre und du mir ein Kuckucksei unterschieben versuchst, würde ich auch protestieren. :zwinker: Du Quadrat(wurzel)-Funktionen schaust du dir am besten mal ![]() ![]() MfG, hanselmansel |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Hey hanselmansel!
Was soll "distance" angeben? Ich versteh nicht so ganz, was das da alles bedeuten soll mit aRect und distance. Sorry, wenn ich nerve, aber ich kriegs beim besten willen nicht hin. |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Distance und Radius sollen wohl dasselbe sein. aRect (warum dieser Prefix btw?) ist das Rechteck, das die Ellipse umgibt ("Bounding-Rect"):
Delphi-Quellcode:
Das umgebende Rechteck bekommst du sozusagen, wenn du vom Mittelpunkt aus in alle vier Himmelsrichtungen Distance/Radius weit gehst.
// Etwas vereinfacht:
TRect = record Left, Top, Right, Bottom: Integer; end; |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
HiHo Co0kie,
da ich - wie du dir sicherlich schon gedacht hast - das Programm mal in Delphi getippt habe (um zu gucken, ob das auch stimmt, was ich poste) habe ich den Code nun ein wenig verändert:
Delphi-Quellcode:
Die Herangehensweise ist die Selbe, aber evtl. ein wenig einfacher zu verstehen. :thumb:
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); Var Radius_real :Real; Radius :Integer; begin Radius_real := SQRT( SQR(Center.X - X) + SQR(Center.Y - Y) ); Radius := Trunc(Radius_real); //Nachkommastellen abschneiden //Variante 1 Form1.Canvas.Ellipse(Center.X-Radius, Center.Y-Radius, Center.X+Radius, Center.Y+Radius); //Variante 2 {aRect.Left := Center.X - distance; aRect.Top := Center.Y - distance; aRect.Right := Center.X + distance; aRect.Bottom := Center.Y + distance; Form1.Canvas.Ellipse(aRect); } end; |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Hanselmansel, du bist ein Genie :mrgreen:
Ich hab es endlich hinbekommen :) Jetzt hab ich aber noch ein letztes Problem: Wie lasse ich den Cursor zu einem weißen rechteck werden? |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Hallo hanselmansel,
behaupte doch bitte nicht Dinge die ganz eindeutig falsch sind. Dazu braucht man eben nicht den Pythagoras. Vielleicht liest das jemand, den du dann total verunsicherst. Ausserdem erklärt mein Beitrag die mathematischen Grundlagen zu diesem thread und genau darum geht es. Ich erklär dir das gerne nocheinmal ( privat per mail ). Rainer |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Man könnte es auch so verstehen, dass der X- oder Y-Wert des Cursors den Kreis bestimmt, dafür wäre wirklich kein Pythagoras nötig. Aber für den Benutzer ist diese Möglichkeit IMO sinnlos und verwirrend. |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Schau dir mal form1.cursor an. Du kannst auch eine selbst erstellte Cursordatei verwenden. Wie das geht kannst du bestimmt über die Suche ermitteln:
![]() |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
so, die aufgabe kenn ich auch, aber wie zeichne ich ein exaktes quadrat immer nach der längsten seite?
|
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Zitat:
Zitat:
Sorry, aber ich verstehe kein einziges Wort deines Posts. |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
HiHo Markus,
du kannst den von mir hier irgendwo im Thread geposteten Ansatz nehmen, und musst nur Canvas.Ellipse durch Canvas.Rectangle und den Pytagoras durch eine >-Abfrage ersetzten. :thumb: MfG, hanselmansel |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Aufgabe: Beim Klicken auf eine Image-Komponente sollen die Klickkoordinaten (xa, ya) gespeichert werden. Beim Bewegen der Maus über das Formular sollen nun "Gummilinien" gezeichent werden, für die folgendes gilt: gestrichelt und hellgrau. außerdem gilt:
Ich hoffe jetzt ist das ganze verständlicher |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Und wie ist dein bisheriger Lösungsansatz?
|
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Delphi-Quellcode:
private
{ Private-Deklarationen } mausgedrueckt : boolean; x_start, y_start, x_alt, y_alt, radius, radius_alt, breite, hoehe, breite_alt, hoehe_alt, quadrat_x, quadrat_y, max, laenge_alt : integer; bg_color, fg_color, fill_color : TColor; deckend : TBrushStyle; function vorzeichen(a : integer): integer; function TMain.vorzeichen(a : integer): integer; begin if a < 0 then Result := -1 else Result := +1; end; procedure TMain.im_pictureMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin mausgedrueckt := true; with im_picture.Canvas do begin case Main.Tag of 8 : begin x_start := x; y_start := y; x_alt := x; y_alt := y; breite := x - X_start; hoehe := y - y_start; if breite > hoehe then begin quadrat_x := x_start + breite; quadrat_y := y_start + breite * vorzeichen(hoehe); end else begin quadrat_x := x_start + hoehe * vorzeichen(breite); quadrat_y := y_start + hoehe; end; end; end; end; end; procedure TMain.im_pictureMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin with im_picture.Canvas do begin if mausgedrueckt then case Main.Tag of 8 : begin pen.Color := clSilver; Pen.Style := psDot; Brush.Style := bsClear; Pen.Mode := pmNotXor; Rectangle(x_start, y_start, quadrat_x, quadrat_y); breite := x - X_start; hoehe := y - y_start; if breite > hoehe then begin quadrat_x := x_start + breite; quadrat_y := y_start + breite * vorzeichen(hoehe); end else begin quadrat_x := x_start + hoehe * vorzeichen(breite); quadrat_y := y_start + hoehe; end; Rectangle(x_start, y_start, quadrat_x, quadrat_y); pen.Style := psSolid; pen.Color := fg_color; end; end; end; end; procedure TMain.im_pictureMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin with im_picture.Canvas do begin if not bt_hand.Enabled then mausgedrueckt := false; if mausgedrueckt then begin case Main.Tag of 8 : begin pen.Mode := pmCopy; pen.Style := psSolid; pen.Color := fg_color; Brush.Color := bg_color; Brush.Style := deckend; breite := x - X_start; hoehe := y - y_start; if breite > hoehe then begin quadrat_x := x_start + breite; quadrat_y := y_start + breite * vorzeichen(hoehe); end else begin quadrat_x := x_start + hoehe * vorzeichen(breite); quadrat_y := y_start + hoehe; end; Rectangle(x_start, y_start, quadrat_x, quadrat_y); end; end; end; end; mausgedrueckt := false; end; |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Und was funktioniert innerhalb dieser 134 Zeilen Quellcode nicht?
|
Re: Minipaint - Kreis von Mittelpunkt aufziehen
der zechnet die quadrate alle außer nach unten rechts falsch
|
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Liste der Anhänge anzeigen (Anzahl: 1)
:gruebel:
Delphi-Quellcode:
mehr fällt mir zum "Gummirechteck" nicht ein, ausser dass man in jedem "Frame" das alte Rechteck clearen muss bzw. komplett refreshen.
canvas.rectangle(OldMouse.X,OldMouse.Y,Mouse.Cursorpos.X,Mouse.Cursorpos.Y); //es sollte absolut egal sein,
Zitat:
|
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Zitat:
Die folgenden 4ecke stellen jeweils ein quadrat dar: dabei ist x die position an der nie maus geklick wurde und M die Position an der die Maus sich beim MouseMove bzw. MouseUp befindet. die - und | geben einfach nur die linien des quadrates an
Code:
+---x
| | M---+
Code:
x---+
| | +---M
Code:
+---M
| | x---+
Code:
M---+
| | +---x |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Liste der Anhänge anzeigen (Anzahl: 1)
ach so... ein Quadrat.... kein Rechteck?
ok. dann musst du dich entscheiden, ob du es vertikal oder horizontal aufziehst. Sprich: ob dein Mauszeiger immer auf einer vertikalen oder auf einer horizontalen Seite des Quadrats liegt. angenommen du machst es so, dass der Mauszeiger immer horizontal draufliegt, dann sollte
Delphi-Quellcode:
zum Ziel führen. Werde das gleich mal persönlich überprüfen.
s := MousePos.X - OldMouse.X; //S = Seitenlänge
p1 := point(OldMouse.X,OldMouse.Y); p2 := point(OldMouse.X + s, OldMouse.Y + s); canvas.Rectangle(rect(p1,p2)); //hoffe, die überladung gibts.... EDIT: funktioniert, beispielprojekt im Anhang. EDIT2: Bedienung: einfach in der form ein rechteck aufziehen ;) EDIT3: mir fällt gerade auf, dass das doch nciht so funzt wie es sollte. :wall: EDIT4: :dancer2: Neue Version im Anhang, verhält sich richtig, Bedienung wie 2. :dancer: |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Anfang:
Delphi-Quellcode:
Quadrat:
procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); var SeiteA,SeiteB,Seite1:integer; H:TPoint; StartPunkt:Boolean; begin If StartPunkt=True then begin
Delphi-Quellcode:
Rechteck:
SeiteA:=Abs(SP.X-X);
SeiteB:=Abs(SP.Y-Y); if (SeiteA>SeiteB) and (X<>SP.X) and (Y<>SP.Y) then Seite1:=SeiteB else Seite1:=SeiteA; if X<SP.X then H.X:=Sp.X-Seite1 else H.X:=SP.X; if Y<SP.Y then H.Y:=SP.Y-Seite1 else H.Y:=SP.Y; paintbox.Canvas.Rectangle(H.X,H.Y,H.X+Seite1,H.Y+Seite1); StartPunkt:=False; end
Delphi-Quellcode:
Ende:
if X<SP.X
then begin SeiteA:=SP.X-X; H.X:=X; end else begin SeiteA:=X-SP.X; H.X:=SP.X; end; if Y<SP.Y then begin SeiteB:=SP.Y-Y; H.Y:=Y; end else begin SeiteB:=Y-SP.Y; H.Y:=SP.Y; end; paintbox.Canvas.Rectangle(H.X,H.Y,H.X+SeiteA,H.Y+SeiteB); StartPunkt:=False; end
Delphi-Quellcode:
jetzt musst du nur noch unter Private die Variable SP als TPoint deklarieren und dann sollte es gehen.
else
SP.X:=X; SP.Y:=Y; StartPunkt:=True; |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
ich hab's geschaft
programm könnt ihr euch wenn das projekt bewertet wurde downloaden. |
Re: Minipaint - Kreis von Mittelpunkt aufziehen
Hey und ist die Bewertung schon geschehen?
|
Re: Minipaint - Kreis von Mittelpunkt aufziehen
ja, schon lange.
war eine 1+ mit sternchen ^^ weil ich der einzige im kurs ware, bei dem alles funktioniert hat *lol* |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz