Autor Beitrag
ZeitGeist87
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1593
Erhaltene Danke: 20

Win95-Win10
Delphi 10 Seattle, Rad Studio 2007, Delphi 7 Prof., C++, WSH, Turbo Pascal, PHP, Delphi X2
BeitragVerfasst: Fr 16.05.14 08:46 
Guten Morgen zusammen,

ich sitze seit gestern Nachmittag an einem Problem, bei dessen Lösung ich auf dem Schlauch sitze.
Mir fehlt hier ein Denkanstoß.

Zum Problem:

Gegeben ist ein Objekt: siehe Vorlage.
Dieses Besteht in diesem Beispiel aus 4 Bildern (TImage). Eins für die Form und jeweils ein TImage für die Markierung (rot, grün und blau).

Das Objekt wird wird auf einer Scrollbox platziert und soll nun rotiert werden. Soweit alles kein Problem, die Form wird rotiert, 90° im Uhrzeigersinn.

Jetzt geht mein eigentliches Problem los: Die Markierungen an den definierten Positionen müssen sich um 90° mit rotieren.

Folgenden Lösungsansatz hab ich, zumindest dachte ich, dass ich auf Basis einer Rotation eines Punktes arbeite:

Ich nehme mir vom entsprechenden Marker (rot, grün und dann blau) jeweils TOP/LEFT und betrachte diesen als Koordinate im absoluten Raum und wende dann einfach die Formel

X2 = +(X1*cos(90)) + (Y1*sin(90))
Y2 = -(X1*sin(90)) + (Y1*cos(90))


darauf an.

Allerdings rotiert das die Objekte irgendwo hin.

Dann kam mir die Idee, dass ich vom Mittelpunkt der Form ausgehen sollte und diese darum rotiere?

Ich wäre froh um eure Hilfe.

Danke und schönen Freitag,
Stefan

Crosspost in der DP
Einloggen, um Attachments anzusehen!
_________________
Wer Provokationen, Ironie, Sarkasmus oder Zynismus herauslesen kann soll sie ignorieren um den Inhalt meiner Beiträge ungetrübt erfassen zu können.
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1448

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Fr 16.05.14 09:16 
Hallo,
user profile iconZeitGeist87 hat folgendes geschrieben Zum zitierten Posting springen:
Allerdings rotiert das die Objekte irgendwo hin.
Dann kam mir die Idee, dass ich vom Mittelpunkt der Form ausgehen sollte und diese darum rotiere?

Einen Punkt korrekt Drehen um einen beliebigen Punkt P geht normalerweise in 3 Schritten.
Zuerst wird eine Verschiebung durchgeführt, die P in den Ursprung transformiert, danach wird um (0;0) gedreht und anschließend die Translation rückgängig gemacht.
Dreht sich Deine Form um ihren Mittelpunkt, so ist dieser Mittelpunkt auch der Drehpunkt für Deine anderen Objekte.

Beste Grüße
Mathematiker
Einloggen, um Attachments anzusehen!
ZeitGeist87 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1593
Erhaltene Danke: 20

Win95-Win10
Delphi 10 Seattle, Rad Studio 2007, Delphi 7 Prof., C++, WSH, Turbo Pascal, PHP, Delphi X2
BeitragVerfasst: Fr 16.05.14 09:26 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,
user profile iconZeitGeist87 hat folgendes geschrieben Zum zitierten Posting springen:
Allerdings rotiert das die Objekte irgendwo hin.
Dann kam mir die Idee, dass ich vom Mittelpunkt der Form ausgehen sollte und diese darum rotiere?

Einen Punkt korrekt Drehen um einen beliebigen Punkt P geht normalerweise in 3 Schritten.
Zuerst wird eine Verschiebung durchgeführt, die P in den Ursprung transformiert, danach wird um (0;0) gedreht und anschließend die Translation rückgängig gemacht.
Dreht sich Deine Form um ihren Mittelpunkt, so ist dieser Mittelpunkt auch der Drehpunkt für Deine anderen Objekte.

Beste Grüße
Mathematiker


Klingt wunderbar. Nur muss ich sagen, bin mathematisch nicht so bewandert.

Könntest du mir hier eine Hilfestellung geben, wie ich das in Delphi bewerkstellige?
Ich hab noch nie mit Matrizen gerechnet...

_________________
Wer Provokationen, Ironie, Sarkasmus oder Zynismus herauslesen kann soll sie ignorieren um den Inhalt meiner Beiträge ungetrübt erfassen zu können.
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1448

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Fr 16.05.14 09:34 
Hallo,
user profile iconZeitGeist87 hat folgendes geschrieben Zum zitierten Posting springen:
Könntest du mir hier eine Hilfestellung geben, wie ich das in Delphi bewerkstellige?

Beispiel: x1,y1 sollen um xp,yp gedreht werden.
ausblenden Quelltext
1:
2:
3:
4:
5:
1. xh := x1-xp;  yh := y1-xp;
2. xh, yh mit Deinen Gleichungen drehen, also
X2 := +(xh*cos(90)) + (yh*sin(90)); 
Y2 := -(xh*sin(90)) + (yh*cos(90)); 
3. x1 := x2+xp; y1 := y2+yp;

