求解旋转中心

分类: 365直播网APP下载 📅 2025-09-20 08:45:10 👤 admin 👁️ 2217 ❤️ 453
求解旋转中心

1.求旋转中心

public static Point CalculateRotateCenter(Point p1, Point p2, double angle)

{

double r = angle / 180.0 * Math.PI;

double x = 0.5 * ((p2.Y - p1.Y) * Math.Sin(r) + (p2.X + p1.X) * Math.Cos(r) - (p2.X + p1.X)) / (Math.Cos(r) - 1.0);

double y = 0.5 * ((p2.Y + p1.Y) * Math.Cos(r) - (p2.X - p1.X) * Math.Sin(r) - (p2.Y + p1.Y)) / (Math.Cos(r) - 1.0);

return new Point(x, y);

}

2、已知旋转中心求旋转点

public static Point CalculateRotateCenter(Point p1, Point p2, double angle)

{

double r = angle / 180.0 * Math.PI;

double x = 0.5 * ((p2.Y - p1.Y) * Math.Sin(r) + (p2.X + p1.X) * Math.Cos(r) - (p2.X + p1.X)) / (Math.Cos(r) - 1.0);

double y = 0.5 * ((p2.Y + p1.Y) * Math.Cos(r) - (p2.X - p1.X) * Math.Sin(r) - (p2.Y + p1.Y)) / (Math.Cos(r) - 1.0);

return new Point(x, y);

}

3、向量法求解

using System;

public class RotationCenterCalculator

{

public static (double X, double Y) CalculateRotationCenter(double p1x, double p1y, double p2x, double p2y)

{

// 计算P1和P2之间的中点

double midX = (p1x + p2x) / 2.0;

double midY = (p1y + p2y) / 2.0;

// 计算P1和P2之间的距离

double distance = Math.Sqrt(Math.Pow(p2x - p1x, 2) + Math.Pow(p2y - p1y, 2));

// 旋转半径等于P1和P2之间距离除以根号2

double radius = distance / Math.Sqrt(2);

// 旋转中心位于P1和P2连线的垂直平分线上,且距离中点radius远

// 由于是顺时针旋转90度,旋转中心位于P1和P2连线的垂直平分线的下方(或左侧,取决于坐标系的方向)

// 但由于我们不知道具体是在哪个方向上(上方或下方,左侧或右侧),我们需要考虑两种情况

// 然而,在这个特定情况下,由于旋转是90度,我们只需要考虑一个确定的方向

// 旋转中心位于中点向下(或向左,取决于你如何定义旋转的方向)偏移radius的位置

// 但实际上,由于旋转中心位于垂直平分线上,且距离两点等远,我们只需要考虑中点和半径即可确定位置

// 这里我们假设坐标系是标准的,即x轴向右,y轴向上,因此旋转中心位于中点的左下方(对于顺时针旋转)

// 但由于旋转中心实际上位于中垂线上且与两点的连线垂直,我们可以通过中点和向量旋转来确定其位置

// 不过,为了简化,我们可以直接使用中点和半径以及旋转方向来“猜测”旋转中心的位置

// 在这个例子中,我们知道旋转中心位于P1和P2连线的中垂线上,且距离它们radius远

// 我们可以使用中点和P1到P2的向量来计算出旋转中心的坐标

// 向量P1P2

double dx = p2x - p1x;

double dy = p2y - p1y;

// 旋转中心坐标(使用中点和旋转半径以及旋转方向来确定)

// 由于是顺时针旋转90度,我们可以将向量P1P2旋转-90度(即逆时针旋转90度的相反方向)来找到从中点到旋转中心的向量

// 然后将这个向量加到中点上即可得到旋转中心的坐标

// 旋转-90度的向量是(dy, -dx)除以向量的长度(但在这里我们不需要除以长度,因为我们已经知道半径)

double centerX = midX - dy * (radius / distance); // 注意:这里乘以radius/distance实际上是多余的,因为dy已经是单位向量的一部分了,但为了保持一致性,可以保留

double centerY = midY + dx * (radius / distance); // 同上

// 但由于我们已经知道distance = radius * sqrt(2),所以上面的计算可以简化为:

centerX = midX - dy / Math.Sqrt(2);

centerY = midY + dx / Math.Sqrt(2);

// 或者更简单地,由于我们只需要确定旋转中心位于中垂线上且与P1和P2等远,我们可以直接使用中点和半径来计算:

// centerX = midX - (p2y - p1y) / 2(这是错误的,因为上面的旋转逻辑不适用,这里只是为了说明直接计算的方法不可行)

// centerY = midY + (p2x - p1x) / 2(这同样是错误的)

// 正确的做法是使用上面的旋转向量方法或者下面的简化方法(考虑到旋转角度是90度的特殊情况)

// 正确的简化方法(考虑到旋转角度是90度,且旋转中心位于中垂线上):

// 由于旋转中心位于中垂线上,我们可以直接使用中点和P1到P2的单位向量的垂直分量来确定位置

// 单位向量P1P2是(dx/distance, dy/distance),其垂直向量是(-dy/distance, dx/distance)

// 但由于我们只需要找到旋转中心,且知道旋转半径,我们可以直接使用中点和这个垂直向量乘以半径来确定位置

// 不过,为了与上面的计算保持一致(尽管有些步骤是多余的),我们可以使用下面的方法:

// 最终简化的正确计算:

centerX = midX - dy * (1 / Math.Sqrt(2)); // 乘以1/sqrt(2)是因为我们要得到单位向量的一部分,但在这里乘以radius(即distance/sqrt(2))已经是单位向量的倍数了,所以直接乘以1/sqrt(2)即可

centerY = midY + dx * (1 / Math.Sqrt(2)); // 同上

// 但由于我们之前已经计算了radius,并且知道distance = radius * sqrt(2),所以上面的乘以1/sqrt(2)实际上是直接使用radius来计算:

// centerX = midX - (p2y - p1y) * (1 / (2 * radius / distance)) = midX - (p2y - p1y) * (sqrt(2) / 2 * 1/sqrt(2)) = midX - (p2y - p1y) / 2 * (但这里我们不需要再除以2,因为radius已经是distance的一半的sqrt(2)倍了)

// centerY = midY + (p2x - p1x) * (1 / (2 * radius / distance)) = 同上(但注意这里的计算过程是为了说明,实际上我们应该直接使用上面的简化方法)

// 所以,最终的正确计算就是:

centerX = midX - dy / Math.Sqrt(2); // 这与上面的正确简化方法中的第一个等式相同(但注意这里的dy已经是P1和P2的y坐标差)

centerY = midY + dx / Math.Sqrt(2); // 这与上面的正确简化方法中的第二个等式相同(但注意这里的dx已经是P1和P2的x坐标差)

// 注意:上面的解释中有些步骤是冗余的,目的是为了说明计算过程。实际的正确计算就是最后给出的两个等式。

return (centerX, centerY);

}

public static void Main()

{

double p1x = 0, p1y = 0; // 点P1的坐标

double p2x = 1, p2y = 1; // 点P2的坐标(假设P1顺时针旋转90度后到达P2的位置)

var rotationCenter = CalculateRotationCenter(p1x, p1y, p2x, p2y);

Console.WriteLine($"Rotation center: X = {rotationCenter.X}, Y = {rotationCenter.Y}");

}

}

