X、Y、Z 座標を含む 3 つのポイントがあります。
var A = {x: 100, y: 100, z: 80},
B = {x: 100, y: 175, z: 80},
C = {x: 100, y: 100, z: 120};
座標は、3d CSS 変換からのピクセルです。ベクトル BA と BC の間の角度を取得するにはどうすればよいですか? 数式で十分です。JavaScript コードの方が優れています。ありがとうございました。
X、Y、Z 座標を含む 3 つのポイントがあります。
var A = {x: 100, y: 100, z: 80},
B = {x: 100, y: 175, z: 80},
C = {x: 100, y: 100, z: 120};
座標は、3d CSS 変換からのピクセルです。ベクトル BA と BC の間の角度を取得するにはどうすればよいですか? 数式で十分です。JavaScript コードの方が優れています。ありがとうございました。
疑似コードでは、ベクトル BA (v1 と呼びます) は次のとおりです。
v1 = {A.x - B.x, A.y - B.y, A.z - B.z}
同様に、ベクトル BC (v2 と呼びます) は次のとおりです。
v2 = {C.x - B.x, C.y - B.y, C.z - B.z}
v1
との内積v2
は、それらの間の角度のコサインの関数です (大きさの積によってスケーリングされます)。したがって、最初に正規化v1
し、次のようにし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}
次に内積を計算します。
res = v1norm.x * v2norm.x + v1norm.y * v2norm.y + v1norm.z * v2norm.z
最後に、角度を復元します。
angle = acos(res)
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;
迅速な@Rogerアルゴリズム
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()
}
}