现在的位置: 首页 > 综合 > 正文

来玩玩画直线

2012年09月28日 ⁄ 综合 ⁄ 共 2437字 ⁄ 字号 评论关闭

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

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

俺们写程序也就是一个乐趣 比不了你们这些博客园的牛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跟不足之处 多多见谅 别丢啥子西红柿 臭鸡蛋之类的过来哈  ̄□ ̄||

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

源码下载

抱歉!评论已关闭.