Algorithm c语言中的线性增长算法#
从x、y、z三个变量的起点到另一个点;什么是最好的线性算法 例如: 从x:0,y=0,z=0到x:10,y=20,z=50 我寻找的方法是在每个同质化递增块上的相等步长 编辑歧义:Algorithm c语言中的线性增长算法#,algorithm,c#-4.0,Algorithm,C# 4.0,从x、y、z三个变量的起点到另一个点;什么是最好的线性算法 例如: 从x:0,y=0,z=0到x:10,y=20,z=50 我寻找的方法是在每个同质化递增块上的相等步长 编辑歧义: 我问这个问题是关于马达控制的。电机控制x和y坐标,但不能同时执行步骤。所以我的运动必须像梯子或正方形。因此,我正在寻找3个(或更多)坐标的最小阶梯,如最小二乘逻辑,精确地用c#表示。您可以使用简单的线性插值: f(t) = start + t * (end - start), t in [0, 1] = (
我问这个问题是关于马达控制的。电机控制x和y坐标,但不能同时执行步骤。所以我的运动必须像梯子或正方形。因此,我正在寻找3个(或更多)坐标的最小阶梯,如最小二乘逻辑,精确地用c#表示。您可以使用简单的线性插值:
f(t) = start + t * (end - start), t in [0, 1]
= (1 - t) * start + t * end
如果将t增加一个恒定的量,步长也将是恒定的。如果要执行n
步骤,应将t增加
dt = 1 / n
在每一步中
插值可以按坐标独立计算。使用整数坐标,可以将差值除以: 有些线只有两个步骤,因为它们不能在所有三维空间中平均划分。(例如
(0,0,0)-(17,19,23)
)
或者,你可以使用
公共静态IEnumerable GetPointsOnLine(int x0、int y0、int z0、int x1、int y1、int z1)
{
bool-swapXY=Math.Abs(y1-y0)>Math.Abs(x1-x0);
bool-swapXZ=Math.Abs(z1-z0)>Math.Abs(x1-x0);
if(swapXY)
{
int tmp;
tmp=x0;x0=y0;y0=tmp;
tmp=x1;x1=y1;y1=tmp;
}
if(swapXZ)
{
int tmp;
tmp=x0;x0=z0;z0=tmp;
tmp=x1;x1=z1;z1=tmp;
}
int deltaX=Math.Abs(x1-x0);
int deltaY=Math.Abs(y1-y0);
int deltaZ=数学绝对值(z1-z0);
int-floftxy=deltaX/2;
int-floftxz=deltaX/2;
int stepX=x0使用最小二乘法进行直线拟合。当你查询“c#最小二乘拟合”时,谷歌点击了大量。由于模糊性,我编辑了问题。我们是否有机会通过递归方式改进线性插值?(问题已编辑。)实际上,你的编辑让我更加困惑。你可以通过添加dt*(end-start)迭代计算插值
每一步。非常感谢你的帮助,马库斯。问题的第一部分由你来解决。最后,我有最难的部分,均化步骤。例如:x1,y1,z1=0,0,0;x2,y2,z2=2,50100;和gcd(d1,d2,d3)=2;除以后,我们得到了这个值:1,25,50:我所说的第二个值是,在50之前,它不能走25次,步骤必须如下:1,1,1;0,0,1;0,1,1;0,0,1;0,1,1;…(50次)通过每次检查下一个坐标的优先级。你会说什么?谢谢。如果你想要小步,请在我的答案中尝试Bresenham算法。它每次最多步(1,1,1),并且将保持接近理想线。
var gcd = Gcd(x2 - x1, y2 - y1, z2 - z1);
var stepX = (x2 - x1) / gcd;
var stepY = (y2 - y1) / gcd;
var stepZ = (z2 - z1) / gcd;
public static IEnumerable<Point> GetPointsOnLine(int x0, int y0, int z0, int x1, int y1, int z1)
{
bool swapXY = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
bool swapXZ = Math.Abs(z1 - z0) > Math.Abs(x1 - x0);
if (swapXY)
{
int tmp;
tmp = x0; x0 = y0; y0 = tmp;
tmp = x1; x1 = y1; y1 = tmp;
}
if (swapXZ)
{
int tmp;
tmp = x0; x0 = z0; z0 = tmp;
tmp = x1; x1 = z1; z1 = tmp;
}
int deltaX = Math.Abs(x1 - x0);
int deltaY = Math.Abs(y1 - y0);
int deltaZ = Math.Abs(z1 - z0);
int driftXY = deltaX / 2;
int driftXZ = deltaX / 2;
int stepX = x0 <= x1 ? 1 : -1;
int stepY = y0 <= y1 ? 1 : -1;
int stepZ = z0 <= z1 ? 1 : -1;
int y = y0;
int z = z0;
for (int x = x0; x*stepX <= x1*stepX; x += stepX)
{
int xc = swapXY ? y : swapXZ ? z : x;
int yc = swapXY ? swapXZ ? z : x : y;
int zc = swapXZ ? x : z;
yield return new Point(xc, yc, zc);
driftXY -= deltaY;
if (driftXY < 0)
{
y += stepY;
driftXY += deltaX;
}
driftXZ -= deltaZ;
if (driftXZ < 0)
{
z += stepZ;
driftXZ += deltaX;
}
}
}