高中知识复习:已知三点画圆

参考:

表达式:直线方程的各种表达式

向量:直线的方向向量与法向向量的求法

中垂线的计算方法: 线段中垂线解析式公式 

两直线求交点的方法:一种计算两直线交点的方法(灵歌1992的博客)

这两篇写的很足够了,我用Js来写写代码,顺便可以添加这个新功能到上一篇 从图片测长度 的博客里面;

很多相当有趣的功能,仅仅只会用到高中的知识,所以复习是挺必要的一件事,而且自从毕业以后,要让我手工计算点什么东西,心底里总有些害怕,不知道该从何处入手,复习应该可以拾回年轻时的自信吧,就算只是写写推导过程,应该也是有益的,所以想到什么就复习什么吧,而且再学一遍,很可能会有新的体会。

直线方程

这里面见得最多、最熟悉的直线方程表达式是所谓的:  斜截式:y=kx+b

如果有两个点p1(x1,y1),p2(x2,y2),就可以直接得到斜率,然后将斜率和p1坐标,带入直线方程求出截距:

 k=\frac{y2-y1}{x2-x1},b=\frac{y1x2-y2x1}{x2-x1} 

可以看出,这两个参数还是比较复杂的,但是可以看到,它们的分母是一样的,所以代入斜截式的方程式,

消掉分母:\left ( x2-x1 \right )y= \left ( y2-y1 \right )x+\left ( y1x2-y2x1 \right )

移       项:\left ( y2-y1 \right )x+\left ( x1-x2 \right )y+\left ( y1x2-y2x1 \right )=0

定       义:\bg_green A=y2-y1 ; B=x1-x2 ; C=y1x2-y2x1

然后就可以得到直线方程的一般式了:Ax+By+C=0

求得的 ABC 一般会有一个公约数,但是在此不考虑实际的约分情况,毕竟不是要考试,有个公约数,直线也还是那个直线。

可以看出这个一般式长得很像线性代数里的东西,而且根据参考的文章,这个的确比较好用。

求中垂线的方程

当前直线的法向量为  \overrightarrow{n}=(A,B)  由此可求出垂直线的一般方程:Bx-Ay+C_{\perp} =0 

已知 A,B 以及将其所经过的点   p0(\frac{x1+x2}{2},\frac{y1+y2}{2})\rightarrow \left ( x0,y0 \right )   代入,求取 C_{\perp} 

得: C_{\perp}=A\times y0-B\times x0=\frac{A \times \left ( y1+y2 \right)-B\times \left ( x1+x2 \right)}{2}

  

求中垂线的交点

设交点为 O(x,y) 按照以上方法求出两条线的中垂线一般方程   B1x-A1y+C1_{\perp} =0   和   B2x-A2y+C2_{\perp} =0

联立这两个方程即可,得到   Ox=\frac{C1_{\perp} A2-C2_{\perp} A1}{A1B2-A2 B1}    Oy=\frac{C1_{\perp} B2-C2_{\perp} B1}{A1B2-A2 B1}

提出公共的分母   D = A1B2-A2 B1  单独计算出一个值,即可形成程序。

当 D=0 时需要特殊对待,此时两条直线平行,没有相交线,也就不用求圆心了。

可知,中垂线的交点即为三点圆的圆心。

先把程序效果放出来

我是以轮距为参考,绘制了一个三点圆,可见计算出来的数据是比较符合的。

程序代码:

function circleCenter(ctx){
    var Coef1 = nline(thePoint[0],thePoint[1])
    var Coef2 = nline(thePoint[1],thePoint[2])
    var D = Coef1[0]*Coef2[1] - Coef1[1]*Coef2[0] 
    if(D != 0){
        var ox = (Coef1[2]*Coef2[0] - Coef2[2]*Coef1[0])/D;
        var oy = (Coef1[2]*Coef2[1] - Coef2[2]*Coef1[1])/D;
        thePoint[3] = {
            X: ox,
            Y: oy,
            R:((thePoint[0].X-ox)**2+(thePoint[0].Y-oy)**2)**(1/2)
        };
        ctx.beginPath();
        ctx.arc(thePoint[3].X, thePoint[3].Y, thePoint[3].R, 0, Math.PI*2);
        ctx.moveTo(thePoint[3].X, thePoint[3].Y);
        ctx.lineTo(thePoint[2].X, thePoint[2].Y) 
        ctx.fillText("半径:"+thePoint[3].R*scale+"mm",10,50,200); 
        ctx.stroke();//绘制 
    }
}

function nline(p1,p2){
    var A = p2.Y-p1.Y;
    var B = p1.X-p2.X;
    var Cv = (A*(p1.Y +p2.Y)-B*(p1.X +p2.X))/2; //垂直平分线的
    return [A,B,Cv];
}

把这个加进去,再稍微修改一下之前的代码

将,oc.onmousedown 函数里的完成标志添加限制,等于是修改了模式。当然,在这之前要先加一个画圆模式的变量

if(!CircleMode){CalCompleted = true;}

然后,添加测量距离里的第三个点的处理, 

else if(CircleMode && circleNum == 3){
    circleCenter(ctx);
    CalCompleted = true;
}

 然后就可以开心的测量半径了。

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值