哦啦啦,俺又來啦,幾個月不見是不是很想俺呐,挖哈哈 (¯▽¯;)。
俺這個文章純屬拋磚引玉 ,希望各位高手不要丟板磚啦。
俺們寫程式也就是一個樂趣 比不了你們這些部落格園的牛x人啦
這次俺們來秀下直線方程 小意思 見笑啦,俺們用得最多的就是.net了哈 所以依舊在.net平台上做測試
好正題:
先把一次函數搬出來哈
直線的方程:y=ax+b
地球人都知道哈啊,如果是初中都沒上的同學請略過。。。
還有兩邊都是1的直角等邊三角形他的斜邊是多少?當然是根號2啦 哈哈哈
平常老在VC裡lineTo()過去 lineTo()過來,童鞋們難道就沒想過他是怎麼來的麼。
如果知道了兩個座標(x1,y1 )(x2,y2) ,也就是你的滑鼠在你的form1上在不同地方點兩下 於是就有了兩個point對象 明白了噻
關於直線方程 它有很多“式”哈, 比如像點斜式啊 海底撈月式啊 老樹盤根式啊 兩點式啊 三點式啊 啥的,
俺們這裡由於事Crowdsourced Security Testing道了兩個點(座標),所以當然是用兩點式啦:
(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=50drawLine(new Point(20, 20), new Point(50, 50));
調用結果
噹噹噹噹:
程式還有許多bug跟不足之處 多多見諒 別丟啥子西紅柿 臭雞蛋之類的過來哈  ̄□ ̄||
由於技術含量太低部落格園的大濕們向來對俺都是很不屑的哈 這次總算稍微有點技術含量了吧(¯▽¯;)。
源碼下載