Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Linie im Winkel zeichnen (https://www.delphipraxis.net/185785-linie-im-winkel-zeichnen.html)

GroZ 6. Jul 2015 13:40

Linie im Winkel zeichnen
 
Hallo. Ich soll in einem Kreis eine Linie zeichnen soweit kein Problem. Aber diese Linie soll im Winkel angepasst sein. das heißt wenn ich 15° eingebe soll die Linie im 15° Winkel gezeichnet werden. Kann mir jemand helfen?
In etwas so hier: https://de.wikipedia.org/wiki/Polark...eiskoordinaten

alleinherrscher 6. Jul 2015 15:06

AW: Linie im Winkel zeichnen
 
Und wo genau ist dein Problem, was hast du denn bis jetzt schon? Hast du schon mit MoveTo und LineTo herumexperimentiert, so wie in dem zweiten Thread, den du geschrieben hast, empfohlen?

Weiterhin: Was sind deine mathematischen Vorkenntnisse? Weißt du, wie Sinus und Kosinus definiert sind und wie man mit deren Hilfe einen beliebigen Punkt auf einem Kreis mit Radius R beschreiben kann?

Besten Gruß

Popov 6. Jul 2015 15:56

AW: Linie im Winkel zeichnen
 
Dieses Beispiel habe ich schon etwa 100 mal im Internet gepostet. Ich habe es mal als Demo geschrieben um zu zeigen wie man einen Kreis mit Sinus und Kosinus alleine zeichnen kann.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  w, x,
  sinX, sinY,
  cosX, cosY,
  sinXorY, cosXorX,
  KreisX, KreisY: Integer;

const
  FX = 200;
  FY = 50;
  sinStartX = 200;
  sinStartY = 100;
  cosStartX = 100;
  cosStartY = 200;

  procedure CanLine(Can: TCanvas; x1, y1, x2, y2: Integer);
  begin
    Can.MoveTo(x1, y1);
    Can.LineTo(x2, y2);
  end;

  function mySin(PixelX: Integer; PiInPixel, OneInPixel: Word): Integer;
  var
    x: Extended;
  begin
    x := Pi * (PixelX / PiInPixel);
    Result := Trunc(sin(x) * OneInPixel);
  end;

  function myCos(PixelX: Integer; PiInPixel, OneInPixel: Word): Integer;
  var
    x: Extended;
  begin
    x := Pi * (PixelX / PiInPixel);
    Result := Trunc(cos(x) * OneInPixel);
  end;

  procedure XorLine(Can: TCanvas; x1, y1, x2, y2: Integer);
  begin
    with Can, TPen.Create do
    try
      Mode := Pen.Mode;
      Pen.Mode := pmNot;
      MoveTo(x1, y1);
      LineTo(x2, y2);
      Pen.Mode := Mode;
    finally
      Free;
    end;
  end;

begin
  with Canvas do
  begin
    FillRect(ClipRect);

    MoveTo(sinStartX, sinStartY-FY);
      LineTo(sinStartX, sinStartY+FY);
    MoveTo(sinStartX, sinStartY);
      LineTo(sinStartX+(FX*2), sinStartY);
    MoveTo(cosStartX-FY, cosStartY);
      LineTo(cosStartX+FY, cosStartY);
    MoveTo(cosStartX, cosStartY);
      LineTo(cosStartX, cosStartY+(FX*2));

    sinX := sinStartX;
    sinY := sinStartY;
    cosX := cosStartY;
    cosY := cosStartX;
    KreisY := sinY;
    KreisX := cosY;


    for w := -FX to FX do
    begin
      if not(w = -FX) then
      begin
        //alte Xor-Linen löschen
        XorLine(Canvas, 0, sinXorY, ClipRect.Right, sinXorY);
        XorLine(Canvas, cosXorX, 0, cosXorX, ClipRect.Bottom);
      end;

      //sin zeichnen
      x := w;
      MoveTo(sinX, sinY);
      sinX := sinStartX + FX + w;
      sinY := sinStartY + mySin(x, FX, FY);
      LineTo(sinX, sinY);

      //cos zeichnen
      x := w;
      MoveTo(cosY, cosX);
      cosX := cosStartY + FX + w;
      cosY := cosStartX + myCos(x, FX, FY);
      LineTo(cosY, cosX);

      //Kreis zeichen aus den Y-Werten von Sinus und Cosinus
      MoveTo(KreisX, KreisY);
      KreisY := sinY;
      KreisX := cosY;
      LineTo(KreisX, KreisY);

      //Xor-Line zeichnen
      sinXorY := sinY;
      cosXorX := cosY;
      XorLine(Canvas, 0, sinXorY, ClipRect.Right, sinXorY);
      XorLine(Canvas, cosXorX, 0, cosXorX, ClipRect.Bottom);

      Sleep(10); //eine kurze Verzögerung damit es langsammer geht
      Application.ProcessMessages;
    end;

    //Letzte Xor-Linen löschen
    XorLine(Canvas, 0, sinXorY, ClipRect.Right, sinXorY);
    XorLine(Canvas, cosXorX, 0, cosXorX, ClipRect.Bottom);

  end;

end; {Popov}

Perlsau 6. Jul 2015 16:04

AW: Linie im Winkel zeichnen
 
Mein Eindruck: Der TE probiert hier so lange die Hilfsbereitschaft gewisser User aus, bis er eine fertige Lösung erhält, weil er im Unterricht nicht aufgepaßt hat. Ich finde nicht, daß man das auch noch unterstützen sollte.

Popov 6. Jul 2015 16:32

AW: Linie im Winkel zeichnen
 
Das braucht er nicht, denn ob er etwas hier bekommt oder über Google, ist gehopst wie gesprungen. Nicht die Formeln sind das Problem, denn von denen gibt es im Internet genug, wichtig ist wie man an die Aufgabe herangeht. Es ist die Methode, bzw. die Technik wie man eine Aufgabe löst. Die bekommt man eigentlich in der Schule beigebracht.
Code:
Aufgabe:
Koordinate B berechnen.

Gegeben:
Koordinate A
Winkel Alpha
Hypotenuse (Radius)
Kreiszahl Pi

Gesucht:
Ankathete (Länge X)
Gegenkathete (Länge Y)
Hat man alle schön aufgeschrieben, muss man nur nach der Lösung suchen wo das Gesuchte mit dem Gegebenen berechnet werden kann.

Perlsau 6. Jul 2015 16:37

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von Popov (Beitrag 1307837)
Nicht die Formeln sind das Problem, denn von denen gibt es im Internet genug, wichtig ist wie man an die Aufgabe herangeht. Es ist die Methode, bzw. die Technik wie man eine Aufgabe löst. Die bekommt man eigentlich in der Schule beigebracht.

Leider kann ich nicht erkennen, ob der Schüler über diese Techniken verfügt bzw. sie in der Schule gelernt hat. Wäre es da nicht wesentlich sinnvoller, erst mal abzufragen, was der denn weiß (Kenntnisstand), bevor man etwas postet, das es angeblich bereits 100 Mal im Internet zu finden gibt? Wie soll das dem Schüler jetzt weiterhelfen, seinen wohl eher mageren Kenntnisstand berücksichtigend?

GroZ 7. Jul 2015 08:31

AW: Linie im Winkel zeichnen
 
Ich hatte sowas wie Informatik gar nicht in der Schule ich mache derzeit ein Praktikum und soll diese Dinge programmieren. ich schick euch mal meinen Quellcode ist wirklich sehr einfach^^

Delphi-Quellcode:
unit Uhr;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Winkel: TEdit;
    Strich: TButton;
    Reset: TButton;
    PaintBox1: TPaintBox;
    procedure PaintBox1Paint(Sender: TObject);
    procedure ResetClick(Sender: TObject);
    procedure StrichClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  i : integer;

implementation

{$R *.dfm}

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin

canvas.Ellipse(100,100,400,400);


end;

procedure TForm1.ResetClick(Sender: TObject);
begin

paintbox1.Repaint
end;

procedure TForm1.StrichClick(Sender: TObject);
var i : integer ;
begin
canvas.MoveTo(250,250);
canvas.lineto(250,100);

i := StrToInt(Winkel.Text) ;



end;

end.

GroZ 7. Jul 2015 08:55

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von Popov (Beitrag 1307837)
Das braucht er nicht, denn ob er etwas hier bekommt oder über Google, ist gehopst wie gesprungen. Nicht die Formeln sind das Problem, denn von denen gibt es im Internet genug, wichtig ist wie man an die Aufgabe herangeht. Es ist die Methode, bzw. die Technik wie man eine Aufgabe löst. Die bekommt man eigentlich in der Schule beigebracht.
Code:
Aufgabe:
Koordinate B berechnen.

Gegeben:
Koordinate A
Winkel Alpha
Hypotenuse (Radius)
Kreiszahl Pi

Gesucht:
Ankathete (Länge X)
Gegenkathete (Länge Y)
Hat man alle schön aufgeschrieben, muss man nur nach der Lösung suchen wo das Gesuchte mit dem Gegebenen berechnet werden kann.

Den winkel Alpha möchte ich über ein Editfeld selber eingeben.

Sir Rufo 7. Jul 2015 09:45

AW: Linie im Winkel zeichnen
 
Wenn du auf dem Canvas der Paintbox malen möchtest, dann musst du auch auf dem Canvas der Paintbox malen und nicht auf dem Canvas der Form!
Delphi-Quellcode:
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  LCanvas: TCanvas;
begin
  LCanvas := TPaintBox(Sender).Canvas;

  LCanvas.Ellipse(100,100,400,400);

end;

GroZ 7. Jul 2015 09:57

AW: Linie im Winkel zeichnen
 
Das ist jetzt mein Quellcode. Jetzt komm ich aber absolout nicht mehr weiter...
Delphi-Quellcode:
unit Uhr;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Winkel: TEdit;
    Strich: TButton;
    Reset: TButton;
    PaintBox1: TPaintBox;
    procedure PaintBox1Paint(Sender: TObject);
    procedure ResetClick(Sender: TObject);
    procedure StrichClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  i : integer;

implementation

{$R *.dfm}

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  LCanvas: TCanvas;
begin

LCanvas := TPaintBox(Sender).Canvas;

  LCanvas.Ellipse(100,100,400,400);


end;

procedure TForm1.ResetClick(Sender: TObject);
begin

paintbox1.Repaint
end;

procedure TForm1.StrichClick(Sender: TObject);
var Radi, Gradi : extended ;
    Pi: extended ;
begin
canvas.MoveTo(280,280);
canvas.lineto(280,125);

Gradi := StrToFloat(Winkel.Text) ;

Radi := Pi*(Gradi/180);







end;

end.

Aphton 7. Jul 2015 10:04

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von GroZ (Beitrag 1307942)
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
LCanvas: TCanvas;
begin

LCanvas := TPaintBox(Sender).Canvas;

LCanvas.Ellipse(100,100,400,400);
// ...

procedure TForm1.StrichClick(Sender: TObject);
var Radi, Gradi : extended ;
Pi: extended ;
begin
canvas.MoveTo(280,280);
canvas.lineto(280,125);
// ...
[/DELPHI]

Fällt dir hier nichts auf?

GroZ 7. Jul 2015 10:11

AW: Linie im Winkel zeichnen
 
Leider nein :D

Aphton 7. Jul 2015 10:11

AW: Linie im Winkel zeichnen
 
Zitat:

... das heißt wenn ich 15° eingebe soll die Linie im 15° Winkel gezeichnet werden. Kann mir jemand helfen?
Aber gerne - hier

Code:
x := kreis_radius * cos(DegToRad(15))
y := kreis_radius * sin(DegToRad(15))

linie_x1 = kreis_mittelpunkt_x
linie_y1 = kreis_mittelpunkt_y
linie_x2 = kreis_mittelpunkt_x + x
linie_y2 = kreis_mittelpunkt_y + y

Sir Rufo 7. Jul 2015 10:13

AW: Linie im Winkel zeichnen
 
Das Wichtigste ist, dass die PaintBox ihren Kram selber zeichnet. Und zwar in dem Event
Delphi-Quellcode:
OnPaint
.

Wenn die PaintBox nun also etwas mehr zeichnen soll, dann muss man so etwas wie einen Bauplan zur Verfügung stellen und dann kann die PaintBox diesen Bauplan abarbeiten.

Ändert man den Bauplan, dann teilt man das der PaintBox durch den Aufruf von
Delphi-Quellcode:
TPaintBox.Repaint
mit.

Der einfachste Bauplan, wäre z.B. das Zeichnen der Ellipse:
Delphi-Quellcode:
type
  TForm1 = class( TForm )
    CheckBox1: TCheckBox; // OnClick = CheckBox1Click
    PaintBox1: TPaintBox; // OnPaint = PaintBox1Paint
    procedure CheckBox1Clicked( Sender: TObject );
    procedure PaintBox1.Paint( Sender: TObject );
  private
    FPaintEllipse: Boolean;
  end;

procedure TForm1.CheckBox1Clicked( Sender: TObject );
begin
  // Bauplan ändern
  FPaintEllipse := CheckBox1.Checked;
  // PaintBox neu zeichnen lassen
  PaintBox1.Repaint;
end;

procedure TForm1.PaintBox1Paint( Sender: TObject );
var
  LCanvas: TCanvas;
begin
  LCanvas := TPaintBox(Sender).Canvas;
  // nach dem Bauplan zeichnen
  if FPaintEllipse then
    LCanvas.Ellipse(100,100,400,400);
end;

Aphton 7. Jul 2015 10:14

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von GroZ (Beitrag 1307945)
Leider nein :D

Im StrichClick() greifst du auf den Canvas des Formulars zu, anstatt wie bei PaintBox1Paint() auf den Canvas der Paintbox zuzugreifen

GroZ 7. Jul 2015 10:52

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von Aphton (Beitrag 1307948)
Zitat:

Zitat von GroZ (Beitrag 1307945)
Leider nein :D

Im StrichClick() greifst du auf den Canvas des Formulars zu, anstatt wie bei PaintBox1Paint() auf den Canvas der Paintbox zuzugreifen

Habe es jetzt gelöst danke an alle!
Delphi-Quellcode:
unit Uhr;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Winkel: TEdit;
    Strich: TButton;
    Reset: TButton;
    PaintBox1: TPaintBox;
    procedure PaintBox1Paint(Sender: TObject);
    procedure ResetClick(Sender: TObject);
    procedure StrichClick(Sender: TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  i : integer;

implementation

{$R *.dfm}

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  LCanvas: TCanvas;
begin

LCanvas := TPaintBox(Sender).Canvas;

  LCanvas.Ellipse(100,100,400,400);       // Kreis zeichnen


end;

procedure TForm1.ResetClick(Sender: TObject);
begin

paintbox1.Repaint ;                     // Clear
end;

procedure TForm1.StrichClick(Sender: TObject);
var Radi, Gradi, R, PX, PY : double ;
    MX, MY, PXi, PYi : integer ;

begin

MX := 250;                         // Mittelpunkt
MY := 250;
R := 150;
Canvas.MoveTo(MX,MY);
//Canvas.lineto(280,125);

Gradi := StrToFloat(Winkel.Text) ;

Radi := 3.14 *(Gradi/180);        // Rechnung

PX := cos(Radi)* R + MX ;
PY := MY-sin(Radi)* R;
PXi := trunc(PX) ;                   // Von ??? zu Integer umwandeln
PYi := trunc(PY) ;
Canvas.lineTo(PXi,PYi) ;








end;



end.

Aphton 7. Jul 2015 11:00

AW: Linie im Winkel zeichnen
 
Naja, das nebensächliche Problem besteht weiterhin.. Ansosnten - kein Problem :thumb:

Popov 7. Jul 2015 11:49

AW: Linie im Winkel zeichnen
 
@GroZ

Paar kleine Vorschläge:

- nimm die Konstante Pi statt 3,14. Kostet nix, ist bereits im System.
- Nutze lieber Round() statt Trunc(). Round rundet kaufmännisch, Trunc schneidet nur die Nachkommastellen ab.

Das alles ist zwar nicht ganz wichtig, kann aber den Unterschied ausmachen ob z. B. Punkt 9 Uhr klein wenig drunter oder über dem Punkt ist.

SProske 7. Jul 2015 12:12

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von Popov (Beitrag 1307974)

- nimm die Konstante Pi statt 3,14. Kostet nix, ist bereits im System.

Wieso nicht gleich DegToRad aus der Math?

Delphi-Quellcode:
Radi := DegToRad(Gradi);

BadenPower 7. Jul 2015 12:14

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von Aphton (Beitrag 1307963)
Naja, das nebensächliche Problem besteht weiterhin.. Ansosnten - kein Problem :thumb:

Als Nächstes kommen folgende Fragen des TE:

1.:
Ich habe die PaintBox im Formular um 100 Pixel nach unten verschoben, nun stimmt mein Anfangspunkt der Linie nicht mehr mit dem Mittelpunkt des Kreises überein.

2.:
Wenn ich die Anwendung minimiere und dann wieder Anzeigen lasse, dann sind meine gezeichneten Linien verschwunden.

3.:
Meine Linen bei 180 und 270° sind nicht gerade.

Popov 7. Jul 2015 12:40

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von SProske (Beitrag 1307984)
Wieso nicht gleich DegToRad aus der Math?

Delphi-Quellcode:
Radi := DegToRad(Gradi);

Kann man auch nehmen, dazu braucht man aber die Unit Math. Das ist an sich kein Problem, aber in Anbetracht dessen, dass es ein unerfahrener Programmierer ist, stellt sich die Frage ob man für Kleinigkeiten extra eine weitere Unit einbinden soll. Den schließlich muss er den Code auch verstehen und u.U. vertreten.

Aber nein, im Prinzip spricht nichts dagegen.

GroZ 7. Jul 2015 12:44

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von Popov (Beitrag 1307974)
@GroZ

Paar kleine Vorschläge:

- nimm die Konstante Pi statt 3,14. Kostet nix, ist bereits im System.
- Nutze lieber Round() statt Trunc(). Round rundet kaufmännisch, Trunc schneidet nur die Nachkommastellen ab.

Das alles ist zwar nicht ganz wichtig, kann aber den Unterschied ausmachen ob z. B. Punkt 9 Uhr klein wenig drunter oder über dem Punkt ist.

Pi hab ich gesucht sowohl bei math als auch bei system leider nix drin. keine ahnung wieso. round hatte ich erst aber es hat dann nicht gepasst bei den linien. beim nächsten mal.

Popov 7. Jul 2015 12:51

AW: Linie im Winkel zeichnen
 
Pi befindet sich in der Unit System. Die ist in der Regel schon eingebunden, so dass du einfach nur noch Pi schreiben musst. Beispiel:
Delphi-Quellcode:
ShowMessage(FloatToStr(Pi));
.

Die Funktion Round ist nur ein guter Tipp. Aus Erfahrung weiß ich, dass es manchmal um die Nachkommastellen geht. Round ist öfter näher am richtigen Ergebnis als Trunc.

GroZ 7. Jul 2015 12:59

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von Popov (Beitrag 1307991)
Pi befindet sich in der Unit System. Die ist in der Regel schon eingebunden, so dass du einfach nur noch Pi schreiben musst. Beispiel:
Delphi-Quellcode:
ShowMessage(FloatToStr(Pi));
.

Die Funktion Round ist nur ein guter Tipp. Aus Erfahrung weiß ich, dass es manchmal um die Nachkommastellen geht. Round ist öfter näher am richtigen Ergebnis als Trunc.

Auch mein "ausbilder" hat pi gesucht und nix gefunden. ok danke merk ich mir :)

Captnemo 7. Jul 2015 13:01

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von GroZ (Beitrag 1307995)
Auch mein "ausbilder" hat pi gesucht und nix gefunden. ok danke merk ich mir :)

