/ Forside / Teknologi / Udvikling / Delphi/Pascal / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Delphi/Pascal
#NavnPoint
oldwiking 603
jrossing 525
rpje 520
EXTERMINA.. 500
gandalf 460
gubi 270
DJ_Puden 250
PARKENSS 230
technet 210
10  jdjespers.. 200
Rotering af Image?
Fra : Monie Jacobsen


Dato : 22-07-02 10:12

Hej, Vil du hjælpe mig med nedstående?


Forslag fra Asger Grunnet

Jeg har ikke fulgt med i tråden indtil nu, så jeg er ikke sikker på om
det her hjælper. Jeg antager, at du har nogle punkter (x[i],y[i]) som du
gerne vil have roteret omkring et punkt (xc,yc) med en vinkel v.
De roterede punkter (xn[i],yn[i]) beregnes med:

xn[i] := (x[i]-xc)*cos(v/360 * 2*pi) - (y[i]-yc)*sin(v/360 * 2*pi) + xc;
yn[i] := (y[i]-yc)*cos(v/360 * 2*pi) + (x[i]-xc)*sin(v/360 * 2*pi) + yc;

Jeg går ud fra at koordinaterne (x[i], y[i], xn[i], yn[i], xc, yc) er
erklærede
som floating-point (f.eks. double eller extended). NEJ hvordan?

For at det ovenstående virker, skal du inkludere "math" i uses-listen. ER
ERKLÆRET.

Vil du være behjælpelig med, at tilrette nedstående procedure som Asger
Grunnet forslår.
Har prøvet, men uden held!

PROCEDURE TForm1.Button2Click(Sender: TObject);
var
X, Yop, Yned : array [0..18] of Real;
midY,roterY,roterX: Real;
count: Integer;

begin
X[0] := 0.00; Yop[0] := 0.00; Yned[0] := 0.00;
X[1] := 1.25; Yop[1] := 3.07; Yned[1] := -1.79;
X[2] := 2.50; Yop[2] := 4.18; Yned[2] := -2.48;
X[3] := 5.00; Yop[3] := 5.74; Yned[3] := -3.27;
X[4] := 7.50; Yop[4] := 6.91; Yned[4] := -3.71;
X[5] := 10.00; Yop[5] := 7.84; Yned[5] := -3.98;
X[6] := 15.00; Yop[6] := 9.27; Yned[6] := -4.18;
X[7] := 20.00; Yop[7] := 10.25; Yned[7] := -4.15;
X[8] := 25.00; Yop[8] := 10.92; Yned[8] := -3.98;
X[9] := 30.00; Yop[9] := 11.25; Yned[9] := -3.75;
X[10] := 40.00; Yop[10] := 11.25; Yned[10] := -3.25;
X[11] := 50.00; Yop[11] := 10.53; Yned[11] := -2.72;
X[12] := 60.00; Yop[12] := 9.30; Yned[12] := -2.14;
X[13] := 70.00; Yop[13] := 7.63; Yned[13] := -1.55;
X[14] := 80.00; Yop[14] := 5.55; Yned[14] := -1.03;
X[15] := 90.00; Yop[15] := 3.08; Yned[15] := -0.57;
X[16] := 95.00; Yop[16] := 1.67; Yned[16] := -0.35;
X[17] := 100.00; Yop[17] := 0.16; Yned[17] := -0.16;
X[18] := 100.00; Yop[18] := 0.00; Yned[18] := 0.00;

midY := Image1.Height /2; // Midten af Image1
roterY:=midY; // Roterings punkt Y
roterX:=25; // Roterings punkt X Afstand fra
profilets forreste 1/4 del.

count:=0;
repeat
// Tegn linie fra curX til Yned.
Image1.Canvas.MoveTo(Round(X[count]*zoom),Round(midY-Yned[count]*zoom));

Image1.Canvas.LineTo(Round(X[count+1]*zoom),Round(midY-Yned[count+1]*zoom));

// Tegn linie fra curX til Yop.
Image1.Canvas.MoveTo( Round(X[count]*zoom),Round(midY-Yop[count]*zoom));
Image1.Canvas.LineTo(
Round(X[count+1]*zoom),Round(midY-Yop[count+1]*zoom));

inc(count);
until(count = 19);
end;

På forhåndem mange tak.

MVH
Monie





 
 
Juno (23-07-2002)
Kommentar
Fra : Juno


Dato : 23-07-02 08:16

"Monie Jacobsen" skrev...
> Hej, Vil du hjælpe mig med nedstående?
> Forslag fra Asger Grunnet
>> xn[i] := (x[i]-xc)*cos(v/360 * 2*pi) - (y[i]-yc)*sin(v/360 * 2*pi) + xc;
>> yn[i] := (y[i]-yc)*cos(v/360 * 2*pi) + (x[i]-xc)*sin(v/360 * 2*pi) + yc;
>>
>> Jeg går ud fra at koordinaterne (x[i], y[i], xn[i], yn[i], xc, yc) er
>> erklærede
>> som floating-point (f.eks. double eller extended).
> NEJ hvordan?
Jo de er, Real er også floating point...
Floating point er bare endnu en måde at sige "kommatal" på.
Sæt markøren oveni ordet Real og tryk F1 hvis du vil vide mere...

> Vil du være behjælpelig med, at tilrette nedstående procedure som Asger
> Grunnet forslår.
> Har prøvet, men uden held!
OK, her kommer så en hel Unit, men måden den bliver roteret på, er
ikke helt hvad jeg havde forventet...
Jeg har delt koden lidt op, i et forsøg på at gøre den mere overskuelig :)
Har også lavet et par nye typer, håber du kan se meningen...
Hvis det her skal virke bare nogenlunde, skal Image1.Width = Image1.Height.
Så må du selv lege videre med den. Jeg kan ikke hjælpe med måden den bliver
roteret på... Det er Asger's kode, jeg har bare implementeret den :)

Forresten, den der Button1Click, er til at "rense" image1.
Så tror jeg der er mere :)
God fornøjelse.

