拿支笔在纸上画啊画的....怎么判断线条闭合,除了用眼睛以外我没想过其他办法,可是程序没有眼睛,怎么办?!
话说回来,就算眼睛看到闭合了,你为什么说它就是闭合了???
上面的问题,我没做这个例子之前从来没想过...做了以后才发现,很多显而易见的东西,道理其实不是什么人都懂的,我终于搞懂了,偶们的陈景润干吗要去证明1+1了 >o<
ok....数学啊数学...偶的痛(偶好像浑身是痛..寒)
废话不再说了
首先要知道点斜式,不知道的往下看,偶现在把你当之前的我在教(我复习了好久啊..苦闷555)
y = k*x + b;
k = (y2-y1) / (x2-x1); 分母不为0
以上k为斜率...算法为任取一条直线上两个不同点,得到坐标(x1,y1)(x2,y2)...
b为截距, 也就是直线在y轴的交点坐标...别说没交点,直线能无限衍生哦(要我复习直线的概念?晕)
ok...公式知道了,偶们就可以干点事情了...比如我们有两条直线,任意在上面各抓两不同点,设为
(px1,py1),(px2,py2) -- 线段p
(qx1,qy1),(qx2,qy2) -- 线段q
我们可以得到
pk = (py2-py1)/(px2-px1);
pb = py1 - px1*pk;(这里用py2,px2代入也是一样的)
同理 qk,qb
然后捏...假设p和q相交...交点为i,坐标为(xi,yi);
那么i也在p上,i也在q上...这句似乎是废话~~~
列出二元一次方程(大哥表走...方程不用你解的啦-_-!)
yi = xi*pk + pb;
yi = xi*qk + qb;
.........!%$@##$#@##@@%!$^@%!.......头大的计算中...
xi = (qb - pb)/(pk - qk);
yi = xi*pk + pb;(这里用qk,qb也是一样的)
乌拉拉乌拉拉...交点坐标算出拉......偶们的任务完成1/2了....
废话不多,继续啊~~^<>^
我们已经判断线条的闭合,但是要填充它,又一个问题...
因为之前判断都是直线的...也就是说直线只要不平行,总有交点,而我们画线时,随机拿出来的两条是线段,很有可能交点是在线段的衍生线上的....
接下去我们要做的是判断这个交点是否在线段内...否则交了也白交,你也看不到
还是(xi,yi)...这里要用到一个叫什么等比比例公式的,不好意思忘掉了,不过可以肯定是初中学的,上面的点斜式是高中学的....什么你小学就学了?!大哥这里不是你来的...去,去国家科学院去 >口<
那个比例公式大致就是给你一条直线,任取3点(为了方便就取x轴了,y坐标就免了) x1,x2,x3公式 n = (x2-x1) / (x3-x1)
如果 0<=n<=1 x2在线段x3x1内,否则不是出头就是出尾
好了好了...这样子...结合上面的,我们就可以作出判断了....(我知道你忘了-w-,自己回上去看)
t = (xi - px1)/(px2 - px1)
s = (xi - qx1)/(qx2 - qx2)
0<=t<=1并且0<=s<=1
那么交点在线段内,你能看到这个交点所在(x的比了,y就不用比了,什么为什么,没有为什么>o<)
终于完事了....下面贴个as代码,大家看一下吧...做了简单注释....至于线条填充部分的判断.....其实就是把鼠标各点保存数组,然后逐个判断....以后有空再讲吧...累了..睡了..zzzZZZZZ
function lineToLine(px1, py1, px2, py2, qx1, qy1, qx2, qy2)
{
// 线条垂直或者水平的话,防止计算斜率是出现'0',越界所以+上一个很小的数,以确保不同
// 1E-6等于10的-6次方,即0.000001
if(px1 == px2) px2 += 1E-6;
if(py1 == py2) py2 += 1E-6;
// 计算斜率
var pk = (py2 - py1) / (px2 - px1);
// 计算截距
var pb = py1 - pk * px1;
// 第二条线段
if(qx1 == qx2) qx2 += 1E-6;
if(qy1 == qy2) qy2 += 1E-6;
var qk = (qy2 - qy1) / (qx2 - qx1);
var qb = qy1 - qk * qx1;
// 确保斜率不相等,相等的话为平行或重叠
if(pk != qk)
{
// 计算交点坐标
var xi = (qb - pb) / (pk - qk);
var yi = qk * xi + qb;
// 交点所在线段比例
var t = (xi - px1) / (px2 - px1);
var s = (xi - qx1) / (qx2 - qx1);
// 交点是否在线段内
if((t >= 0) && (t <= 1) && (s >= 0) && (s <= 1))
{
// 保存交点坐标
closx = xi;
closy = yi;
return true;
}
else return false;
}
else return false;
}