Übrigens sind bei einem 90°-Winkel cos 90° = 0 und sin 90° = 1. Damit kannst Du es auf
ausblenden Quelltext
1:
2:
3:
4:
5:
1. xh := x1-xp;  yh := y1-xp;
2. xh, yh mit Deinen Gleichungen drehen, also
X2 := yh; 
Y2 := -xh; 
3. x1 := x2+xp; y1 := y2+yp;

reduzieren und weiter zusammenfassen.
ausblenden Quelltext
1:
2:
X2 := y1-xp; Y2 := -x1+xp; 
x1 := x2+xp; y1 := y2+yp;

Beste Grüße
Mathematiker
ZeitGeist87 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1593
Erhaltene Danke: 20

Win95-Win10
Delphi 10 Seattle, Rad Studio 2007, Delphi 7 Prof., C++, WSH, Turbo Pascal, PHP, Delphi X2
BeitragVerfasst: Fr 16.05.14 10:55 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,
user profile iconZeitGeist87 hat folgendes geschrieben Zum zitierten Posting springen:
Könntest du mir hier eine Hilfestellung geben, wie ich das in Delphi bewerkstellige?

Beispiel: x1,y1 sollen um xp,yp gedreht werden.
ausblenden Quelltext
1:
2:
3:
4:
5:
1. xh := x1-xp;  yh := y1-xp;
2. xh, yh mit Deinen Gleichungen drehen, also
X2 := +(xh*cos(90)) + (yh*sin(90)); 
Y2 := -(xh*sin(90)) + (yh*cos(90)); 
3. x1 := x2+xp; y1 := y2+yp;

Übrigens sind bei einem 90°-Winkel cos 90° = 0 und sin 90° = 1. Damit kannst Du es auf
ausblenden Quelltext
1:
2:
3:
4:
5:
1. xh := x1-xp;  yh := y1-xp;
2. xh, yh mit Deinen Gleichungen drehen, also
X2 := yh; 
Y2 := -xh; 
3. x1 := x2+xp; y1 := y2+yp;

reduzieren und weiter zusammenfassen.
ausblenden Quelltext
1:
2:
X2 := y1-xp; Y2 := -x1+xp; 
x1 := x2+xp; y1 := y2+yp;

Beste Grüße
Mathematiker


ausblenden Quelltext
1:
1. xh := x1-xp;  yh := y1-xp;					


Muss das nicht yh := y1-yp lauten?

_________________
Wer Provokationen, Ironie, Sarkasmus oder Zynismus herauslesen kann soll sie ignorieren um den Inhalt meiner Beiträge ungetrübt erfassen zu können.
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1448

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Fr 16.05.14 11:43 
user profile iconZeitGeist87 hat folgendes geschrieben Zum zitierten Posting springen:
Muss das nicht yh := y1-yp lauten?

Muss es, natürlich. :autsch:
Sorry

Mathematiker
ZeitGeist87 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1593
Erhaltene Danke: 20

Win95-Win10
Delphi 10 Seattle, Rad Studio 2007, Delphi 7 Prof., C++, WSH, Turbo Pascal, PHP, Delphi X2
BeitragVerfasst: Fr 16.05.14 11:48 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconZeitGeist87 hat folgendes geschrieben Zum zitierten Posting springen:
Muss das nicht yh := y1-yp lauten?

Muss es, natürlich. :autsch:
Sorry

Mathematiker


Kein Problem. Man soll ja auch das Hirn einschalten und nicht alles via Copy&Paste übernehmen ;-)

Ich hab es jetzt mal implementiert, allerdings glaube ich, hab ich noch einen..Schwachpunkt.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
unit unit_main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Imaging.jpeg, Vcl.ExtCtrls,
  Vcl.Imaging.pngimage, Vcl.StdCtrls, Generics.Collections, System.Math;

type
  RMarker = record
    Top: Integer;
    Left: Integer;
    Width: Integer;
    Height: Integer;
  end;

type
  TMarker = TDictionary<TImage, RMarker>;

type
  Tform_main = class(TForm)
    Image1: TImage;
    img1: TImage;
    Button1: TButton;
    Image2: TImage;
    shape_mittelpunkt: TShape;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    fRotationCount: Integer;

    fMarker: TMarker;

    fMarker1Left, fMarker1Top, fMarker1Width, fMarker1Height: Integer;
  public
    { Public-Deklarationen }
  end;

var
  form_main: Tform_main;

implementation

{$R *.dfm}

