三维空间内两相交直线内切圆

 voidMoveDataCircle::initWithStraight(MoveDataBase* straight1,MoveDataBase* straight2)

{

    

    C3DVector3 v1 = ((MoveDataStraight*)straight1)->m_startPosition;

    C3DVector3  v2 = ((MoveDataStraight*)straight1)->m_endPosition;

    C3DVector3  v3 = ((MoveDataStraight*)straight2)->m_startPosition;

    C3DVector3  v4 = ((MoveDataStraight*)straight2)->m_endPosition;


    float distance = 24;//假设平滑过渡得距离

    

    Vec3 dirL1 =  Vec3((v2.x-v1.x),(v2.y-v1.y),(v2.z-v1.z));

    dirL1.normalize();

    //切点坐标1

    Vec3  P1 = Vec3(v2.x,v2.y,v2.z) + distance*dirL1*(-1);

    

    

    Vec3 dirL2 =  Vec3((v4.x-v3.x),(v4.y-v3.y),(v4.z-v3.z));

    dirL2.normalize();

    //切点坐标2

    Vec3  P2 = Vec3(v3.x,v3.y,v3.z) + distance*dirL2;

    

    //把切点付给圆弧起始点

    v2 = C3DVector3(P1.x,P1.y,P1.z);

    ((MoveDataStraight*)straight1)->m_endPosition = v2;

    v3 = C3DVector3(P2.x,P2.y,P2.z);

    ((MoveDataStraight*)straight2)->m_startPosition = v3;

    ((MoveDataStraight*)straight2)->m_initPos = ((MoveDataStraight*)straight2)->m_startPosition;

    //计算圆心等参数

    initWithPoint4(v1,v2,v3,v4);

}

voidMoveDataCircle::initWithPoint4(C3DVector3 v1,C3DVector3  v2,C3DVector3  v3,C3DVector3  v4)

{

    

    //直线方程 L1;直线1  v1,v2

    //向量

    Vec3 dirL1 =  Vec3((v2.x-v1.x),(v2.y-v1.y),(v2.z-v1.z));

    dirL1.normalize();

    //垂直与此直线的平面方程

    //    x2*dirL1.x+y2*dirL1.y+z2*dirL1.z+d=0;

    float A1,B1,C1,D1;

    D1 = (v2.x*dirL1.x+v2.y*dirL1.y+v2.z*dirL1.z);

    A1 = dirL1.x;

    B1 = dirL1.y;

    C1= dirL1.z;

    //      x*dirL1.x+y*dirL1.y+z*dirL1.z+d=0;

    

    //直线方程 L2;直线2 v3,v4

    //向量

    Vec3 dirL2 =  Vec3((v4.x-v3.x),(v4.y-v3.y),(v4.z-v3.z));

    dirL2.normalize();

    //垂直与此直线的平面方程

     float A2,B2,C2,D2;

//    x3*dirL2.x+y3*dirL2.y+z3*dirL2.z+d=0;

     D2 = (v3.x*dirL2.x+v3.y*dirL2.y+v3.z*dirL2.z);

     A2 = dirL2.x;

     B2 = dirL2.y;

     C2 = dirL2.z;

//    x*dirL2.x+y*dirL2.y+z*dirL2.z+d=0;


    float A3,B3,C3,D3;

    //平面方向

    Vec3 dirL3;

    Vec3 dir1 = dirL1 - dirL2;

    Vec3 dir2 = dirL1 + dirL2;

    dirL3 = Vec3(dir1.y*dir2.z-dir1.z*dir2.y,dir2.x*dir1.z-dir1.x*dir2.z,dir1.x*dir2.y-dir1.y*dir2.x);

    

//    向量AB×向量CD=(y1z2-z1y2,x2z1-x1z2,x1y2-y1x2)

    

    

    dirL3.normalize();

    A3 = dirL3.x;

    B3 = dirL3.y;

    C3 = dirL3.z;

    //平面方程  (点法式)

    D3 = (A3*v1.x+B3*v1.y+C3*v1.z);

    Vec3 direction = Vec3(A3,B3,C3);

    

    

    //联立平面方程

    

    //解方程得圆心  行列式算法

   

//    Vec3 center = getXYZ(Vec3(A1,B1,C1),Vec3(A2,B2,C2),Vec3(A3,B3,C3),Vec3 (D1,D2,D3));

    

    

    Vec3 center ;

    float m=fx(A1,B1,C1,A2,B2,C2,A3,B3,C3);

    if(m==0)

    {

        center = Vec3(0, 0, 0);

    }else

    {

        center.x=fx(D1,B1,C1,D2,B2,C2,D3,B3,C3)/(float)m;

        center.y=fx(A1,D1,C1,A2,D2,C2,A3,D3,C3)/(float)m;

        center.z=fx(A1,B1,D1,A2,B2,D2,A3,B3,D3)/(float)m;

    }

    


    //半径

    float radius = center.distance(Vec3(v2.x,v2.y,v2.z));

    

    // 两直线夹角

    float cosθ=judge((A1*A2+B1*B2+C1*C2),(sqrt(A1*A1+B1*B1+C1*C1)*sqrt(A2*A2+B2*B2+C2*C2)));

    float θ= CC_RADIANS_TO_DEGREES (acos(cosθ));

    //圆的弧度


    

    //计算初始角度

    if (direction.x==0&&direction.y==0) {

        direction.x = 0.001; //杜绝x、y同时为0 在路径时设定0.01的误差

    }

    float a3 = radius*sqrt(direction.x*direction.x + direction.y*direction.y)/sqrt(direction.x*direction.x + direction.y*direction.y+direction.z*direction.z);

    //a3*sin = center.z - v2.z;

    float sin= (center.z - v2.z)/a3;

    if (sin>1) {

        sin = 1.0;

    }

    if (sin<-1) {

        sin = -1.0;

    }

    float cos= sqrt(1-sin*sin);


    float beginAngle = atan2(sin,cos);

    

    Vec3 begin =  getaAnglePoint(center,direction,beginAngle,radius);

    C3DVector3 begin_ = C3DVector3(begin.x,begin.y,begin.z);

    if (begin_.distance(v2)>2.0) {

        beginAngle = atan2(sin,-cos);

        begin =  getaAnglePoint(center,direction,beginAngle,radius);

        begin_ = C3DVector3(begin.x,begin.y,begin.z);

        if (begin_.distance(v2)>2.0) {

        

            CCLOG("fuck! begin\n");

        }

    }

    

     //判断顺时针逆时针

    bool clockWise = false;  //假设是顺时针

    float factor = 1.0f;

    float usingAngle = θ * M_PI*2 /360.0f;

    float angle = (beginAngle+factor*usingAngle);


 

    //得到终点坐标

    C3DVector3 end;

    

    Vec3 end_= getaAnglePoint(center,direction,angle,radius);

    end = C3DVector3(end_.x,end_.y,end_.z);

    if (end.distance(v3)>2.0) {

        clockWise = true; //假设不成立

    }

  direction.z *= -1;

    

    

    //赋值

    m_centerPosition = C3DVector3(center.x,center.y,center.z);

    m_nDirection = C3DVector3(direction.x,direction.y,direction.z);

    m_radius = radius;

    m_time = 1.0;

    m_moveStyle = 0;

    m_totalAngle = θ;

    m_beginAngle = beginAngle;

    m_clockWise = clockWise;

    m_bLoop = false;

    m_initPos = v2;

}

Vec3  MoveDataCircle::getaAnglePoint(Vec3 center ,Vec3 direction, float angle,float radius)

{

    float cosAngle = cosf (angle);

    float sinAngle = sinf (angle);

    Vec3 begin;

    

    begin.x = center.x + radius*direction.y/sqrt(direction.x*direction.x + direction.y*direction.y)*cosAngle+radius*direction.x*direction.z/(sqrt(direction.x*direction.x+direction.y*direction.y)*sqrt(direction.x*direction.x+direction.y*direction.y+direction.z*direction.z))*sinAngle;

    begin.y = center.y - radius*direction.x/sqrt(direction.x*direction.x + direction.y*direction.y)*cosAngle+radius*direction.y*direction.z/(sqrt(direction.x*direction.x+direction.y*direction.y)*sqrt(direction.x*direction.x+direction.y*direction.y+direction.z*direction.z))*sinAngle;

    begin.z = center.z - radius*sqrt(direction.x*direction.x + direction.y*direction.y)/sqrt(direction.x*direction.x + direction.y*direction.y+direction.z*direction.z)*sinAngle;

    return begin;

}

floatMoveDataCircle::fx(float a,float b,float c,

       float d,float e,float f,

       float g,float h,float i)

{float result;

    result=a*e*i+b*f*g+c*d*h-a*f*h-b*d*i-c*e*g;

    return result;

}

floatMoveDataCircle::judge(float numerator ,float denominator)

{

    if (denominator==0) {

        return0;

    }

    return numerator/denominator;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值