2015-11-23 76 views
0

假設我有一組四個或更多的點位於矩形的周長上,並且該矩形旋轉了某個未知量。我知道至少有一個點位於矩形的每一邊。一個任意的邊點被指定爲(0,0),其他點是距該起點的距離。我怎樣才能得到這個矩形的非旋轉角點?如何從側點獲得旋轉的矩形角點

+0

4分是不夠的。想象一下一個正方形,四個輸入點就是它的角落。現在畫一顆鑽石,使得四個點是每個邊緣的中點。任何四個點都是矩形的確切角落,可以繪製任意數量的其他矩形,以使這些點不是角點(一旦旋轉到正交,所有角點都將不同)。 – Draco18s

+0

我不確定我的理解。你的例子中的所有矩形都不會有相同的高度和寬度嗎?如果是這樣,那很好,在矩形旋轉到正交後,我可以根據左上角的值(0,0)重新計算每個點的相對偏移量。 – Kevin

+1

您證明紙上沒有獨特的解決方案:繪製一個正方形,現在在您的正方形上繪製一個旋轉的矩形(具有不同的高度和寬度)。選擇4個交點。你有4個點在2個明顯不同的矩形上(並且有2個以上的矩形可以滿足你的4個點)。 – dtudury

回答

1

假設你沒有試圖找到一種獨特的解決方案:

  1. 周圍0,0旋轉你的點,直到最頂層,最底層的, 最左邊,和最右邊的點所有不同點
  2. 通過最頂層和最底層,和垂直線通過畫水平線的最左邊和最右邊,最
  3. 大功告成

var points = []; 
 
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", addPoint, false); 
 
document.body.appendChild(c); 
 
var ctx = c.getContext("2d"); 
 
var interval; 
 

 
function addPoint(e) { 
 
    if (points.length >= 4) points = []; 
 
    points.push({ 
 
     x: e.x - c.offsetLeft, 
 
     y: e.y - c.offsetTop 
 
    }); 
 
    while (points.length > 4) points.shift(); 
 
    redraw(); 
 
} 
 
function rotateAround(a, b, r) { 
 
    d = {x:a.x - b.x, y:a.y - b.y}; 
 
    return { 
 
     x: b.x + Math.cos(r) * d.x - Math.sin(r) * d.y, 
 
     y: b.y + Math.cos(r) * d.y + Math.sin(r) * d.x 
 
    } 
 
} 
 
function drawPoint(p) { 
 
    ctx.strokeStyle = "rgb(0,0,0)"; 
 
    ctx.beginPath(); 
 
    ctx.arc(p.x, p.y, 10, 0, 2 * Math.PI, true); 
 
    ctx.closePath(); 
 
    ctx.stroke(); 
 
} 
 

 
var last_few = []; 
 

 
function redraw() { 
 
    if (interval) clearInterval(interval); 
 
    last_few = []; 
 
    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"; 
 
    if (points.length < 4) { 
 
     ctx.fillText("click " + (4 - points.length) + " times", 20, 40); 
 
     points.forEach(drawPoint); 
 
    } else { 
 
     var average = {x:0, y:0}; 
 
     points.forEach(function (p) { 
 
      average.x += p.x/4; 
 
      average.y += p.y/4; 
 
     }); 
 
     var step = 0; 
 
     interval = setInterval(function() { 
 
    \t \t ctx.clearRect(0, 0, c.width, c.height); 
 
\t   ctx.fillText("click anywhere to start over", 20, 40); 
 
      last_few.forEach(function(r) { 
 
      \t ctx.strokeStyle = "rgb(200,255,200)"; 
 
       ctx.save(); 
 
       ctx.translate(average.x, average.y); 
 
       ctx.rotate((step -r.step) * Math.PI/180); 
 
      \t ctx.strokeRect(r.lm - average.x, r.tm - average.y, (r.rm - r.lm), (r.bm - r.tm)); 
 
       ctx.restore(); 
 
      }); 
 
      var tm = Infinity; 
 
      var bm = -Infinity; 
 
      var lm = Infinity; 
 
      var rm = -Infinity; 
 
      points.forEach(function (p) { 
 
       p = rotateAround(p, average, step * Math.PI/180); 
 
       drawPoint(p); 
 
       tm = Math.min(p.y, tm); 
 
       bm = Math.max(p.y, bm); 
 
       lm = Math.min(p.x, lm); 
 
       rm = Math.max(p.x, rm); 
 
      }); 
 
      if (points.every(function (p) { 
 
       p = rotateAround(p, average, step * Math.PI/180); 
 
       return (p.x == lm) || (p.x == rm) || (p.y == tm) || (p.y == bm); 
 
      })) { 
 
       ctx.strokeStyle = "rgb(0,255,0)"; 
 
       ctx.strokeRect(lm, tm, (rm - lm), (bm - tm)); 
 
       last_few.push({tm:tm, bm:bm, lm:lm, rm:rm, step:step}); 
 
       while(last_few.length > 30) last_few.shift(); 
 
      } else { 
 
       ctx.strokeStyle = "rgb(255,0,0)"; 
 
       ctx.strokeRect(lm, tm, (rm - lm), (bm - tm)); 
 
      } 
 
      step++; 
 
     }, 30); 
 
    } 
 
} 
 

 
window.onresize = redraw; 
 
redraw();

+0

而不是你的第1步,如果我測量旋轉時點之間的水平距離怎麼辦?在這種測量最大的情況下,矩形是不是旋轉的?例如。那將是矩形與2D網格對齊的點,寬度> =高度。 – Kevin

+1

1)是一個無用的指令,4點已經不同了。 2)沒有幫助,因爲這些點可能不是角點。 – Draco18s

+0

@凱文找到最大的距離不一定能幫你找到每一點的一面;有幾種方法來排列點,使相鄰兩側的點之間的最長距離爲 – dtudury