• 来玩玩画直线


    哦啦啦,俺又来啦,几个月不见是不是很想俺呐,挖哈哈 (¯▽¯;)。

    俺这个文章纯属抛砖引玉 ,希望各位高手不要丢板砖啦。

    俺们写程序也就是一个乐趣 比不了你们这些博客园的牛x人啦

    这次俺们来秀下直线方程 小意思 见笑啦,俺们用得最多的就是.net了哈 所以依旧在.net平台上做测试

    好正题:

    先把一次函数搬出来哈

    直线的方程:y=ax+b

    地球人都知道哈啊,如果是初中都没上的同学请略过。。。

    还有两边都是1的直角等边三角形他的斜边是多少?当然是根号2啦  哈哈哈

    平常老在VC里lineTo()过去 lineTo()过来,童鞋们难道就没想过他是怎么来的么。

    如果知道了两个坐标(x1,y1 )(x2,y2) ,也就是你的鼠标在你的form1上在不同地方点两下  于是就有了两个point对象 明白了噻

    关于直线方程 它有很多“式”哈, 比如像点斜式啊 海底捞月式啊 老树盘根式啊 两点式啊 三点式啊 啥的,

    俺们这里由于事先知道了两个点(坐标),所以当然是用两点式啦:

     (y-y1)/(y2-y1)=(x-x1)/(x2-x1)

    y2 y1 x2 x1 俺都了解,熟么 那个y是怎么回事? 这个嘛⊙﹏⊙ 。。。

    上头那个公式是在百度里抄的 俺错了∪﹏∪。

    上头那些最后发现行不通,所以基本都是废话

    俺们现在用到的解决方案:

    既然知道了两个坐标(x跟y的值) 我们就仿照y=ax+b 连立个二元一次方程组

    管他行不行得通先搞个山寨的再说,比如p1=(0,1) p2=(5,4)

    代入方程

    1=a*0+b

    4=a*5+b

    不要告诉我你不会解二元一次方程组哈

    先把b=y1-a*x1代入2式

    a=(y2-y1)/(x2-x1)

    然后求

    b=y1-a*x1

    这就好办了噻,反正都是坐标 x1肯定不等于x2噻 否则就是一条竖线了,

    让x1往x2的方向累加或者累减 然后不断求出y的值  连续起来不就是一条直线了么

    挖哈哈终于OK了

    别高兴得过早⊙﹏⊙∥ ,

    Windows下的坐标系是这样的:

    数学里的平面直角坐标系是这样的:

    对此我们只需要做这样的操作即可(看到上面那破图别恶心哈,又把它整出来了 俄罗斯方块的文章里也有):

    //第一步
    //由于Windows坐标跟数学坐标系的不同 先把 Windows坐标 x y变成负数(假设他是数学坐标里的第三象限)
    Point t1=new Point(0-p1.X,0-p1.Y);
    Point t2=new Point(0-p2.X,0-p2.Y);
    

    为什么要这样呢,我不解释 。可能有朋友说只要把x变成负数不就行了吗 真的行吗 你试试吧。

    为什么要这样呢,他究竟是为什么呢 这是为什么呢。坐标系的第一到三象限我都没有画出来 可能容易让大家迷糊。

    且听贫僧慢慢道来:

    Windows坐标系下的x y全是正数,我们把它投射到直角坐标系的第三象限(也就是x y 全是负数)。

    然而第三象限投射过后的直线 跟第四象限里的直线是相互对称的 你没发现吗

    总之上面的意思可以用下图表示:

    怎么变回Windows里的第四象限? 好说,在最终结果全部取绝对值就ok啦:

    //注意 从平面直角坐标系到Windows坐标系的转换
    drawPoint(new Point((int)Math.Abs(i), (int)Math.Abs(ty)));
    

    最后发点小牢骚都知道bitmap有setpixel()函数 graphics下俺想找个画点的函数愣是没找着,也许小弟见识少真没见过。

    只有自己随便整了个:

    void drawPoint(Point p1)//画点 p1是Windows坐标
    {
        Bitmap p = new Bitmap(1,1);
        Graphics g = Graphics.FromImage(p);
        g.Clear(Color.Red);
        gph.DrawImage(p, new Point(p1.X, p1.Y));
    }
    

    说实话代码不多哈 就那么几十行,关键是理论。 是骡子是马拉出来溜溜 献丑了哈:

    void drawPoint(Point p1)//画点 p1是Windows坐标
    {
        Bitmap p = new Bitmap(1,1);
        Graphics g = Graphics.FromImage(p);
        g.Clear(Color.Red);
        gph.DrawImage(p, new Point(p1.X, p1.Y));
    }
    
    void drawLine(Point p1,Point p2)//画线的函数 p1 p2均为Windows坐标
    {
        //直线方程
        //y=ax+b
    
        //第一步
        //由于Windows坐标跟数学坐标系的不同 先把 Windows坐标 x y变成负数(假设他是数学坐标里的第三象限)
        Point t1=new Point(0-p1.X,0-p1.Y);
        Point t2=new Point(0-p2.X,0-p2.Y);
    
        //第二步
        //仿照直线方程搞个山寨的 连立二元一次方程组 并求解
        double x1,x2,y1,y2;
        x1=t1.X;
        x2=t2.X;
        y1=t1.Y;
        y2=t2.Y;            
        double a,b;
        //因为连立方程
        //y1=ax1+b
        //y2=ax2+b
        //把b=y1-ax1代入2式
        //y2=ax2+(y1-ax1)
        //y2-y1=ax2-ax1
        //y2-y1=a(x2-x1)
        //所以
        //a=(y2-y1)/(x2-x1)
        a = (y2 - y1) / (x2 - x1);
        //然后
        b = y1 - a * x1;
    
        //第三步
        //把x代入 然后通过循环画出直线
        for (double i = x1; i >= x2; i-=1)
        {
            double tx, ty;
            ty = a * i + b;
            //注意 从平面直角坐标系到Windows坐标系的转换
            drawPoint(new Point((int)Math.Abs(i), (int)Math.Abs(ty)));
        }
    
    }      
    

    调用:

    //两点 x=20 y=20  ,x=50 y=50
    drawLine(new Point(20, 20), new Point(50, 50));
    

    调用结果

    当当当当:

    程序还有许多bug跟不足之处 多多见谅 别丢啥子西红柿 臭鸡蛋之类的过来哈  ̄□ ̄||

    由于技术含量太低博客园的大湿们向来对俺都是很不屑的哈 这次总算稍微有点技术含量了吧(¯▽¯;)。

    源码下载

  • 相关阅读:
    Oracle使用序列创建自增字段(主键自动增长)
    Oracle 增加修改删除字段
    JavaScript trim函数大赏
    js跨域问题
    document.getElementsByClassName的理想实现
    IIS启用Gzip的方法与优缺点分析
    浅释跳转漏洞
    js跨域及解决方法
    C#编写COM组件
    50种方法巧妙优化你的SQL Server数据库
  • 原文地址:https://www.cnblogs.com/assassinx/p/assassinxBlog.html
Copyright © 2020-2023  润新知