• 技术文章 >后端开发 >C#.Net教程

    从0自学C#07--螺旋队列和螺旋运动

    黄舟黄舟2017-02-04 10:46:12原创748

    基于螺旋队列逻辑的螺旋运动实现

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

    783.png

    1.螺旋队列算法分析

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

    784.jpg


    每圈最大值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中文网(m.sbmmt.com)!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇: 从0自学C#06--多窗体共用对象 下一篇: 从0自学C#08--绘制曲线chart控件

    相关文章推荐

    • c语言中形参的缺省存储类别是什么• C# 2.0 Specification (泛型三)• C++中内存泄漏的检测• .NET原型模式讲解• C#的多线程机制初探(3)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网