zoukankan      html  css  js  c++  java
  • 直线与圆弧插补采用DDS的模拟程序

    数字微分分析,本质是根据轨迹上的每个点的速度在各轴的分配比例转换成脉冲的分配比例
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using MathNet.Numerics;
    using MathNet.Numerics.LinearAlgebra.Generic;
    using MathNet.Numerics.LinearAlgebra.Double;
    using System.Drawing.Drawing2D;
    using System.Drawing.Text;
    
    
    namespace MC.UI
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    #region 画图指令
                    if (string.IsNullOrWhiteSpace(textBox1.Text)) return;
                    var lines = textBox1.Lines;
                    var gList = new List<G>();
                    foreach (var line in lines)
                    {
                        if (string.IsNullOrWhiteSpace(line)) continue;
                        var arr = line.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        if (arr.Length == 2)
                        {
                            gList.Add(new G(arr[0],arr[1]));
                        }
                    }
                    #endregion
                    pictureBox1.Image = DrawImg(gList);
                    tabControl1.SelectedIndex = 0;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
    
            }
            private void button2_Click(object sender, EventArgs e)
            {
                try
                {
                    #region 直线插补,倍率10
    
                    var gList = new List<G>();
                    int x = 0, y = 0;
                    int len = 2;//每步长度
                    int xe=400,ye=150;
    
                    var xe1 = xe / len;
                    var ye1 = ye / len;
    
                    var max = Math.Max(xe1, ye1);
                    var n =Math.Ceiling( Math.Log(max, 2));
                    Console.WriteLine("n:" + n);
                    var periodNum = Math.Pow(2.0, n);
                    double sX=0, sY = 0;
    
                  
                    for (int step = 0; step < periodNum; step++)
                    {
                        sX += xe1;
                        sY += ye1;
                        bool xOver = false;
                        bool yOver = false;
                        if (sX >= periodNum)
                        {
                            //X累加器溢出
                            sX -= periodNum;
                            xOver = true;
                        }
                        if (sY >= periodNum)
                        {
                            //Y累加器溢出 
                            sY -= periodNum;
                            yOver = true;
                        }
                    
                        if (xOver)
                        {
                            x = x + len;
                        }
                        if (yOver)
                        {
                            y = y + len;
                        }
                        if (xOver || yOver)
                        {
                            gList.Add(new G(x.ToString(), y.ToString()));
                        }
                    }
    
                    #endregion
                    pictureBox1.Image = DrawImg(gList);
                    tabControl1.SelectedIndex = 0;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                try
                {
                    #region 圆弧插补,第一象限逆时针圆
    
                    var gList = new List<G>();
                    
                    
                    int x0=400,y0=0;
                    int xe=0, ye=400;
                    int len = 1;//每步长度
                    int xi = x0, yi = y0;
                    //移动到圆弧开始点
                    gList.Add(new G(x0.ToString(),y0.ToString()));
                    int xe1 = xe / len, ye1 = ye / len;
                    int x01 = x0 / len, y01 = y0 / len;
    
                    var max =Math.Max( Math.Max(xe1, ye1),Math.Max(x01,y01));
                    var n = Math.Ceiling(Math.Log(max, 2));
                    Console.WriteLine("n:" + n);
                    var periodNum = Math.Pow(2.0, n);
                    double sX = 0, sY = 0;
    
    
                    while (!( Math.Abs(xe-xi)<=len && Math.Abs(ye-yi)<=len ))
                    {
    
                        bool xOver = false;
                        bool yOver = false;
                        sX += yi/len;
                        sY += xi/len;
    
                        if (sX >= periodNum)
                        {
                            //X累加器溢出
                            sX -= periodNum;
                            xi = xi - len;
                            xOver = true;
                        }
                        if (sY >= periodNum)
                        {
                            //Y累加器溢出 
                            sY -= periodNum;
                            yi = yi + len;
                            yOver = true;
                        }
    
    
                        if (xOver || yOver)
                        {
                            gList.Add(new G(xi.ToString(), yi.ToString()));
                        }
                        else
                        {
                            //两个坐标都没变化
                        }
        
                        
    
                    }
    
                    #endregion
                    pictureBox1.Image = DrawImg(gList);
                    tabControl1.SelectedIndex = 0;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            #region
            private static Matrix<double> _M = null;
            public static Point TransCoordinate(Point p)
            {
                if (_M == null)
                {
                    #region
                    //x,y,z-- x由左到右,y由上到下,z由屏幕向外坐标,
                    //平移到600,600,然后绕y轴转180度的坐标转换矩阵
                    double[,] a =
                {
                    {1 ,  0  ,0  ,600},
                    {0 , -1  ,0  ,600},
                    {0 ,  0  ,-1 , 0 },
                    {0 ,  0  ,0  , 1 } 
                };
                    _M = DenseMatrix.OfArray(a);
                    #endregion
                }
    
                var B = DenseVector.OfEnumerable(new double[] { p.X, p.Y, 0, 1 });
                var C = _M.Multiply(B);
                return new Point((int)C[0], (int)C[1]);
            }
            private static Point P(int x, int y)
            {
                return TransCoordinate(new Point(x, y));
    
            }
            public static Bitmap DrawImg(List<G> gList)
            {
                int w = 1200;
                int h = 1200;
                var bmp = new Bitmap(w, h);
                var g = Graphics.FromImage(bmp);
    
                g.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                g.FillRectangle(new SolidBrush(Color.White), 0, 0, w, h);
    
                #region 定义画笔
                var pen0 = new Pen(Brushes.AliceBlue, 0.1f);
                pen0.DashStyle = DashStyle.DashDot;
                pen0.Color = Color.Black;
    
                var pen1 = new Pen(Brushes.AliceBlue, 0.5f);
                pen1.Color = Color.Black;
    
                var pen1_red = new Pen(Brushes.AliceBlue, 0.5f);
                pen1_red.Color = Color.Red;
    
                var pen2 = new Pen(Brushes.AliceBlue, 1);
                pen2.Color = Color.Black;
    
                var pen10 = new Pen(Brushes.AliceBlue, 10f);
                pen10.Color = Color.Black;
    
                var font = new Font("宋体", 12, FontStyle.Regular);
                var font10 = new Font("宋体", 10, FontStyle.Regular);
                var font8 = new Font("宋体", 8, FontStyle.Regular);
                var brush = new SolidBrush(Color.Black);
                var brush_red = new SolidBrush(Color.Red);
                #endregion
                int x0 = 0;
                int y0 = 0;
                int x1=0;
                int y1=0;
                foreach (var it in gList)
                {
                    if (it.X == "x")
                    {
                        x1 = x0;
                    }
                    else
                    {
                        x1 = int.Parse(it.X);
                    }
                    if (it.Y == "y")
                    {
                        y1 = y0;
                    }
                    else
                    {
                        y1 = int.Parse(it.Y);
                    }
                    g.DrawLine(pen1, P(x0,y0), P(x1,y1));
                    x0 = x1;
                    y0 = y1;
                }
                return bmp;
            }
            public class G
            {
                public String X { get; set; }
                public String Y { get; set; }
    
                public G(String x, String y)
                {
                    X=x;
                    Y=y;
    
                }
            }
            #endregion
    
            
    
    
        }
    }
    View Code

     代码下载 :

    https://files.cnblogs.com/files/wdfrog/MC.UI.rar

    //对于其他曲线

    下面是椭圆,长短轴是2:1,平方后是4:1,

    对椭圆方程两边求x的导数可以得到dy/dx ,得表达式,dy/dx 对应这点(X,Y)得Vy/Vx之比

                try
                {
                    #region 椭圆弧插补,第一象限逆时针圆
    
                    var gList = new List<G>();
    
    
                    int x0 = 200, y0 = 0;
                    int xe = 0, ye = 400;
                    int len = 1;//每步长度
                    int xi = x0, yi = y0;
                    //移动到圆弧开始点
                    gList.Add(new G(x0.ToString(), y0.ToString()));
                    int xe1 = xe / len, ye1 = ye / len;
                    int x01 = x0 / len, y01 = y0 / len;
    
                    var max = Math.Max(Math.Max(xe1, ye1), Math.Max(x01, y01));
                    var n = Math.Ceiling(Math.Log(max, 2));
                    Console.WriteLine("n:" + n);
                    var periodNum = Math.Pow(2.0, n)*4;// (400 / 200)^2
                    double sX = 0, sY = 0;
    
    
                    while (!(Math.Abs(xe - xi) <= len*2 && Math.Abs(ye - yi) <= len*2))
                    {
    
                        bool xOver = false;
                        bool yOver = false;
                        sX += yi / len;
                        sY +=(4 * xi) / len;
    
                        if (sX >= periodNum)
                        {
                            //X累加器溢出
                            sX -= periodNum;
                            xi = xi - len;
                            xOver = true;
                        }
                        if (sY >= periodNum)
                        {
                            //Y累加器溢出 
                            sY -= periodNum;
                            yi = yi + len;
                            yOver = true;
                        }
    
    
                        if (xOver || yOver)
                        {
                            gList.Add(new G(xi.ToString(), yi.ToString()));
                        }
                        else
                        {
                            //两个坐标都没变化
                        }
    
                        //if (xi <= -1 || yi <= -1) break;
    
                    }
    
                    #endregion
                    pictureBox1.Image = DrawImg(gList);
                    tabControl1.SelectedIndex = 0;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
    View Code

     

    `注意根据代码每次累加的数(xe,ye--对于直线)是一样的所以xe+xe = xe *2 ,也就是相当于左移一位

    根据前面的视频可知,累加ye 或 xe最大取2^n -1 ,而累加寄存器最大取2^n , 而数2^n - 1  在n位寄存器里全是1111....,再累加一次2^n-1必定是溢出的

    而对应前i位(左边的)是0的,左移1位相当于乘以2,左移i位等于乘以2^i, 相当于要累加2^i次才能溢出

  • 相关阅读:
    OCP-1Z0-052-V8.02-112题
    OCP-1Z0-052-V8.02-109题
    OCP-1Z0-052-V8.02-41题
    OCP-1Z0-052-V8.02-40题
    OCP-1Z0-053-V12.02-492题
    基于MysqlConnector/C++的数据库连接池的实现
    mysql Connector C/C++ 多线程封装
    OCP-1Z0-052-V8.02-108题
    OCP-1Z0-052-V8.02-105题
    OCP-1Z0-052-V8.02-104题
  • 原文地址:https://www.cnblogs.com/wdfrog/p/15788716.html
Copyright © 2011-2022 走看看