已知平面上两点坐标及半径,求过两点圆弧的圆心坐标

时间:2022-03-14 09:45:25

功能:已知平面圆弧上两点坐标及圆半径,计算圆心坐标. 

编程语言:JavaScript  

分析: 

      给定圆弧半径,经过平面上两点的圆弧圆心落在两点的中垂线上,  一般有两个.

算法: 

1)  计算两点之间的中点坐标.
2)计算连接两点的方向向量.
3)将两点方向向量顺时针旋转90度,得到中垂线方向向量.
4)单位化中垂线方向向量.
5)计算中点与圆心的偏移距离.
6)将中点沿中垂线方向移动偏移距离,既得到第一个圆心坐标.
7)将中垂线方向旋转180度(也就是将两点方向向量逆时针旋转90度),重复步骤6,得到第二个圆心坐标.

 

//
//  由平面圆弧上两点坐标及圆半径,计算圆心坐标的JavaScript脚本代码  
//  Author: Chunfeng Yang 
//  Date:   April 1st, 2018

//
// Data Structure
//
function Point( x, y)
{
    this.x = x;
    this.y = y;
    if( (typeof(x) == "undefined") || (typeof(y) == "undefined") ){ 
        this.x = 0;
        this.y = 0;
    }

    this.distance = function( otherPoint ) {
        var self = this;
        if (typeof(otherPoint) == "undefined") { 
            return ; // The return obejct is undefined.
        }
        if( (typeof(self.x) == "undefined") || (typeof(self.y) == "undefined") ){ 
            return;
        }
        if( (typeof(otherPoint.x) == "undefined") || (typeof(otherPoint.y) == "undefined") ){ 
            return;
        }
        var dx =  parseFloat(self.x) - parseFloat(otherPoint.x); 
        var dy =  parseFloat(self.y) - parseFloat(otherPoint.y);
        return ( Math.sqrt( parseFloat(dx) * parseFloat(dx) + parseFloat(dy) * parseFloat(dy) ) );
    }

    this.middle = function( otherPoint ) {
        var self = this;
        if (typeof(otherPoint) == "undefined") { 
            return ; // The return obejct is undefined.
        }
        if( (typeof(self.x) == "undefined") || (typeof(self.y) == "undefined") ){ 
            return;
        }
        if( (typeof(otherPoint.x) == "undefined") || (typeof(otherPoint.y) == "undefined") ){ 
            return;
        }
        var thex = ( parseFloat(self.x) + parseFloat(otherPoint.x) ) / 2.0; 
        var they = ( parseFloat(self.y) + parseFloat(otherPoint.y) ) / 2.0; 
        return ( new Point( thex, they ) );
    }

    this.vector = function( otherPoint ) {
        var self = this;
        if (typeof(otherPoint) == "undefined") { 
            return ; // The return obejct is undefined.
        }
        if( (typeof(self.x) == "undefined") || (typeof(self.y) == "undefined") ){ 
            return;
        }
        if( (typeof(otherPoint.x) == "undefined") || (typeof(otherPoint.y) == "undefined") ){ 
            return;
        }
        var dx =  parseFloat(otherPoint.x) - parseFloat(self.x); 
        var dy =  parseFloat(otherPoint.y) - parseFloat(self.y);
        return ( new Point( dx, dy ) );
    }

    this.moveto = function( theVector ) {
        var self = this;
        if (typeof(theVector) == "undefined") { 
            return ; // The return obejct is undefined.
        }
        if( (typeof(self.x) == "undefined") || (typeof(self.y) == "undefined") ){ 
            return;
        }
        if( (typeof(theVector.x) == "undefined") || (typeof(theVector.y) == "undefined") ){ 
            return;
        }
        var thex =  parseFloat(theVector.x) + parseFloat(self.x); 
        var they =  parseFloat(theVector.y) + parseFloat(self.y);
        return ( new Point( thex, they ) );
    }
}



function calCircleCenter( p1, p2, r )
{   
    // Checking parameters
    if (typeof(p1) == "undefined") { 
        console.error("Parameter point 1 is undefined");   
        return;
    }
    if (typeof(p2) == "undefined") {   
        console.error("Parameter point 2 is undefined");    
        return;
    }
    if (typeof(r) == "undefined") {    
        console.error("Parameter radius is undefined");   
        return;
    }

    if( parseFloat(r) < 0 ) {    
        console.error("Parameter radius is less than zero");   
        return;
    }
   
    var distance = p1.distance( p2 );
    var half_dis = parseFloat(distance)/2.0;
    if( parseFloat(r) < half_dis ) {    
        console.error("Parameter radius is too samll, please increass radius.");   
        return;
    }
    if( parseFloat(half_dis) < 0.0001 ) {    
        console.error("Distance between two point is too samll, please increase their distance.");   
        return;
    }

    var v = p1.vector( p2 );
    if (typeof(v) == "undefined") {    
        console.error("Vector p1p2 is undefined");   
        return;
    }   
    
    var middle_point = p1.middle( p2 );

    // Roating vector p1p2 90 degrees clockwise
    var new_v_x =  v.y;
    var new_v_y =  -v.x;

    // Unifing the new vector
    var origin = new Point( 0.0,  0.0); 
    var new_v = new Point( new_v_x,  new_v_y ); 
    var l = origin.distance( new_v ) 
    var uni_v_x = parseFloat(new_v_x) / parseFloat(l);
    var uni_v_y = parseFloat(new_v_y) / parseFloat(l);

  
    var move_length = Math.sqrt( parseFloat(r) * parseFloat(r) - parseFloat(half_dis) * parseFloat(half_dis) ) ;
    var move_vector = new Point( parseFloat(uni_v_x) * parseFloat(move_length),  parseFloat(uni_v_y) * parseFloat(move_length) ); 

    var r_1 =  middle_point.moveto( move_vector );

    // Roating vector p1p2 90 degrees anti-clockwise
    move_vector = new Point( - parseFloat(uni_v_x) * parseFloat(move_length),  -parseFloat(uni_v_y) * parseFloat(move_length) ); 
 
    var r_2 =  middle_point.moveto( move_vector );

    return( [r_1, r_2] );
}



// Testing function
function test()
{
    var p = new Point(-3,0); 

    var p1 = new Point(3,0);  

    var result = calCircleCenter( p, p1, 5 )

    console.log('result = ', result );
}

test();

  测试结果:

result =  [ Point {
    x: 0,
    y: -4,
    distance: [Function],
    middle: [Function],
    vector: [Function],
    moveto: [Function] },
  Point {
    x: 0,
    y: 4,
    distance: [Function],
    middle: [Function],
    vector: [Function],
    moveto: [Function] } ]