procedure DreheBmp(Grad: Word; SourceBmp, DestBmp: TBitmap);
var
  Points: array [0 .. 2of TPoint;
  Winkel: Double;
  X1, X2, Y1, Y2: Integer;
begin
  if Grad <= 360 then
  begin
    Winkel := (Grad - Grad div 90 * 90) / 180 * pi;
    X1 := Round(SourceBmp.Width * sin(Winkel));
    X2 := Round(SourceBmp.Width * cos(Winkel));
    Y2 := Round(SourceBmp.Height * sin(Winkel));
    Y1 := Round(SourceBmp.Height * cos(Winkel));
    Case Grad of
      0 .. 89360:
        begin
          Points[1] := Point(X2, 0); // rechts oben
          Points[0] := Point(0, X1); // links oben
          Points[2] := Point(Y2, Y1 + X1); // links unten
          DestBmp.Width := X2 + Y2;
          DestBmp.Height := Y1 + X1;
        end;
      90 .. 179:
        begin
          Points[1] := Point(0, Y2); // rechts oben
          Points[0] := Point(X1, Y2 + X2); // links oben
          Points[2] := Point(X1 + Y1, X2); // links unten
          DestBmp.Width := Y1 + X1;
          DestBmp.Height := X2 + Y2;
        end;
      180 .. 269:
        begin
          Points[1] := Point(Y2, X1 + Y1); // rechts oben
          Points[0] := Point(Y2 + X2, Y1); // links oben
          Points[2] := Point(X2, 0); // links unten
          DestBmp.Width := X2 + Y2;
          DestBmp.Height := Y1 + X1;
        end;
      270 .. 359:
        begin
          Points[1] := Point(X1 + Y1, X2); // rechts oben
          Points[0] := Point(Y1, 0); // links oben
          Points[2] := Point(0, Y2); // links unten
          DestBmp.Width := Y1 + X1;
          DestBmp.Height := X2 + Y2;
        end;
    end;
    PlgBlt(DestBmp.Canvas.Handle, Points, SourceBmp.Canvas.Handle, 00,
      SourceBmp.Width, SourceBmp.Height, 000);
  end;
end;

procedure Tform_main.Button1Click(Sender: TObject);
var
  bmp1, bmp2: TBitmap;

  xp, yp: Integer;
  X1, Y1: Integer;
  X2, Y2: Integer;
  xh, yh: Integer;
begin
  bmp1 := TBitmap.Create;
  bmp1.Assign(Image1.Picture.Graphic);
  bmp2 := TBitmap.Create;

  inc(fRotationCount);

  // Mittelpunkt des T-Stücks
  xp := (Image1.Left + Image1.Width) - (Image1.Width div 2);
  yp := (Image1.Top + Image1.Height) - (Image1.Height div 2);

  // Drehpunkt TOP/LEFT T-Stück (DEBUG)
  // xp := Image1.Left;
  // yp := Image1.Top;

  // TOP/LEFT des Markers
  X1 := img1.Left;
  Y1 := img1.Top;

  // Differenz zum Mittelpunkt
  xh := X1 - xp;
  yh := Y1 - yp;

  X2 := +Round((xh * cos(DegToRad(90))) + (yh * sin(DegToRad(90))));
  Y2 := -Round((xh * sin(DegToRad(90))) + (yh * cos(DegToRad(90))));

  X1 := X2 + xp;
  Y1 := Y2 + yp;

  X2 := Y1 - xp;
  Y2 := -X1 + xp;
  X1 := X2 + xp;
  Y1 := Y2 + yp;

  // Zuweisung neuer Koordinaten
  img1.Left := X1;
  img1.Top := Y2;

  // Drehe T-Stück
  // DreheMarker(img1);
  DreheBmp(90, bmp1, bmp2);
  Image1.Picture.Assign(bmp2);

  // Mittelpunkt nach Drehung holen (DEBUG)
  xp := (Image1.Left + Image1.Width) - (Image1.Width div 2);
  yp := (Image1.Top + Image1.Height) - (Image1.Height div 2);

  // Objektmittelpunkt anzeigen (DEBUG)
  shape_mittelpunkt.Left := xp - shape_mittelpunkt.Width div 2;
  shape_mittelpunkt.Top := yp - shape_mittelpunkt.Height div 2;

end;

end.
Einloggen, um Attachments anzusehen!
_________________
Wer Provokationen, Ironie, Sarkasmus oder Zynismus herauslesen kann soll sie ignorieren um den Inhalt meiner Beiträge ungetrübt erfassen zu können.
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1448

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Fr 16.05.14 13:53 
Hallo,
user profile iconZeitGeist87 hat folgendes geschrieben Zum zitierten Posting springen:
Ich hab es jetzt mal implementiert, allerdings glaube ich, hab ich noch einen..Schwachpunkt.

Kannst Du eine Exe anhängen.
Mit meinem Delphi 5 kann ich es nicht übersetzen und sehe deshalb nicht, wo der "Schwachpunkt" ist.

Beste Grüße
Mathematiker
ZeitGeist87 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1593
Erhaltene Danke: 20

Win95-Win10
Delphi 10 Seattle, Rad Studio 2007, Delphi 7 Prof., C++, WSH, Turbo Pascal, PHP, Delphi X2
BeitragVerfasst: Fr 16.05.14 14:05 
Na klar ;-)

Ich kann es auch schnell in D7 tippen.
Einloggen, um Attachments anzusehen!
_________________
Wer Provokationen, Ironie, Sarkasmus oder Zynismus herauslesen kann soll sie ignorieren um den Inhalt meiner Beiträge ungetrübt erfassen zu können.