基于螺旋队列逻辑的螺旋运动实现
螺旋队列算法的逆向方法,控制两轴马达按螺旋轨迹运动,如下图。

1.螺旋队列算法分析
下图是螺旋队列。设1的坐标是(0,0),x方向向右为正,y方向向下为正,例如,7的坐标为(-1,-1),2的坐标为(1,0)。编程实现输入任意一点坐标(x,y),输出所对应的数字!(转自网络)

每圈最大值max=(2*c+1)(2*c+1),c为由内往外的圈数。
这些基准值与max之间的差分别是1C(上边),3C(左边),5C(下边),7C(右边)(C表示当前圈数),在上边和下边,y坐标表示(或等于)圈数(即C=y),而在左边和右边,x坐标表示(或等于)圈数(即C=x)。因此前面提到的差值又可用坐标表示成1y,3x,5y,7x。
代码实现:
private static Object spiral(int x, int y)
{
int c = max(abs(x), abs(y));// 当前坐标所在圈
int max = (c * 2 + 1) * (c * 2 + 1);// 当前圈上最大值
if (y == -c) { // 上边
return max + (x + y);
} else if (x == -c) {// 左边
return max + (3 * x - y);
} else if (y == c) {// 下边
return max + (-x - 5 * y);
} else {// 右边
return max + (-7 * x + y);
}
}2.螺旋运动
首先自定义坐标运算,表示PD的逻辑位置。
struct Coordinate
{ public int X; public int Y; public Coordinate(int a, int b)
{
X = a;
Y = b;
} public static bool operator ==(Coordinate loc1, Coordinate loc2)
{ return (loc1.X == loc2.X) && (loc1.Y == loc2.Y);
} public static bool operator !=(Coordinate loc1, Coordinate loc2)
{ return !(loc1 == loc2);
} public override bool Equals(object loc)
{ return this == (Coordinate)loc;
} public override int GetHashCode()
{ return base.GetHashCode();
} public static Coordinate operator -(Coordinate loc1, Coordinate loc2)
{ return new Coordinate(loc1.X - loc2.X, loc1.Y - loc2.Y);
} public static Coordinate operator +(Coordinate loc1, Coordinate loc2)
{ return new Coordinate(loc1.X + loc2.X, loc1.Y + loc2.Y);
} public override string ToString()
{ return "(" + X + "," + Y + ")";
}
}然后逆向方法,根据步数算出x,y坐标。
public Coordinate ToLocation(int step, int pulse)
{
int c = (int)Math.Ceiling((Math.Sqrt(step) - 1) / 2);
int max = (int)Math.Pow(2 * c + 1, 2);
int x, y;
y = -c;//top
x = -(max + y - step);
if (Math.Abs(x) <= Math.Abs(y))
{
this.location.X = x * pulse;
this.location.Y = y * pulse;
return this.location;
}
x = -c;//left
y = max + 3 * x - step;
if (Math.Abs(y) <= Math.Abs(x))
{
this.location.X = x * pulse;
this.location.Y = y * pulse;
return this.location;
}
y = c;//bottom
x = max - 5 * y - step;
if (Math.Abs(x) <= Math.Abs(y))
{
this.location.X = x * pulse;
this.location.Y = y * pulse;
return this.location;
}
x = c;//right
y = -(max - 7 * x - step);
this.location.X = x * pulse;
this.location.Y = y * pulse;
//LocChange();
return this.location;
}最后,根据坐标的变化实现运动。
public void Start()
{
Coordinate moveToLoc, currentLoc, deltaLoc;
currentLoc = ToLocation(1, 0);
logInfo = string.Format("{0}: {1}{2}.", DateTime.Now.ToString("HH:mm:ss"), "the start location is ", currentLoc.ToString());
log.SaveLogToTxt(logInfo);
logInfo = string.Format("{0}: {1}.", DateTime.Now.ToString("HH:mm:ss"), "begin to move... ");
log.SaveLogToTxt(logInfo);
for (int step = 1; step <= this.roMaxStep[0]; step++)
{
moveToLoc = ToLocation(step + 1, this.roPulse[0]);
deltaLoc = moveToLoc - currentLoc;
logInfo = string.Format("{0}: step{1}{2}{3}...", DateTime.Now.ToString("HH:mm:ss"), step + " ", "move to ", moveToLoc.ToString());
log.SaveLogToTxt(logInfo);
bool moveX = card.MoveX(deltaLoc.X);
bool moveY = card.MoveY(deltaLoc.Y);
if (moveX == false || moveY == false)
//throw error
return;
currentLoc = moveToLoc;
//if RES > RoRESTarget
//break;
}
logInfo = string.Format("{0}: {1}.", DateTime.Now.ToString("HH:mm:ss"), "move done");
log.SaveLogToTxt(logInfo);
logInfo = string.Format("{0}: {1}{2}.", DateTime.Now.ToString("HH:mm:ss"), "the current location is ", currentLoc.ToString());
log.SaveLogToTxt(logInfo);
}以上就是 从0自学C#07--螺旋队列和螺旋运动的内容,更多相关内容请关注PHP中文网(www.php.cn)!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号