public class RotationCenterCalculator

{

///

/// 计算旋转中心

///

/// 初始点

/// 旋转后的点

/// 旋转角度(度)

/// 旋转中心

public static Point CalculateRotationCenter(Point p1, Point p2, double angleDegrees)

{

// 将角度转换为弧度

double angleRadians = angleDegrees * Math.PI / 180;

// 计算 P1 和 P2 的中点

double midX = (p1.X + p2.X) / 2;

double midY = (p1.Y + p2.Y) / 2;

// 计算 P1 到 P2 的向量

double dx = p2.X - p1.X;

double dy = p2.Y - p1.Y;

// 计算 P1 和 P2 之间的距离

double distance = Math.Sqrt(dx * dx + dy * dy);

// 计算旋转半径

double radius = distance / (2 * Math.Sin(angleRadians / 2));

// 计算垂直平分线的斜率

double slopePerpendicular = -dx / dy;

// 计算旋转中心

double centerX = midX - (dy / distance) * radius * Math.Cos(angleRadians / 2);

double centerY = midY + (dx / distance) * radius * Math.Cos(angleRadians / 2);

return new Point(centerX, centerY);

}

}

旋转半径公式:

旋转半径 R与两点距离 d 和旋转角度θ 的关系为:

R= d/2sin(θ/2)

旋转中心坐标:

旋转中心位于垂直平分线上,且距离中点的长度为 Rcos(θ/2)。

旋转中心的坐标为:

centerX=midX− dy/d ⋅R⋅cos(θ/2)

centerY= midY+ dx/d R⋅cos(θ/2)

相关文章