调整有角度的矩形的大小
我有一个矩形,它是 4 点结构的数组。它可以以任何角度(0 到 360 度)旋转并正确绘制。
用户还可以拖动一个角来调整矩形的大小。例如,如果移动左下点,它也会更新左上点的 X 坐标和右下点的 Y 坐标。这样,无论移动到哪一点,它都将始终是一个矩形。
Points[point] = newValue;
switch (point)
{
case TopLeft:
Points[BottomLeft].X = newValue.X;
Points[TopRight].Y = newValue.Y;
break;
case BottomRight:
Points[TopRight].X = newValue.X;
Points[BottomLeft].Y = newValue.Y;
break;
case BottomLeft:
Points[TopLeft].X = newValue.X;
Points[BottomRight].Y = newValue.Y;
break;
case TopRight:
Points[BottomRight].X = newValue.X;
Points[TopLeft].Y = newValue.Y;
break;
}
在这里,我将四个点中的任何一个更改为给定的输入点 (newValue),然后修改链接的点,使其保持矩形形状。
但是,如果我的矩形处于这样的角度,我需要修改上面的代码才能工作:
此处添加的示例代码:
http://www.assembla.com/code/moozhe-testing/subversion/nodes/rotateRectangle
I have a Rectangle which is an array of 4 Point structures. It can be rotated in place on any angle (0 to 360 degrees) and will draw properly.
The user can also drag a corner to resize the rectangle. For example, if they move the bottom-left point, it will also update the X coordinate of the upper-left point, and the Y coordinate of the lower-right point. In this way, it will always be a rectangle no matter which point they move.
Points[point] = newValue;
switch (point)
{
case TopLeft:
Points[BottomLeft].X = newValue.X;
Points[TopRight].Y = newValue.Y;
break;
case BottomRight:
Points[TopRight].X = newValue.X;
Points[BottomLeft].Y = newValue.Y;
break;
case BottomLeft:
Points[TopLeft].X = newValue.X;
Points[BottomRight].Y = newValue.Y;
break;
case TopRight:
Points[BottomRight].X = newValue.X;
Points[TopLeft].Y = newValue.Y;
break;
}
Here I change any of the four points to the given input point (newValue), and then modify the linked points so that it stays a Rectangle shape.
However, I need to modify the above code to work if my rectangle is on an angle like this:
Sample code added here:
http://www.assembla.com/code/moozhe-testing/subversion/nodes/rotateRectangle
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我看到有 2 个解决方案。第一个理论上可行,但由于四舍五入,它最终不起作用。我将把第一个解决方案放在那里,但第二个是好的解决方案。
在这些示例中,我将 4 个角称为 CornerA、B、C 和 D,以顺时针方式命名。假设您要将“CornerA”从位置
Point oldPoint
移动到位置Point newPoint
。第一个解决方案:
sideAtoB
上对该增量进行投影,并将该向量添加到 PointD。sideDtoA
上对该增量进行投影,并将该向量添加到 PointB。第二种解决方案:
这是第二个解决方案的代码:
I see 2 solutions. The first one theoretically works, but because of rounding, it ends up not working. I'll let the first solution there, but the second one is the good one.
In these samples, I'll call the 4 corners CornerA, B, C and D, named in a clockwise fashion. Let's say you're moving "CornerA" from a position
Point oldPoint
to positionPoint newPoint
.First solution :
sideAtoB
and add that vector to PointD.sideDtoA
and add that vector to PointB.Second solution :
Here is the code for that 2nd solution :
我使用了一个计算垂直线之间交点的解决方案:
给定一个旋转矩形(未轴对齐),其中包含点 A、B、C 和 D,以及拖动点 D1(这是从 D 拖动的新点),则目标是找到 C1 和 A1 的新点。 B与D相对,不会移动。
要找到 C1 和 A1,请找到与点 D1 的线的交点,该线与 AB 和 BC 相交,并且垂直于线 AB 和 BC(直角)。这些交叉点将为您提供点 C1 和 A1。由于这两条线垂直于 AB 和 BC,因此它们将形成新的矩形。使用线性方程计算斜率、截距和倒数斜率,这将为您提供计算 AB 和 D1A 之间交点所需的两条直线。对另一边重复上述操作,得到 BC 和 D1C 之间的交集(记住,对于轴对齐的矩形,下面的内容不是必需的,而且更容易)
解决方案:
求直线 AB 和 AC 的斜率、相反的斜率和 y 截距。并找到线 D1A 和 D1C 的 y 截距。然后计算交集得到x,将x代入其中一条直线的线方程得到y:
相应地重复上述6次计算得到C1x和C1y
I used a solution that calculates the intersection between perpendicular lines:
Given a rotated rectangle (NOT axis aligned) with points, A, B, C, and D, and a dragged point D1 (which is the new point dragged from D), the goal is to find the new points for C1 and A1. B is opposite of D and will not move.
To find C1 and A1, find the intersection of the lines with points D1, which intersect with AB and BC and that are perpendicular to lines AB and BC (right angle). Those intersections will give you the points C1 and A1. Since the lines are perpendicular to AB and BC, they will form the new rectangle. Use the linear equations to calculate the slopes, intercepts and reciprocal slopes, which will give you both lines needed to calculate the intersection between AB and D1A. Repeat for the other side to get the intersection between BC and D1C (Remember, for axis-aligned rectangles, the below is not necessary and much easier)
Solution:
Find the slopes, opposite reciprocal slopes, and y-intercepts of the lines AB and AC. And find the y-intercepts of the lines D1A and D1C. Then calculate the intersection to get x and plug x into the lienar equation of one of the lines to get y:
Repeat above 6 calculations accordingly to get C1x and C1y