2015-07-01 106 views
0

我想確定兩個3D但共面三角形相交的所有點。我找到了檢測三角形是否相交的方法,但我真正需要的是交點出現的實際點。下面我已經展示了一些這種情況。 另外,我將用Java編寫這個代碼,但我相信只要我理解數學,我就可以轉換不同的語言!確定兩個3D(共面)三角形的所有交點

我知道所有的頂點,但就是這樣! 編輯澄清。

感謝, 邁克爾

https://www.dropbox.com/s/yoszrlfqbx3usrf/cases.png?dl=0

+0

什麼信息你有三角形嗎?你知道所有的頂點嗎? – Amber

+0

http://stackoverflow.com/questions/7113344/find-whether-two-triangles-intersect-or-not –

+0

是的,我知道兩個三角形的所有頂點,這就是我所知道的。 –

回答

0
  1. ,如果你沒有爲你需要計算它的平面方程。

  2. 忽略Z軸現在(除非這使得所有的點上在這種情況下,忽略另一個軸:)

  3. 找到交點爲每條邊的第一個三角形的每一個角落,並在同一行下跌其他三角

  4. 插頭的交點回到你的飛機的方程來恢復ž


步驟3:從line line intersection wikipedia article determinant

丟棄不落在兩邊的任何交叉


這裏是一個js代碼片段,做第3步

var a; 
 
var b; 
 
var bs = document.body.style; 
 
var ds = document.documentElement.style; 
 
bs.height = bs.width = ds.height = ds.width = "100%"; 
 
bs.border = bs.margin = bs.padding = 0; 
 
var c = document.createElement("canvas"); 
 
c.style.display = "block"; 
 
c.addEventListener("mousedown", randomize, false); 
 
c.addEventListener("mousemove", follow, false); 
 
document.body.appendChild(c); 
 
var ctx = c.getContext("2d"); 
 
window.addEventListener("resize", redraw); 
 
randomize(); 
 

 
function randomPoint() { 
 
    return {x:Math.random() * window.innerWidth, 
 
      y: Math.random() * window.innerHeight}; 
 
} 
 
function randomize(e) { 
 
    a = []; 
 
    b = []; 
 
    for (var i = 0; i < 3; i++) { 
 
    a[i] = randomPoint(); 
 
    b[i] = randomPoint(); 
 
    } 
 
    redraw(); 
 
} 
 
function follow(e) { 
 
    var average = {x:0, y:0}; 
 
    for (var i = 0; i < 3; i++) { 
 
    average.x += a[i].x/3; 
 
    average.y += a[i].y/3; 
 
    } 
 
    for (var i = 0; i < 3; i++) { 
 
    a[i].x += e.clientX - average.x; 
 
    a[i].y += e.clientY - average.y; 
 
    } 
 
    redraw(); 
 
} 
 
function drawPoint(p, color) { 
 
    ctx.strokeStyle = color; 
 
    ctx.beginPath(); 
 
    ctx.arc(p.x, p.y, 10, 0, 2 * Math.PI, true); 
 
    ctx.closePath(); 
 
    ctx.stroke(); 
 
} 
 
function isPointOnLine(p, v1, v2) { 
 
    if (v1.x === v2.x) 
 
    return (Math.max(v1.y, v2.y) >= p.y && Math.min(v1.y, v2.y) <= p.y) 
 
    else 
 
    return (Math.max(v1.x, v2.x) >= p.x && Math.min(v1.x, v2.x) <= p.x) 
 
} 
 
function calculateIntersection(a1, a2, b1, b2) { 
 
    var d = (a1.x - a2.x)*(b1.y - b2.y) - 
 
     (a1.y - a2.y)*(b1.x - b2.x); 
 
    if (!d) return null; 
 
    return { 
 
    x:((a1.x*a2.y - a1.y*a2.x)*(b1.x - b2.x) - 
 
     (a1.x - a2.x)*(b1.x*b2.y - b1.y*b2.x))/d, 
 
    y:((a1.x*a2.y - a1.y*a2.x)*(b1.y - b2.y) - 
 
     (a1.y - a2.y)*(b1.x*b2.y - b1.y*b2.x))/d 
 
    }; 
 
} 
 
function drawIntersections(a, b) { 
 
    a.forEach(function (a1, i) { 
 
    var a2 = a[(i + 1) % a.length]; 
 
    b.forEach(function (b1, j) { 
 
     var b2 = b[(j + 1) % b.length]; 
 
     var p = calculateIntersection(a1, a2, b1, b2); 
 
     if(!p) return; 
 
     if (isPointOnLine(p, a1, a2) && isPointOnLine(p, b1, b2)) 
 
     drawPoint(p, "red"); 
 
     else 
 
     drawPoint(p, "yellow"); 
 
    }); 
 
    }); 
 
} 
 
function drawShape(shape) { 
 
    ctx.strokeStyle = "black"; 
 
    ctx.beginPath(); 
 
    ctx.moveTo(shape[0].x, shape[0].y); 
 
    for (var i = 1; i <= shape.length; i++) { 
 
    ctx.lineTo(shape[i % shape.length].x, shape[i % shape.length].y); 
 
    } 
 
    ctx.closePath(); 
 
    ctx.stroke(); 
 
} 
 
function redraw() { 
 
    c.width = window.innerWidth; 
 
    c.height = window.innerHeight; 
 
    ctx.clearRect(0, 0, c.width, c.height); 
 
    ctx.fillStyle = "rgb(200, 200, 200)"; 
 
    ctx.font = "40px serif"; 
 
    ctx.fillText("click to randomize", 20, 40); 
 
    drawShape(a); 
 
    drawShape(b); 
 
    drawIntersections(a, b); 
 
}