Dann muss dein "Ausbilder" vielleicht mal eine Ausbildung machen, wie man die Hilfe benutzt. Bei mir ist das der erste Eintrag, wenn ich in der Hilfe mal nach PI suche.

Popov 7. Jul 2015 13:10

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von GroZ (Beitrag 1307995)
Auch mein "ausbilder" hat pi gesucht und nix gefunden. ok danke merk ich mir :)

Kleiner Tipp mit dem du deinen Ausbilder beeindrucken kannst: Einfach Pi eingeben und dann den Cursor vor, nach oder einfach mitten rein positionieren. Dann einfach die Funktionstaste F1 drücken. Dein Ausbilder wird ganz aus dem Häuschen sein, denn es wird sich die Hilfe von Delphi offen. Dort wird die Funktion beschrieben und sogar der Hinweis gegeben in welcher Unit sich die Funktion befindet.

Captnemo 7. Jul 2015 13:20

AW: Linie im Winkel zeichnen
 
Zitat:

Zitat von Popov (Beitrag 1307998)
Zitat:

Zitat von GroZ (Beitrag 1307995)
Auch mein "ausbilder" hat pi gesucht und nix gefunden. ok danke merk ich mir :)

Kleiner Tipp mit dem du deinen Ausbilder beeindrucken kannst: Einfach Pi eingeben und dann den Cursor vor, nach oder einfach mitten rein positionieren. Dann einfach die Funktionstaste F1 drücken. Dein Ausbilder wird ganz aus dem Häuschen sein, denn es wird sich die Hilfe von Delphi offen. Dort wird die Funktion beschrieben und sogar der Hinweis gegeben in welcher Unit sich die Funktion befindet.

Deinem Ausbilder wird eine völlig neue Welt offenbaren :D


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:09 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz