Kig på \"Efg\'s Computer Lab\", der finder du det du søger. Jeg har selv brugt formlerne til at \"rotere nogle koordinater\":
http://www.efg2.com/lab/ eller direkte link hvis du hellere vi have denne:
http://www.efg2.com/lab/ImageProcessing/RotateScanline.htmUd fra formlerner har jeg lavet flg. Component (til behandling af \"punkter\"). Erstat \"Float\" med \"Double\" (eller lign.):
<SNIP>
//--- Interface ---
TFloatPoint = Class(TPersistent)
private
Fx : Float;
Fy : Float;
FAsCompas : Boolean;
public
Constructor Create(nX : Float = 0.0; nY : Float = 0.0;
lAsCompas : Boolean = False);
Procedure Assign(Source: TPersistent); Override;
//---
Procedure Translate(nX, nY : Float);
Function DeltaX(Point : TFloatPoint) : Float;
Function DeltaY(Point : TFloatPoint) : Float;
Function Distance(Point : TFloatPoint) : Float;
Function Direction(Point : TFloatPoint) : Float;
Function Bearing(Point : TFloatPoint) : Float;
Procedure RotatePoint(Point : TFloatPoint; nDegrees : Float);
Procedure Rotate(nDegrees : Float);
//---
property X : Float Read fX Write fX;
property Y : Float Read fY Write fY;
property AsCompas : Boolean Read FAsCompas Write FAsCompas;
end;
//--- Implementation ---
Function Degrees360(nDegrees : Float) : Float;
begin
Result := nDegrees;
While (Result >= 360) do Result := Result - 360;
While (Result < 0) do Result := Result + 360;
end;
Function CompasMathDegree(nDegrees : Float) : Float;
begin
Result := Degrees360((360 - nDegrees) + 90);
end;
//---
Constructor TFloatPoint.Create(nX : Float = 0.0; nY : Float = 0.0;
lAsCompas : Boolean = False);
begin
Fx := nX;
Fy := nY;
FAsCompas := lAsCompas;
end;
Procedure TFloatPoint.Assign(Source : TPersistent);
begin
Fx := TFloatPoint(Source).Fx;
Fy := TFloatPoint(Source).Fy;
FAsCompas := TFloatPoint(Source).FAsCompas;
end;
Procedure TFloatPoint.Translate(nX, nY : Float);
begin
Fx := Fx + nX;
Fy := Fy + nY;
end;
Function TFloatPoint.DeltaX(Point : TFloatPoint) : Float;
begin
Result := Fx - Point.X;
end;
Function TFloatPoint.DeltaY(Point : TFloatPoint) : Float;
begin
Result := Fy - Point.Y;
end;
Function TFloatPoint.Distance(Point : TFloatPoint) : Float;
var
nX, nY : Float;
begin
nX := DeltaX(Point);
nY := DeltaY(Point);
Result := Sqrt((nX*nX)+(nY*nY));
end;
Function TFloatPoint.Direction(Point : TFloatPoint) : Float;
var
nDeltaX : Float;
nDeltaY : Float;
nDistance : Float;
begin
nDeltaX := Fx - Point.X;
nDeltaY := Fy - Point.Y;
nDistance := Sqrt((nDeltaX*nDeltaX)+(nDeltaY*nDeltaY));
Result := (RadToDeg(ArcCos(Abs(nDeltaX)/nDistance)) +
RadToDeg(ArcSin(Abs(nDeltaY)/nDistance))) / 2;
if (nDeltaX < 0) and (nDeltaY > 0) then Result := 180 - Result;
if (nDeltaX < 0) and (nDeltaY < 0) then Result := Result + 180;
if (nDeltaX > 0) and (nDeltaY < 0) then Result := 360 - Result;
if FAsCompas then Result := CompasMathDegree(Result);
end;
Function TFloatPoint.Bearing(Point : TFloatPoint) : Float;
begin
Result := Degrees360(360 - Direction(Point));
end;
Procedure TFloatPoint.RotatePoint(Point : TFloatPoint; nDegrees : Float);
var
nDeltaX : Float;
nDeltaY : Float;
nDistance : Float;
nDegree : Float;
begin
nDeltaX := Fx - Point.X;
nDeltaY := Fy - Point.Y;
if (nDeltaX = 0.0) and (nDeltaY = 0.0) then Exit; // Nothing to rotate
nDistance := Sqrt((nDeltaX*nDeltaX)+(nDeltaY*nDeltaY));
nDegree := (RadToDeg(ArcCos(Abs(nDeltaX)/nDistance)) +
RadToDeg(ArcSin(Abs(nDeltaY)/nDistance))) / 2;
if (nDeltaX < 0) and (nDeltaY > 0) then nDegree := 180 - nDegree;
if (nDeltaX < 0) and (nDeltaY < 0) then nDegree := nDegree + 180;
if (nDeltaX > 0) and (nDeltaY < 0) then nDegree := 360 - nDegree;
nDegree := Degrees360(nDegree + nDegrees);
Fx := (Cos(DegToRad(nDegree)) * nDistance) + Point.X;
Fy := (Sin(DegToRad(nDegree)) * nDistance) + Point.Y;
end;
Procedure TFloatPoint.Rotate(nDegrees : Float);
var
Point : TFloatPoint;
begin
Point := TFloatPoint.Create(0.0, 0.0);
Point.AsCompas := AsCompas;
RotatePoint(Point, nDegrees);
Point.Free;
end;
</SNIP>
Jeg vil håbe at jeg har husket det hele, ellers må du sige til.