基於螺旋隊列邏輯的螺旋運動實現
螺旋隊列演算法的逆向方法,控制兩軸馬達按螺旋軌跡運動,如下圖。
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)!