Strich zeichnen

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
Dragomir
Beiträge: 40
Registriert: Di 28. Apr 2015, 12:06

Strich zeichnen

Beitrag von Dragomir »

Hallo ich benötige mal wieder eure Hilfe :( :oops:

Ich wollte fragen, ob es eine möglichkeit gibt ein Strich, mit Canvas zu zeichnen und diesen dann nachträglich zu bewegen.

Wenn ich dann zwei zeichne, möchte ich beide einzelnd bewegen können.

Danke im voraus für die Hilfe.
lg Dragomir

Benutzeravatar
theo
Beiträge: 10499
Registriert: Mo 11. Sep 2006, 19:01

Re: Strich zeichnen

Beitrag von theo »

Ein Strich ist nur ein Strich. Bewegung erreichst du, indem du den Strich bei nächsten Zeichnen versetzt zeichnest.

Dragomir
Beiträge: 40
Registriert: Di 28. Apr 2015, 12:06

Re: Strich zeichnen

Beitrag von Dragomir »

Also müsste ich für jeden Strich und /oder rechteck eine neue Ebene erstellen, damit ich die Einzelnd anfassen kann ?
Oder geht das auch anderst?

Benutzeravatar
theo
Beiträge: 10499
Registriert: Mo 11. Sep 2006, 19:01

Re: Strich zeichnen

Beitrag von theo »

Wenn du z.B. willst, dass der Strich der Maus folgt, musst du OnPaint und OnMouseMove einhängen.

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure FormPaint(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  Pt:TPoint;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Pt:=Point(X,Y);
  Invalidate;
end;
 
procedure TForm1.FormPaint(Sender: TObject);
begin
  Canvas.MoveTo(10,10);
  Canvas.LineTo(Pt);
end;
 
end

Dragomir
Beiträge: 40
Registriert: Di 28. Apr 2015, 12:06

Re: Strich zeichnen

Beitrag von Dragomir »

Genau das danke :)

jetz muss ich halt nur schauen, dass wenn ich 2 striche habe er nur den einen bewegt

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Strich zeichnen

Beitrag von mschnell »

Dragomir hat geschrieben:jetz muss ich halt nur schauen, dass wenn ich 2 striche habe er nur den einen bewegt

Canvas merkt sich nur die Pixel, nicht wie sie entstanden sind.
Oft ist es sinnvoll, das komplette Neuzeichnen (Redraw) in einem OnPaint Event zu machen, damit das korrekte aktuelle Bild komplett neu generiert wird.

Für zwei Striche sollte das kein Problem sein.

Bei komplexeren Figuren und Operationen reicht die Performance der CPU nicht aus, dann sollte man den Grafik-Prozessor auf der Video.-Karte verwenden. Hierzu bieten sich OpenGL und SDL an.

-Michael

Dragomir
Beiträge: 40
Registriert: Di 28. Apr 2015, 12:06

Re: Strich zeichnen

Beitrag von Dragomir »

@ michael danke für die Antwort ja es sind nit nur zwei striche, Es ist eine Bildbearbeitungsanwendung.

darauf kann ich kreise rechtecke zeichnen sowie kreise und alle Objekte müssen einzelnd bewegt werden können

Benutzeravatar
theo
Beiträge: 10499
Registriert: Mo 11. Sep 2006, 19:01

Re: Strich zeichnen

Beitrag von theo »

Ist jetzt alles klar?
Du musst im OnPaint Event immer alles neu zeichnen, ob es bewegt wird oder nicht.
Hintergründe etc. kann man natürlich auch vorher auf einen Puffer (TBitmap) zeichnen, und dann in OnPaint nur noch kopieren.

wp_xyz
Beiträge: 4892
Registriert: Fr 8. Apr 2011, 09:01

Re: Strich zeichnen

Beitrag von wp_xyz »

Dragomir hat geschrieben:Es ist eine Bildbearbeitungsanwendung.

Ich will dir ja den Spaß nicht verderben, aber kennst du LazPaint (https://sourceforge.net/projects/lazpaint/)? Das ist mit Lazarus geschrieben, und da kannst du schon mal sehen, was auf dich zukommt. :wink:

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Strich zeichnen

Beitrag von mschnell »

Dragomir hat geschrieben: Es ist eine Bildbearbeitungsanwendung.

Ich habe mal einem Bekannten geholfen, der eine (sehr spezielle) Bildbearbeitungs-Software gemacht hat.

Die Software hat nur (farbige) Pixel auf eine sehr große (unsichtbare) Canvas gezeichnet. Es war aber notwendig, dass der Bediener flüssig zu dem Teilbereich in dem er arbeiten wollte, "Zoomen" und "Pannen" konnte.

Das haben wir dann mit SDL gemacht.

Die darzustellende Canvas wurde nach Abschluss eines Editier-Vorgangs in die Grafik-Karte kopiert. Das "Stretchdraw" bei jedem Mouse-Move wurde dann vom Grafik-Prozessor auf der Karte berechnet. Das hätte die PC-CPU nicht gekonnt. Allein schon das kopieren der Pixel vom PC - Memory in die Grafik-Karte kann von der PC-Hardware nicht schnell genug ausgeführt werden, um bei Zoom und Pan mit jedem Mouse-Move eine flüssige Bewegung zu bekommen.

-Michael

Warf
Beiträge: 1912
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Strich zeichnen

Beitrag von Warf »

Also für ein simples Grafik Programm sollte die CPU schnell genug sein. Was du hat tuen musst ist die Daten über die Objekte Zwischenspeichern und dann in der OnPaint Methode dann Zeichnen. Je nach umfang empfiehlt sich für die verschiedenen Formen eine Klassen Hierarchie.

Mal ein kleines Beispiel:

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls, contnrs;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    PaintBox1: TPaintBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  private
    FMyShapes: TObjectList;
    { private declarations }
  public
    { public declarations }
  end;
 
  TMyShape = class(TObject)
  private
    FPosition: TPoint;
  public
    procedure Draw(C: TCanvas); virtual; abstract;
    property Position: TPoint read FPosition write FPosition;
  end;
 
  TMyRect = class(TMyShape)
  private
    FWidth, FHeight: integer;
  public
    procedure Draw(C: TCanvas); override;
    property Width: integer read FWidth write FWidth;
    property Height: integer read FHeight write FHeight;
  end;
 
  TMyLine = class(TMyShape)
  private
    FStartPoint, FEndPoint: TPoint;
  public
    procedure Draw(C: TCanvas); override;
    property StartPoint: TPoint read FStartPoint write FStartPoint;
    property EndPoint: TPoint read FEndPoint write FEndPoint;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
 
procedure TMyRect.Draw(C: TCanvas);
begin
  C.Rectangle(Position.X, Position.Y, Position.X + Width, Position.Y + Height);
end;
 
procedure TMyLine.Draw(C: TCanvas);
begin
  c.MoveTo(Position.X + StartPoint.X, Position.Y + StartPoint.Y);
  c.LineTo(Position.X + EndPoint.X, Position.Y + EndPoint.Y);
end;
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  randomize;
  FMyShapes := TObjectList.Create(True);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  // Adding an Object
  with FMyShapes[FMyShapes.Add(TMyLine.Create)] as TMyLine do
  begin
    Position := Point(0, 0);
    StartPoint := Point(Random(PaintBox1.Width), Random(PaintBox1.Height));
    EndPoint := Point(Random(PaintBox1.Width), Random(PaintBox1.Height));
  end;
  // Redraw everything
  PaintBox1.Invalidate;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
var
  i: integer;
begin
  // Reposition all Objects
  for i := 0 to FMyShapes.Count - 1 do
    (FMyShapes[i] as TMyShape).Position :=
      Point(Random(PaintBox1.Width), Random(PaintBox1.Height));
  // Redraw everything
  PaintBox1.Invalidate;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  FMyShapes.Free;
end;
 
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  i: integer;
begin
  //Clear
  PaintBox1.Canvas.Clear;
  for i := FMyShapes.Count - 1 downto 0 do    // FMyShapes[0] oberste Ebene
    (FMyShapes[i] as TMyShape).Draw(Canvas);
end;
 
end.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Strich zeichnen

Beitrag von mschnell »

Warf hat geschrieben:Also für ein simples Grafik Programm sollte die CPU schnell genug sein.

Es ist immer die Frage, was "Simpel" ist. Ein paar Stzriche auf große Pixel-Fläche zu malen und davon Teilbereiche anzuzeigen ist eigentlich simpel, aber flüssiges Zoom und Pan braucht trotzdem Hardware-Unterstützung.

-Michael

Dragomir
Beiträge: 40
Registriert: Di 28. Apr 2015, 12:06

Re: Strich zeichnen

Beitrag von Dragomir »

Danke für die Antworten :)

Ja das müsste jetz klar sein bin mal dabei das umzusetzen werde dann noch eintragen für was ich mich entschieden habe oder besser gesagt was am schnellsten ist :)

Danke danke :)

Dragomir
Beiträge: 40
Registriert: Di 28. Apr 2015, 12:06

Re: Strich zeichnen

Beitrag von Dragomir »

Mir wurde i wie was anderes von der Arbeit "empfohlen".

habe jetz bei einer zeichnung die koordinaten gespeichert und habe dann mit einem Mouse Move event, die Koordinaten verglichen. Wenn dann der Zeiger auf einem Strich ist, merkt er sich diese und mit nem Drag & drop event veränder ich die Daten und das OnPaint zeichnet neu.
Kommt mir i wie Stümperhaft rüber aber wenn man es so machen muss :/ .

Antworten