提问人:rbw 提问时间:11/13/2023 最后编辑:rbw 更新时间:11/13/2023 访问量:48
如何计算三角射线交点的坐标?
How do I calculate the coordinates of a triangle-ray intersection?
问:
所以我正在编写自己的游戏引擎,我最近写了一个三角射线跨扇区(我写的意思是从本教程中批发复制而来的)。截至目前,只有当光线和三角形相交时,它才会贯穿整个函数,虽然这很有帮助,但我想知道如何获得相交点的确切坐标。那么,您认为最好的方法是什么?
为了便于实验,我准备了一个最小可重复的例子:
var cube = {
"positions": [-1.0, -1.0, -1.0,
1.0, -1.0, -1.0, -1.0, 1.0, -1.0,
1.0, 1.0, -1.0, -1.0, -1.0, 1.0,
1.0, -1.0, 1.0, -1.0, 1.0, 1.0,
1.0, 1.0, 1.0
],
"indices": [
0, 3, 2,
1, 3, 0,
3, 1, 7,
1, 5, 7,
0, 4, 5,
5, 1, 0,
6, 2, 7,
2, 3, 7,
5, 4, 7,
7, 4, 6,
0, 6, 4,
0, 2, 6
],
"uv": [
0.0, 0.0, 1.0, 1.0, 0.0, 1.0,
1.0, 0.0, 1.0, 1.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 1.0, 0.0, 1.0, 1.0,
1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
1.0, 0.0, 1.0, 1.0, 0.0, 1.0
]
}
var camPos = [0, 0, -10];
var camRot = [0, 0, 0];
setInterval(() => {
for (var j = 0; j < cube.indices.length; j += 3) {
var startPos = [camPos[0], camPos[1], camPos[2]];
var rotation = [-camRot[0], camRot[1], camRot[2]];
var len = 1000000;
var endPos = [
startPos[0] + (len * Math.sin(rotation[1])),
startPos[1] + (len * Math.tan(rotation[0])),
startPos[2] + (len * Math.cos(rotation[1]))
];
var dir = [
endPos[0] - startPos[0],
endPos[1] - startPos[1],
endPos[2] - startPos[2],
];
var v1 = [
cube.positions[cube.indices[j] * 3],
cube.positions[cube.indices[j] * 3 + 1],
cube.positions[cube.indices[j] * 3 + 2]
];
var v2 = [
cube.positions[cube.indices[j + 1] * 3],
cube.positions[cube.indices[j + 1] * 3 + 1],
cube.positions[cube.indices[j + 1] * 3 + 2]
];
var v3 = [
cube.positions[cube.indices[j + 2] * 3],
cube.positions[cube.indices[j + 2] * 3 + 1],
cube.positions[cube.indices[j + 2] * 3 + 2]
];
var u = [
v2[0] - v1[0],
v2[1] - v1[1],
v2[2] - v1[2]
];
var v = [
v3[0] - v1[0],
v3[1] - v1[1],
v3[2] - v1[2]
];
var n = [
u[1] * v[2] - u[2] * v[1],
u[2] * v[0] - u[0] * v[2],
u[0] * v[1] - u[1] * v[0]
];
var w0 = [
startPos[0] - v1[0],
startPos[1] - v1[1],
startPos[2] - v1[2]
];
var a = -(n[0] * w0[0] + n[1] * w0[1] + n[2] * w0[2]);
var b = (n[0] * dir[0] + n[1] * dir[1] + n[2] * dir[2]);
if (b < 0) {
continue;
}
/*if(Math.abs(b) < 0.00001){
if(a==0){
//console.log("parallel");
continue;}
else{
//console.log("not intersecting");
continue;}
}*/
var r = a / b;
//console.log(r);
if (r <= 0 || r >= 1) {
//console.log("not intersecting");
continue;
}
var rd = [
dir[0] * r,
dir[1] * r,
dir[2] * r
];
var ii = [
startPos[0] + rd[0],
startPos[1] + rd[1],
startPos[2] + rd[2]
];
var uu = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
var uv = u[0] * v[0] + u[1] * v[1] + u[2] * v[2];
var vv = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
var w = [
ii[0] - v1[0],
ii[1] - v1[1],
ii[2] - v1[2]
];
var wu = w[0] * u[0] + w[1] * u[1] + w[2] * u[2];
var wv = w[0] * v[0] + w[1] * v[1] + w[2] * v[2];
var d = uv * uv - uu * vv;
var s = (uv * wv - vv * wu) / d;
if (s <= 0 || s > 1) {
//console.log("not intersecting");
continue;
}
var t = (uv * wu - uu * wv) / d;
if (t <= 0 || (s + t) > 1) {
//console.log("not intersecting");
continue;
}
// use these values to find the point of intersection somehow??
console.log(s + "," + t + "," + (s + t));
}
camRot[1] = Math.sin(Date.now() / 1000) * .1;
}, 10);
我目前的假设是,解决这个问题的最好方法是从检查光线是否在三角形边界内时返回的值来解释它,我一直在尝试通过点之间的线性插值来让它工作,边界计算返回的值为 t 值。我还没有让它工作,但如果它工作,我会告诉你。
答: 暂无答案
评论
ii