admin管理员组文章数量:1390241
Let's say I have two vertices and I want to know the 3D angle between the two. By 3D angle, I mean the angle between the one vertex and another on each of the three dimensional planes, stored as
{ x, y, z }
function getAngleBetweenVertices(vert1, vert2){
return {
x: 0, // ?
y: 0, // ?
z: 0 // ?
}
}
// Classes
class Vertex {
constructor(position){
this.position = {
x: 0,
y: 0,
z: 0,
...position
};
}
}
// Init
let vert1 = new Vertex({ x: 1, y: 0, z: 1 });
let vert2 = new Vertex({ x: 0, y: 1, z: 1 });
let angle = getAngleBetweenVertices(vert1, vert2);
console.log("angle ", angle);
Let's say I have two vertices and I want to know the 3D angle between the two. By 3D angle, I mean the angle between the one vertex and another on each of the three dimensional planes, stored as
{ x, y, z }
function getAngleBetweenVertices(vert1, vert2){
return {
x: 0, // ?
y: 0, // ?
z: 0 // ?
}
}
// Classes
class Vertex {
constructor(position){
this.position = {
x: 0,
y: 0,
z: 0,
...position
};
}
}
// Init
let vert1 = new Vertex({ x: 1, y: 0, z: 1 });
let vert2 = new Vertex({ x: 0, y: 1, z: 1 });
let angle = getAngleBetweenVertices(vert1, vert2);
console.log("angle ", angle);
For example in the above image, I've traced over a line segment joining two vertices on a triangle. It should be possible to find the angle between the two vertex positions on the x, y, and z axis.
How can I calculate the three dimensional angle between two vertices?
Share Improve this question edited Jun 11, 2019 at 6:35 J.Todd asked Jun 11, 2019 at 4:39 J.ToddJ.Todd 8271 gold badge16 silver badges55 bronze badges 10- In its current state, the question might be closed as unclear since (based on your ment), it seems to be unclear even to you. What are you trying to achieve? – Robby Cornelissen Commented Jun 11, 2019 at 4:47
- this was linked as a possible duplicate candidate, but I was unable to decipher the python there and discern the correct JS version of the solution. – J.Todd Commented Jun 11, 2019 at 6:04
- @RobbyCornelissen The angle from one vertex to another. – J.Todd Commented Jun 11, 2019 at 6:11
- When I first posted this question I was using the term "vector" instead of "3D angle", which was incorrect. I'm looking for the angle between two locations in 3D space on all three planes. – J.Todd Commented Jun 11, 2019 at 6:37
- 1 @Spektre The purpose of getting the angles is to then build a simplistic (non-perfect, but fast) function for figuring out where a ray should bounce when it collides with a tri. By knowing the angle from one vertex of the tri to the next, for all three edges, I believe I can calculate a pretty fast and somewhat accurate vector for where the ray should bounce. Ultimately Im working on figuring out my own version of reflective light in a raytracing system, for the sake of fun. – J.Todd Commented Jun 11, 2019 at 17:42
3 Answers
Reset to default 4You 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 ments I was right.
So your real problem (based on ments) 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 puted 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
ment 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)...
I'm not sure if this code is correct but I think its what I was looking for.
// Utilities
function normalizeAngle(angle){
if (angle > 360) return angle - 360;
if (angle < 0) return 360 + angle;
else return angle;
}
function getAngleBetweenPoints(cx, cy, ex, ey){
var dy = ey - cy;
var dx = ex - cx;
var theta = Math.atan2(dy, dx);
theta *= 180 / Math.PI;
return theta;
}
function getAngleBetweenVertices(vert1, vert2){
return {
x: normalizeAngle(getAngleBetweenPoints(vert1.position.z,
vert1.position.x, vert2.position.z, vert2.position.x)),
y: normalizeAngle(getAngleBetweenPoints(vert1.position.z,
vert1.position.y, vert2.position.z, vert2.position.y)),
z: normalizeAngle(getAngleBetweenPoints(vert1.position.x,
vert1.position.y, vert2.position.x, vert2.position.y))
}
}
// Classes
class Vertex {
constructor(position){
this.position = {
x: 0,
y: 0,
z: 0,
...position
};
}
}
// Init
let vert1 = new Vertex({ x: 1, y: 0, z: 1 });
let vert2 = new Vertex({ x: 0, y: 1, z: 1 });
let angle = getAngleBetweenVertices(vert1, vert2);
console.log("angle ", angle);
This is how I do it in Cinema 4d python to calculate an angle between 3d points...no thanks to the internet:
def GetAngle(self, a, b):
length = math.sqrt((a.x - b.x)**2 + (a.y - b.y)**2 + (a.z - b.z)**2)
rise = b.y - a.y
run = math.sqrt((length**2) - (rise**2))
angle = math.degrees(math.atan(rise/run))
return angle
本文标签: javascriptHow can I calculate the 3D angle between two pointsStack Overflow
版权声明:本文标题:javascript - How can I calculate the 3D angle between two points? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744736786a2622378.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论