单独旋转矩形点使矩形变形
我尝试使用此代码通过旋转其点来旋转矩形,
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;
但 round 函数使矩形扭曲,有人知道如何克服这个问题吗?
我附上了图像,白点是我绕中心点旋转的点,我确信图像旋转得很好,因此,白点应该与图像的角相同。
I'm trying to rotate a rectangle by rotating its points , using this code
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;
but the round function makes the rectangle distorted , has anyone any idea how to overcome this?
I attached the image, the white points are the points i rotate about the center point, i'm sure that the image is rotated well thus, the white points should be identical to the corners of the image.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为这种方法会失败的唯一方法是如果你正在改变周边的每个点。如果你正在这样做,那就不要这样做。使用图形基元变换角并在每个角之间绘制线条。更新: 您的评论泄露了游戏的真相。每次通过转换为整数进行数字化时,都会重复旋转并累积错误。通过将坐标存储为双精度值来处理这个问题,并在需要绘制时根据需要转换为整数。
事实上,如果我是你,我会将你的主数据视为位置和角度,两者都以双精度存储。我根本不会存储角点的坐标。我将存储一个位置(中心或一个角)和一个方向角(相对于固定的全局轴系统)。这样你总是会画出一个真正的矩形。在每个积分步骤中,根据需要增加位置和方向,然后根据主数据计算角的位置。这样做,你的形状就永远不会变形。
The only way I can see that this approach would fail is if you are transforming every point on the perimeter. If you are doing that, don't. Transform the corners and draw lines between each corner using graphics primitives.Update: Your comment gives the game away. You are rotating repeatedly and accumulating errors every time you digitise by converting to integer. Deal with that by storing your coordinates as double precision values and just convert to integer on demand when you need to draw.
In fact, if I were you I would treat your master data to be a position and an angle, both stored to double precision. I would not store the coordinates of the corners at all. I would store a position (center or one of the corners) and an orientation angle (relative to a fixed global axis system). That way you will always draw a true rectangle. At each integration step increment position and orientation as necessary and then calculate the position of the corners from the master data. Do it like this and you will never suffer from distortion of your shape.
由于浮点变量的分辨率有限,浮点计算(尤其是三角函数)总是容易出错。将坐标差与三角函数相乘,而不是先将坐标相乘,再将结果相减,可以提高计算精度。您可以尝试以下代码(假设角度以弧度为单位并使用 math.pas):
更新: 根据 David 编辑的答案,您不应使用增量旋转,因为这会增加舍入误差。
Floating point calculations, especially with trigonometric functions, are always error prone due to the limited resolution of float variables. You could enhance the precision of the calculation when you multiply the coordinate differences with the trigonometric function instead of multiplying the coordinates and subtracting the results. You can try this code (assuming angle is in radians and math.pas is used):
Update: And according to David's edited answer, you shouldn't use incremental rotations as this will increase the rounding error.