来玩玩画直线
哦啦啦,俺又来啦,几个月不见是不是很想俺呐,挖哈哈 (¯▽¯;)。
俺这个文章纯属抛砖引玉 ,希望各位高手不要丢板砖啦。
俺们写程序也就是一个乐趣 比不了你们这些博客园的牛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跟不足之处 多多见谅 别丢啥子西红柿 臭鸡蛋之类的过来哈  ̄□ ̄||
由于技术含量太低博客园的大湿们向来对俺都是很不屑的哈 这次总算稍微有点技术含量了吧(¯▽¯;)。