Angle between 2 Lines in 3D
the dot product takes the norm (magnitude) of the vectors into account. Make sure you deal with unit vectors, or divide by the product of their norms.
import SceneKit
import simd
var vector1 = float3((pointArray[i].x - pointArray[i+1].x), (pointArray[i].y - pointArray[i+1].y), (pointArray[i].z - pointArray[i+1].z))
var vector2 = float3((pointArray[i+2].x - pointArray[i+1].x), (pointArray[i+2].y - pointArray[i+1].y), (pointArray[i+2].z - pointArray[i+1].z))
var dotProduct = dot(normalize(vector1), normalize(vector2))
var theta = acos(dotProduct)
or
var vector1 = float3((pointArray[i].x - pointArray[i+1].x), (pointArray[i].y - pointArray[i+1].y), (pointArray[i].z - pointArray[i+1].z))
var vector2 = float3((pointArray[i+2].x - pointArray[i+1].x), (pointArray[i+2].y - pointArray[i+1].y), (pointArray[i+2].z - pointArray[i+1].z))
var dotProduct = dot(vector1, vector2)
var theta = acos(dotProduct / (length(vector1) * length(vector2)))
How can I calculate the 3D angle between two points?
You can have angle between two directions v1,v2
(vectors) like this:
ang = acos(dot(v1,v2)/(|v1|.|v2|))
which translates in 3D to:
ang = acos( (x1*x2 + y1*y2 + z1*z2) / sqrt( (x1*x1 + y1*y1 + z1*z1)*(x2*x2+y2*y2+z2*z2) ) )
However you can not have angle between two points that simply has no meaning. Also beware 3D angle is not what you think it is (its angle in steradians and you can look at it as a volume coverage ... normal angle is area coverage) and yes its also scalar value. So what you are looking for are direction cosines or Euler angles (for which you need more info and order of transforms not to be ambitious) or transform matrices.
But as I suspected its an XY problem and based on your comments I was right.
So your real problem (based on comments) is to find the reflected ray from (triangle) face. Using angles (direction cosines nor euler angles nor transform matrices) is a really bad idea as that would be extremly slow. Instead use simple vector math I see it like this:
So you got ray direction dir
and want the reflected one dir'
from face with normal nor
so:
dir' = 2 * ( nor*dot(-dir,nor) + dir ) - dir
dir' = 2 * ( -nor*dot(dir,nor) + dir ) - dir
dir' = -2*nor*dot(dir,nor) + 2*dir - dir
dir' = -2*nor*dot(dir,nor) + dir
dir' = dir-2*nor*dot(dir,nor)
so in 3D it is:
dir=(dx,dy,dz)
nor=(nx,ny,nz)
t = 2*(dx*nx + dy*ny + dz*nz) // 2*dot(dir,nor)
dx' = dx-t*nx
dy' = dy-t*ny
dz' = dz-t*nz
as you can see no goniometrics or angles are needed whatsoever... Also does not matter if normal points in or out of face/object the dot
handles the signs on its own...
In case you need the normal can be computed by cross product of its 2 sides so if the triangle is defined by v0,v1,v2
points then:
nor = cross( v1-v0 , v2-v1 )
Here an example where I use this technique for a raytracer:
- Reflection and refraction impossible without recursive ray tracing?
its mine GLSL ray tracer supporting reflections on triangle faces and it has no goniometrics in it ... look for // reflect
comment in the fragment shader especially look for:
ray[rays].dir=ray[rays].dir-(2.0*t*ray[rays].nor);
its the reflection where
t=dot(ray[i0].dir,ray[i0].nor);
where dir
is ray direction and nor
is face normal (look familiar? yes its the same equation)...
Calculating angle between a line and a point in 3D
let say you have A(x1,y1,z1) B(x2,y2,z2) C(x3,y3,z3) and the common point is B. So the equation of the line AB becomes : (x1-x2)i + (y1-y2)j + (z1-z2)k
and that for BC it is : (x2-x3)i + (y2-y3)j + (z2-z3)k
Cos theta
= (AB.BC)/(|AB|*|BC|)
Here is the code
#include<iostream>
#include<math.h>
#define PI 3.14159265
using namespace std;
int main()
{
int x1,x2,x3,y1,y2,y3,z1,z2,z3;
cout<<"for the first\n";
cin>>x1>>y1>>z1;
cout<<"\nfor the second\n";
cin>>x2>>y2>>z2;
cout<<"\nfor the third\n";
cin>>x3>>y3>>z3;
float dot_product = (x1-x2)*(x2-x3) + (y1-y2)*(y2-y3)+ (z1-z2)*(z2-z3);
float mod_denom1 = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2));
float mod_denom2 = sqrt((x2-x3)*(x2-x3) + (y2-y3)*(y2-y3) + (z2-z3)*(z2-z3));
float cosnum = (dot_product/((mod_denom1)*(mod_denom2)));
float cos = acos(cosnum)*180/PI;
cout<< cos;
}
Calculate angle between two vectors in 3d
mat3 rotateAlign( vec3 v1, vec3 v2)
{
vec3 axis = cross( v1, v2 );
const float cosA = dot( v1, v2 );
const float k = 1.0f / (1.0f + cosA);
mat3 result( (axis.x * axis.x * k) + cosA,
(axis.y * axis.x * k) - axis.z,
(axis.z * axis.x * k) + axis.y,
(axis.x * axis.y * k) + axis.z,
(axis.y * axis.y * k) + cosA,
(axis.z * axis.y * k) - axis.x,
(axis.x * axis.z * k) - axis.y,
(axis.y * axis.z * k) + axis.x,
(axis.z * axis.z * k) + cosA
);
return result;
}
This solved it! Source
How do you calculate the reflex angle given two vectors in 3D space?
I came up with the following solution that takes advantage of the direction change of the cross product of the two vectors:
Make a vector
n = a X b
and normalize it. This vector is normal to the plane spanned by a and b.Whenever a new angle is calculated compare it with the old normal. In the comparison, treat the old and the current normals as points and compute the distance between them. If this distance is 2 the normal (i.e. the cross product a X b has flipped).
You might want to have a threshold for the distance as the distance after a flip might be shorter than 2, depending on how the vectors a and b are oriented and how often you update the angle.
Related Topics
How to Use The Spritekit Method Body(At: Cgpoint)
How to Cut a Hole in a Sprite Image or Texture to Show What Is Behind It Using Spritekit in Swift
Is There Any Shorthand Way to Write Cgpoint, Cgrect, etc
Allocating Ekeventstore Throws Warnings
Bleed Through from Nsbutton Checkbox on Non-Transparent Nspopover
Didbegincontact Not Being Called Swift
Why Run Loop Is Needed When Using Dispatchqueue.Main.Async in MAC Command Line Tool in Swift
Get Out of Navigation Controller and Go Back to Tab Bar View
When to Detach Firebase Listeners in Tableview Cell
Core Image and Memory Leak, Swift 3.0
How to Calculate a Distance Between Two Anchorentities
How to Have a Searchbar Which Shows Suggestions with Different UItableview
How to Resolve Rctpromiseresolveblock After Bftask
How to Add Skspritenode in a Loop
Characteristic.Value from Bluetooth Reading in Swift