计算特定旋转的特定曲线,c#
Calculate a specific curve with specific rotation, c#
我正在尝试为我正在使用特定旋转的特定曲线工作的游戏编写代码。我不是一个伟大的数学家......根本......试图寻找解决方案几个小时,但我恐怕找不到任何解决方案。
那么,先上一张小图来说明一下:
这是一个八分之一的圆,半径为9,起点是(0,0)
收盘价现在大约在 6.364,-2.636。但我需要同样的曲线,在末端有 45° 方向,但恰好在 6.0,-3.0 处结束。
你们谁能告诉我怎么做吗?我需要能够精确计算这条曲线上的任何点及其确切长度。我想使用某种椭圆数学可能是一种解决方案?我承认我的数学 class 现在真的很厉害,现在有了很好的线索...
感谢任何可能的帮助
我想我找到了满足您要求的二次曲线:
f(x) = -1/12 x^2 + 9
将以下内容复制到https://www.desmos.com/calculator中查看:
-\frac{1}{12}x^2+9
f'(x) 将为 -1/6x,因此当 x=6 时,导数将为 -1,对应于 -45° 倾角。可能有无限的曲线可以满足您的要求,但如果我的微积分不太生锈,这就是其中之一。
我试图将焦点从 y=6
here and starting at y=9
here 开始的椭圆拟合到您的点,但斜率看起来不像 45°。
同样从任意高度k开始,here好像不行。
我认为您没有完全理解我在评论中提出的关于 "inclination" 角度的问题。所以我将给出一个 general 案例解决方案,其中你有一个明确的 切线向量 作为曲线的末端。 (您可以使用倾斜角来计算它;如果我们阐明您的意思,那么我很乐意在必要时使用公式进行编辑以计算切线向量)
让我们画一张图来说明设置的外观:
(并非 100% 准确)
A
和 B
是您的固定点。 T
是单位切向量。 r
和C
是我们需要计算的圆弧的半径和圆心。
角度 θ
由 BA
和 T
之间的角度减去 π/2
弧度(90 度)得出。我们可以使用点积来计算它:
从 AB
的中心到 C
的(有符号)距离由下式给出:
请注意,右侧的情况为负,左侧为正。半径由下式给出:
(您可以通过替换和使用余弦加法规则来简化,但我更喜欢用图中的变量来表示)。要获得点 C
,我们需要 AB
的垂直向量(称之为 n
):
既然我们有了圆弧的半径和中心,我们还需要确定哪个 我们移动的方向,即从 A
到 B
。这是一个简单的测试,使用 叉积:
如果这个是负数,那么T
就是图中这样,我们需要顺时针移动,反之亦然。弧长l
,沿弧移动x
距离angular位移γ
:
快到了!仅需一步 - 我们需要计算出如何将点 A
围绕点 C
旋转角度 γ
,以获得我们想要的点(称之为 D
) :
(改编自此Wikipedia page)
现在看一些代码,以防上面的内容令人困惑(可能是!):
public Vector2 getPointOnArc(Vector2 A, Vector2 B, Vector2 T, double x)
{
// calculate preliminaries
Vector2 BA = B - A;
double d = BA.Length();
double theta = Math.Acos(Vector2.DotProduct(BA, T) / d) - Math.PI * 0.5;
// calculate radius
double r = d / (2.0 * Math.Cos(theta));
// calculate center
Vector2 n = new Vector2(BA.y, -BA.x);
Vector2 C = 0.5 * (A + B + n * Math.Tan(theta));
// calculate displacement angle from point A
double l = (Math.PI - 2.0 * theta) * r;
double gamma = (2.0 * Math.PI * x) / l;
// sign change as discussed
double cross = T.x * BA.y - T.y * BA.x;
if (cross < 0.0) gamma = -gamma;
// finally return the point we want
Vector2 disp = A - C;
double c_g = Math.Cos(gamma), s_g = Math.Sin(gamma);
return new Vector2(disp.X * c_g + disp.Y * s_g + C.X,
disp.Y * c_g - disp.X * s_g + C.Y);
}
我正在尝试为我正在使用特定旋转的特定曲线工作的游戏编写代码。我不是一个伟大的数学家......根本......试图寻找解决方案几个小时,但我恐怕找不到任何解决方案。
那么,先上一张小图来说明一下:
这是一个八分之一的圆,半径为9,起点是(0,0)
收盘价现在大约在 6.364,-2.636。但我需要同样的曲线,在末端有 45° 方向,但恰好在 6.0,-3.0 处结束。
你们谁能告诉我怎么做吗?我需要能够精确计算这条曲线上的任何点及其确切长度。我想使用某种椭圆数学可能是一种解决方案?我承认我的数学 class 现在真的很厉害,现在有了很好的线索...
感谢任何可能的帮助
我想我找到了满足您要求的二次曲线:
f(x) = -1/12 x^2 + 9
将以下内容复制到https://www.desmos.com/calculator中查看:
-\frac{1}{12}x^2+9
f'(x) 将为 -1/6x,因此当 x=6 时,导数将为 -1,对应于 -45° 倾角。可能有无限的曲线可以满足您的要求,但如果我的微积分不太生锈,这就是其中之一。
我试图将焦点从 y=6
here and starting at y=9
here 开始的椭圆拟合到您的点,但斜率看起来不像 45°。
同样从任意高度k开始,here好像不行。
我认为您没有完全理解我在评论中提出的关于 "inclination" 角度的问题。所以我将给出一个 general 案例解决方案,其中你有一个明确的 切线向量 作为曲线的末端。 (您可以使用倾斜角来计算它;如果我们阐明您的意思,那么我很乐意在必要时使用公式进行编辑以计算切线向量)
让我们画一张图来说明设置的外观:
(并非 100% 准确)
A
和 B
是您的固定点。 T
是单位切向量。 r
和C
是我们需要计算的圆弧的半径和圆心。
角度 θ
由 BA
和 T
之间的角度减去 π/2
弧度(90 度)得出。我们可以使用点积来计算它:
从 AB
的中心到 C
的(有符号)距离由下式给出:
请注意,右侧的情况为负,左侧为正。半径由下式给出:
(您可以通过替换和使用余弦加法规则来简化,但我更喜欢用图中的变量来表示)。要获得点 C
,我们需要 AB
的垂直向量(称之为 n
):
既然我们有了圆弧的半径和中心,我们还需要确定哪个 我们移动的方向,即从 A
到 B
。这是一个简单的测试,使用 叉积:
如果这个是负数,那么T
就是图中这样,我们需要顺时针移动,反之亦然。弧长l
,沿弧移动x
距离angular位移γ
:
快到了!仅需一步 - 我们需要计算出如何将点 A
围绕点 C
旋转角度 γ
,以获得我们想要的点(称之为 D
) :
(改编自此Wikipedia page)
现在看一些代码,以防上面的内容令人困惑(可能是!):
public Vector2 getPointOnArc(Vector2 A, Vector2 B, Vector2 T, double x)
{
// calculate preliminaries
Vector2 BA = B - A;
double d = BA.Length();
double theta = Math.Acos(Vector2.DotProduct(BA, T) / d) - Math.PI * 0.5;
// calculate radius
double r = d / (2.0 * Math.Cos(theta));
// calculate center
Vector2 n = new Vector2(BA.y, -BA.x);
Vector2 C = 0.5 * (A + B + n * Math.Tan(theta));
// calculate displacement angle from point A
double l = (Math.PI - 2.0 * theta) * r;
double gamma = (2.0 * Math.PI * x) / l;
// sign change as discussed
double cross = T.x * BA.y - T.y * BA.x;
if (cross < 0.0) gamma = -gamma;
// finally return the point we want
Vector2 disp = A - C;
double c_g = Math.Cos(gamma), s_g = Math.Sin(gamma);
return new Vector2(disp.X * c_g + disp.Y * s_g + C.X,
disp.Y * c_g - disp.X * s_g + C.Y);
}