我正在尝试使用此代码
旋转其点来旋转矩形 var
dx,dy:real;
rotp:Tpoint;
begin
dx := (CenterPoint.Y * Sin(angle)) - (CenterPoint.X * Cos(angle)) + CenterPoint.X;
dy := -(CenterPoint.X * Sin(angle)) - (CenterPoint.Y * Cos(angle)) + CenterPoint.Y;
rotP.X := round((point.X * Cos(angle)) - (point.Y * Sin(angle)) + dx);
rotP.Y := round((point.X * Sin(angle)) + (point.Y * Cos(angle)) + dy);
result:= rotP;
end;
但是圆形功能会使矩形变形,有谁知道如何克服这个问题?
我附加了图像,白点是我围绕中心点旋转的点,我确信图像旋转得很好,因此白点应该与图像的角相同。
答案 0 :(得分:7)
我能看到这种方法失败的唯一方法就是改变周边的每个点。如果你这样做,不要。使用图形基元变换角点并在每个角之间绘制线条。
更新:您的评论会让游戏消失。每次数字化时,您都会反复旋转并累积错误,转换为整数。通过将坐标存储为双精度值来处理它,并在需要绘制时按需转换为整数。
事实上,如果我是你,我会将你的主数据视为一个位置和一个角度,两者都存储为双精度。我根本不会存储角落的坐标。我会存储一个位置(中心或一个角)和一个方向角(相对于固定的全局轴系统)。这样你就会总是绘制一个真正的矩形。在每个积分步骤中根据需要增加位置和方向,然后根据主数据计算角的位置。这样做,你永远不会受到形状扭曲。
答案 1 :(得分:4)
由于浮点变量的分辨率有限,浮点计算(尤其是三角函数)总是容易出错。将坐标差与三角函数相乘而不是乘以坐标并减去结果时,可以提高计算的精度。您可以尝试此代码(假设角度为弧度,并使用math.pas):
var
dx,dy,ca,sa:Extended;
rotp:Tpoint;
begin
SinCos(angle, sa, ca);
dx := point.x - CenterPoint.X;
dy := point.y - CenterPoint.Y;
result.X := CenterPoint.X + round(dx*ca - dy*sa);
result.Y := CenterPoint.Y + round(dx*sa + dy*ca);
end;
更新:根据David的编辑回答,您不应该使用增量旋转,因为这会增加舍入误差。
答案 2 :(得分:1)
type
TRectangle = record
A, B, C, D: TPoint;
end;
var
Rectangle, // master rect
TurnedRectangle: TRectangle; // turned rect
...
procedure RotateRectangle;
begin
TurnedRectangle.A := RotatePoint(Rectangle.A);
...
DrawRectangle
end
function RotatePoint(Point: TPoint): TPoint;
var
dx, dy: Real;
rotp: TPoint;
begin
dx := (CenterPoint.Y * Sin(angle)) - (CenterPoint.X * Cos(angle)) + CenterPoint.X;
dy := -(CenterPoint.X * Sin(angle)) - (CenterPoint.Y * Cos(angle)) + CenterPoint.Y;
rotP.X := Round((Point.X * Cos(angle)) - (point.Y * Sin(angle)) + dx);
rotP.Y := Round((Point.X * Sin(angle)) + (point.Y * Cos(angle)) + dy);
result:= rotP;
end;
procedure DrawRectangle;
begin
Canvas.Polygon([TurnedRectangle.A, TurnedRectangle.B, TurnedRectangle.C, TurnedRectangle.D]);
end;