--
*/*
jUno
spamfilter: Fjern din bh

*-*-*- kode begynd *-*-*-*
unit testdraw;

interface

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

type
TVingePkt = record
x: Real;
y: Real;
end;

TVingeKoord = record
Pkt1: TVingePkt;
Pkt2: TVingePkt;
end;

TForm1 = class(TForm)
Button2: TButton;
Image1: TImage;
Button1: TButton;
SpinEdit2: TSpinEdit;
Label1: TLabel;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

// bare en handy rutine.
function VingePkt( x, y: Real): TVingePkt;
begin
Result.x := x;
Result.y := y;
end;

// denne funktion bruger Asger's kode.
// (cx,cy) er centrum for rotering. v er vinklen.
// Returnerer et punkt med kommatals-koordinater.
function RotatePkt(pkt: TVingePkt; v, cx,cy: Real): TVingePkt;
const
toPi = 2*Pi;
begin
v := v / 360; // ingen grund til at beregne den 4 gange.
Result.x := (pkt.x-cx)*cos(v*toPi) - (pkt.y-cy)*sin(v*toPi) + cx;
Result.y := (pkt.y-cy)*cos(v*toPi) - (pkt.x-cx)*sin(v*toPi) + cy;
{
Asger's kode :
xn[i] := (x[i]-xc)*cos(v/360 * 2*pi) - (y[i]-yc)*sin(v/360 * 2*pi) + xc;
yn[i] := (y[i]-yc)*cos(v/360 * 2*pi) + (x[i]-xc)*sin(v/360 * 2*pi) + yc;
}
end;

// Tegner en linie på canvas fra pkt1 til pkt2.
procedure DrawLine( pkt1, pkt2: TVingePkt);
begin
with Form1.Image1.Canvas do
begin
MoveTo( Round(pkt1.x), Round(pkt1.y));
LineTo( Round(pkt2.x), Round(pkt2.y));
end;
end;

// init af X, Yop og Yned.
// koordinering og kald af tegne procedurer.
procedure TForm1.Button2Click(Sender: TObject);
var
X, Yop, Yned : array [0..18] of Real;
koord: array[0..18] of TVingeKoord;
cx, // rotér om denne x-koordinat.
midY: Real; // 1/2 image height. rotér om denne y-koodinat.
zoom, // skalerings faktor.
count: Integer; // taeller.
begin
X[0] := 0.00; Yop[1] := 0.00; Yned[1] := 0.00;
X[1] := 1.25; Yop[1] := 3.07; Yned[1] := -1.79;
X[2] := 2.50; Yop[2] := 4.18; Yned[2] := -2.48;
X[3] := 5.00; Yop[3] := 5.74; Yned[3] := -3.27;
X[4] := 7.50; Yop[4] := 6.91; Yned[4] := -3.71;
X[5] := 10.00; Yop[5] := 7.84; Yned[5] := -3.98;
X[6] := 15.00; Yop[6] := 9.27; Yned[6] := -4.18;
X[7] := 20.00; Yop[7] := 10.25; Yned[7] := -4.15;
X[8] := 25.00; Yop[8] := 10.92; Yned[8] := -3.98;
X[9] := 30.00; Yop[9] := 11.25; Yned[9] := -3.75;
X[10] := 40.00; Yop[10] := 11.25; Yned[10] := -3.25;
X[11] := 50.00; Yop[11] := 10.53; Yned[11] := -2.72;
X[12] := 60.00; Yop[12] := 9.30; Yned[12] := -2.14;
X[13] := 70.00; Yop[13] := 7.63; Yned[13] := -1.55;
X[14] := 80.00; Yop[14] := 5.55; Yned[14] := -1.03;
X[15] := 90.00; Yop[15] := 3.08; Yned[15] := -0.57;
X[16] := 95.00; Yop[16] := 1.67; Yned[16] := -0.35;
X[17] := 100.00; Yop[17] := 0.16; Yned[17] := -0.16;
X[18] := 100.00; Yop[18] := 0.00; Yned[18] := 0.00;
midY := Image1.Height /2;
zoom := Round( Image1.Width / X[High(X)])-1;
cx := Image1.Width / 2; // du kan aendre dette til 25 hvis du vil...

// beregn "absolutte" koordinater (uden rotation).
koord[0].Pkt1 := VingePkt(0,midY);
koord[0].Pkt2 := VingePkt(0,midY);
for count := 1 to 18 do
begin
koord[count].Pkt1.x := X[count]*zoom;
koord[count].Pkt1.y := midY - (Yop[count]*zoom + Yop[count-1]*zoom);
koord[count].Pkt2.x := koord[count].Pkt1.x;
koord[count].Pkt2.y := midY - (Yned[count]*zoom + Yned[count-1]*zoom);
end;
// rotér koordinater
// vinklen bliver laest fra SpinEdit2. cy er midY. cx er midX,
// (cx,cy) er centrum for rotation.
for count := 0 to 18 do
begin
koord[count].Pkt1 := RotatePkt( koord[count].Pkt1, SpinEdit2.Value, cx, midY);
koord[count].Pkt2 := RotatePkt( koord[count].Pkt2, SpinEdit2.Value, cx, midY);
end;
// tegn på canvas.
for count := 0 to 17 do
begin
DrawLine( koord[count].Pkt1, koord[count+1].Pkt1);
DrawLine( koord[count].Pkt2, koord[count+1].Pkt2);
end;
end;

// Clear Image1.
procedure TForm1.Button1Click(Sender: TObject);
var
r: TRect;
begin
with Image1 do
begin
Picture := nil;
if not Windows.GetClientRect(Handle, r) then
r := Rect( 0, 0, Width, Height);
Canvas.FillRect( r);
end;
end;

end.
-**-*--*-*-*-*-*- kode slut. Over and out. Bip. *--*-*



Asger Grunnet (31-07-2002)
Kommentar
Fra : Asger Grunnet


Dato : 31-07-02 18:41


Juno skrev:
> OK, her kommer så en hel Unit, men måden den bliver roteret på, er
> ikke helt hvad jeg havde forventet...
> Jeg har delt koden lidt op, i et forsøg på at gøre den mere overskuelig :)
> Har også lavet et par nye typer, håber du kan se meningen...
> Hvis det her skal virke bare nogenlunde, skal Image1.Width = Image1.Height.
> Så må du selv lege videre med den. Jeg kan ikke hjælpe med måden den bliver
> roteret på... Det er Asger's kode, jeg har bare implementeret den :)

Jeg er lige kommet hjem fra ferie, så jeg har ikke kunnet svare før nu.
Grunden til at profilen ikke bliver roteret korrekt er, at der har sneget
sig en lille fejl ind i din funktion RotatePkt:

> // denne funktion bruger Asger's kode.
> // (cx,cy) er centrum for rotering. v er vinklen.
> // Returnerer et punkt med kommatals-koordinater.
> function RotatePkt(pkt: TVingePkt; v, cx,cy: Real): TVingePkt;
> const
> toPi = 2*Pi;
> begin
> v := v / 360; // ingen grund til at beregne den 4 gange.
> Result.x := (pkt.x-cx)*cos(v*toPi) - (pkt.y-cy)*sin(v*toPi) + cx;
> Result.y := (pkt.y-cy)*cos(v*toPi) - (pkt.x-cx)*sin(v*toPi) + cy;

Denne linie skulle være:

Result.y := (pkt.y-cy)*cos(v*toPi) + (pkt.x-cx)*sin(v*toPi) + cy;

Bemærk at minus'et er ændret til et plus.

> {
> Asger's kode :
> xn[i] := (x[i]-xc)*cos(v/360 * 2*pi) - (y[i]-yc)*sin(v/360 * 2*pi) + xc;
> yn[i] := (y[i]-yc)*cos(v/360 * 2*pi) + (x[i]-xc)*sin(v/360 * 2*pi) + yc;
> }
> end;

Asger.



Monie Jacobsen (02-08-2002)
Kommentar
Fra : Monie Jacobsen


Dato : 02-08-02 00:53

Hej Asger

> Denne linie skulle være:
>
> Result.y := (pkt.y-cy)*cos(v*toPi) + (pkt.x-cx)*sin(v*toPi) + cy;
>
> Bemærk at minus'et er ændret til et plus.
>
Det førte kun til, at vingeprofilet roteret venstre mod højere.
Her nedenfor er så det samlet program.
Kan du se om jeg gør noget forkert eller har glemt noget?

var
Form1: TForm1;
zoom, V: Real;
implementation

{$R *.dfm}

function VingePkt( x, y: Real): TVingePkt;
begin
Result.x := x;
Result.y := y;
end;

function RotatePkt(pkt: TVingePkt; v, cx,cy: Real): TVingePkt;
const
toPi = 2*Pi;
begin
v := v / 360; // ingen grund til at beregne den 4 gange.
Result.x := (pkt.x-cx)*cos(v*toPi) - (pkt.y-cy)*sin(v*toPi) + cx;
Result.y := (pkt.y-cy)*cos(v*toPi) - (pkt.x-cx)*sin(v*toPi) + cy;
end;

// Tegner en linie på canvas fra pkt1 til pkt2.
procedure DrawLine( pkt1, pkt2: TVingePkt);
begin
with Form1.Image1.Canvas do
begin
MoveTo( Round(pkt1.x), Round(pkt1.y));
LineTo( Round(pkt2.x), Round(pkt2.y));
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;


procedure TForm1.Button2Click(Sender: TObject);
var
X, Yop, Yned : array [0..18] of Real;
koord: array[0..18] of TVingeKoord;
cx, // rotér om denne x-koordinat.
midY: Real; // 1/2 image height. rotér om denne y-koodinat.
zoom, // skalerings faktor.
count: Integer; // taeller.

begin
X[0] := 0.00; Yop[0] := 0.00; Yned[0] := 0.00;
X[1] := 1.25; Yop[1] := 3.07; Yned[1] := -1.79;
X[2] := 2.50; Yop[2] := 4.18; Yned[2] := -2.48;
X[3] := 5.00; Yop[3] := 5.74; Yned[3] := -3.27;
X[4] := 7.50; Yop[4] := 6.91; Yned[4] := -3.71;
X[5] := 10.00; Yop[5] := 7.84; Yned[5] := -3.98;
X[6] := 15.00; Yop[6] := 9.27; Yned[6] := -4.18;
X[7] := 20.00; Yop[7] := 10.25; Yned[7] := -4.15;
X[8] := 25.00; Yop[8] := 10.92; Yned[8] := -3.98;
X[9] := 30.00; Yop[9] := 11.25; Yned[9] := -3.75;
X[10] := 40.00; Yop[10] := 11.25; Yned[10] := -3.25;
X[11] := 50.00; Yop[11] := 10.53; Yned[11] := -2.72;
X[12] := 60.00; Yop[12] := 9.30; Yned[12] := -2.14;
X[13] := 70.00; Yop[13] := 7.63; Yned[13] := -1.55;
X[14] := 80.00; Yop[14] := 5.55; Yned[14] := -1.03;
X[15] := 90.00; Yop[15] := 3.08; Yned[15] := -0.57;
X[16] := 95.00; Yop[16] := 1.67; Yned[16] := -0.35;
X[17] := 100.00; Yop[17] := 0.16; Yned[17] := -0.16;
X[18] := 100.00; Yop[18] := 0.00; Yned[18] := 0.00;

midY := Image1.Height /2;
zoom := Round( Image1.Width / X[High(X)])-1;
cx := Image1.Width / 2; // du kan aendre dette til 25 hvis du vil...

// beregn "absolutte" koordinater (uden rotation).
koord[0].Pkt1 := VingePkt(0,midY);
koord[0].Pkt2 := VingePkt(0,midY);
for count := 1 to 18 do
begin
koord[count].Pkt1.x := X[count]*zoom;
koord[count].Pkt1.y := midY - (Yop[count]*zoom + Yop[count-1]*zoom);
koord[count].Pkt2.x := koord[count].Pkt1.x;
koord[count].Pkt2.y := midY - (Yned[count]*zoom + Yned[count-1]*zoom);
end;
// rotér koordinater
// vinklen bliver laest fra SpinEdit2. cy er midY. cx er midX,
// (cx,cy) er centrum for rotation.
for count := 0 to 18 do
begin
koord[count].Pkt1 := RotatePkt( koord[count].Pkt1, SpinEdit2.Value, cx,
midY);
koord[count].Pkt2 := RotatePkt( koord[count].Pkt2, SpinEdit2.Value, cx,
midY);
end;
// tegn på canvas.
for count := 0 to 17 do
begin
DrawLine( koord[count].Pkt1, koord[count+1].Pkt1);
DrawLine( koord[count].Pkt2, koord[count+1].Pkt2);
end;

end;

procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
zoom:= StrToInt(SpinEdit1.Text);
end;

procedure TForm1.SpinEdit2Change(Sender: TObject);
begin
V:= StrToInt(SpinEdit2.Text);
end;


procedure TForm1.Button4Click(Sender: TObject);

var
r: TRect;
begin
with Image1 do
begin
Picture := nil;
if not Windows.GetClientRect(Handle, r) then
r := Rect( 0, 0, Width, Height);
Canvas.FillRect( r);
end;
end;
end.

Med venlig hilsen
Monie




Juno (02-08-2002)
Kommentar
Fra : Juno


Dato : 02-08-02 01:41

[Asger]
>> Denne linie skulle være:
>> Result.y := (pkt.y-cy)*cos(v*toPi) + (pkt.x-cx)*sin(v*toPi) + cy;
>> Bemærk at minus'et er ændret til et plus.

[Monie]
> Det førte kun til, at vingeprofilet roteret venstre mod højere.
> Her nedenfor er så det samlet program.
> Kan du se om jeg gør noget forkert eller har glemt noget?
<snip kode>

Asger :
Øv, jeg troede lige jeg kunne "losse" det over på dig, og så er mig der
kvajet mig :o/

Monie :
Jeg kan ikke se at du har ændret noget i den kode du postede.
Det der skal ændres er linien i funktionen RotatePkt. Det er det
midterste minus der skal ændres til plus. Kun linien der begynder med
"Result.y := ...". Efter den ændring virker det fint her. Den bliver
ganske rigtigt roteret den anden vej rundt, men den bliver ikke
"vredet".

--
*/*
jUno
spamfilter: Fjern din bh



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste