Angle between 3 points in 3d space

后端 未结 4 1232
挽巷
挽巷 2020-12-15 07:17

I have 3 points containing X, Y, Z coordinates:

var A = {x: 100, y: 100, z: 80},
    B = {x: 100, y: 175, z: 80},
    C = {x: 100, y: 100, z: 120};


        
相关标签:
4条回答
  • 2020-12-15 07:51
    double GetAngleABC( double* a, double* b, double* c )
    {
        double ab[3] = { b[0] - a[0], b[1] - a[1], b[2] - a[2] };
        double bc[3] = { c[0] - b[0], c[1] - b[1], c[2] - b[2]  };
    
        double abVec = sqrt(ab[0] * ab[0] + ab[1] * ab[1] + ab[2] * ab[2]);
        double bcVec = sqrt(bc[0] * bc[0] + bc[1] * bc[1] + bc[2] * bc[2]);
    
        double abNorm[3] = {ab[0] / abVec, ab[1] / abVec, ab[2] / abVec};
        double bcNorm[3] = {bc[0] / bcVec, bc[1] / bcVec, bc[2] / bcVec};
    
        double res = abNorm[0] * bcNorm[0] + abNorm[1] * bcNorm[1] + abNorm[2] * bcNorm[2];
    
        return acos(res)*180.0/ 3.141592653589793;
    }
    
    
    double a[] = {1, 0, 0};
    
    double b[] = {0, 0, 0};
    
    double c[] = {0, 1, 0};
    
    std::cout<< "The angle of ABC is " << GetAngleABC(a,b,c)<< "º " << std::endl;
    
    0 讨论(0)
  • 2020-12-15 07:57

    In pseudo-code, the vector BA (call it v1) is:

    v1 = {A.x - B.x, A.y - B.y, A.z - B.z}
    

    Similarly the vector BC (call it v2) is:

    v2 = {C.x - B.x, C.y - B.y, C.z - B.z}
    

    The dot product of v1 and v2 is a function of the cosine of the angle between them (it's scaled by the product of their magnitudes). So first normalize v1 and v2:

    v1mag = sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z)
    v1norm = {v1.x / v1mag, v1.y / v1mag, v1.z / v1mag}
    
    v2mag = sqrt(v2.x * v2.x + v2.y * v2.y + v2.z * v2.z)
    v2norm = {v2.x / v2mag, v2.y / v2mag, v2.z / v2mag}
    

    Then calculate the dot product:

    res = v1norm.x * v2norm.x + v1norm.y * v2norm.y + v1norm.z * v2norm.z
    

    And finally, recover the angle:

    angle = acos(res)
    
    0 讨论(0)
  • 2020-12-15 07:57

    @Roger algorithm in swift

    func SCNVector3Angle(start: SCNVector3, mid: SCNVector3, end: SCNVector3) -> Double {
        let v1 = (start - mid)
        let v2 = (end - mid)
        let v1norm = v1.normalized()
        let v2norm = v2.normalized()
    
        let res = v1norm.x * v2norm.x + v1norm.y * v2norm.y + v1norm.z * v2norm.z
        let angle: Double = Double(GLKMathRadiansToDegrees(acos(res)))
        return angle
    }
    
    /**
    * Subtracts two SCNVector3 vectors and returns the result as a new SCNVector3.
    */
    func - (left: SCNVector3, right: SCNVector3) -> SCNVector3 {
        return SCNVector3Make(left.x - right.x, left.y - right.y, left.z - right.z)
    }
    
    extension SCNVector3
    {
        /**
        * Returns the length (magnitude) of the vector described by the SCNVector3
        */
        func length() -> Float {
            return sqrtf(x*x + y*y + z*z)
        }
    
        /**
        * Normalizes the vector described by the SCNVector3 to length 1.0 and returns
        * the result as a new SCNVector3.
        */
        func normalized() -> SCNVector3 {
            return self / length()
        }
    }
    
    0 讨论(0)
  • 2020-12-15 08:03

    The same in python (with output in degrees):

    import numpy as np
    import math 
    import time
    
    def angle_2p_3d(a, b, c):       
    
        v1 = np.array([ a[0] - b[0], a[1] - b[1], a[2] - b[2] ])
        v2 = np.array([ c[0] - b[0], c[1] - b[1], c[2] - b[2] ])
    
        v1mag = np.sqrt([ v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] ])
        v1norm = np.array([ v1[0] / v1mag, v1[1] / v1mag, v1[2] / v1mag ])
    
        v2mag = np.sqrt(v2[0] * v2[0] + v2[1] * v2[1] + v2[2] * v2[2])
        v2norm = np.array([ v2[0] / v2mag, v2[1] / v2mag, v2[2] / v2mag ])
        res = v1norm[0] * v2norm[0] + v1norm[1] * v2norm[1] + v1norm[2] * v2norm[2]
        angle_rad = np.arccos(res)
    
        return math.degrees(angle_rad)
    
    
    p1 = np.array([1,0,0])
    p2 = np.array([0,0,0])
    p3 = np.array([0,0,1])
    
    start = time.time()
    angle= angle_2p_3d(p1, p2, p3)
    end = time.time()
    
    print("angle: ", angle)
    print("elapsed in: ", end - start)
    

    Output:

    angle: 90.0

    elapsed in: 8.392333984375e-05

    0 讨论(0)
提交回复
热议问题