2013-08-09 4 views
1

시작점, 끝점 및 2 개의 제어점 (이 매개 변수는 http://www.w3schools.com/tags/canvas_beziercurveto.asp)으로 정의 된 베 지어 곡선이 있습니다. 먼저,이 곡선의 너비와 높이를 계산해야합니다. 곡선 주위에 직사각형을 만들면 폭과 높이가 필요한 것입니다. 그러면이 사각형의 점 (왼쪽 위 모서리의 x, y)을 시작해야합니다.베 지어 곡선의 너비, 높이 및 위치를 계산하는 방법

어떻게 계산할 수 있습니까? 감사.

답변

0

대략적인 솔루션을 찾고 있다면 커브를 감싸기에 충분히 큰 솔루션을 계산하는 것은 꽤 쉽지만 너무 클 수 있습니다.

베 지어는 '볼록 선체 속성'을 충족시킵니다. 즉, 제어점 경계 상자를 사용하여 커브 자체를 바인딩 할 수 있음을 의미합니다.

더 정확한 것을 찾고 있다면 가장 간단한 방법은 커브의 여러 점을 평가하고 커브의 해당 점 경계 상자를 가져 오는 것입니다. 품질/속도 트레이드 오프를 변경하기 위해 테스트 할 포인트 수를 변경할 수 있습니다.

정확한 답을 직접 계산하는 것을 찾고 있다면 함수 x (t)와 y (t)의 극한을 찾는 루트 파인더가 필요합니다.

0

실제 경계의 경우 곡선의 구성 요소 함수의 극단을 계산 한 다음 각 끝의 (x, y) 좌표에 대해 베 지어 함수에 연결해야합니다. 나는이 부분을 http://pomax.github.io/bezierinfo/#extremities에서 다룬다. 또한 말단 부분까지 이어지는 텍스트에 들어가기 위해 필요한 대부분의 단계를 수행하는 방법을 설명한다. 문단 11과 12/13은 바운딩 박스 (평범한 것, 아마도 관심이있는 것, 그리고 단단한 것)를 다룹니다.

1

다른 주제에서 대략적인 해결책을 찾았습니다. 그것을 계산하는 간단한 JS 함수 :

function getCurveBoundary(ax, ay, bx, by, cx, cy, dx, dy) { 
     var tobx = bx - ax; 
     var toby = by - ay; 
     var tocx = cx - bx; 
     var tocy = cy - by; 
     var todx = dx - cx; 
     var tody = dy - cy; 
     var step = 1/40; // precission 
     var d, px, py, qx, qy, rx, ry, tx, ty, sx, sy, x, y, i, minx, miny, maxx, maxy; 
     function min(num1, num2) { 
      if (num1 > num2) 
       return num2; 
      if (num1 < num2) 
       return num1; 
      return num1; 
     } 
     function max(num1, num2) { 
      if (num1 > num2) 
       return num1; 
      if (num1 < num2) 
       return num2; 
      return num1; 
     } 
     for (var i = 0; i < 41; i++) 
     { 
      d = i * step; 
      px = ax + d * tobx; 
      py = ay + d * toby; 
      qx = bx + d * tocx; 
      qy = by + d * tocy; 
      rx = cx + d * todx; 
      ry = cy + d * tody; 
      toqx = qx - px; 
      toqy = qy - py; 
      torx = rx - qx; 
      tory = ry - qy; 

      sx = px + d * toqx; 
      sy = py + d * toqy; 
      tx = qx + d * torx; 
      ty = qy + d * tory; 
      totx = tx - sx; 
      toty = ty - sy; 

      x = sx + d * totx; 
      y = sy + d * toty; 
      if (i == 0) 
      { 
       minx = x; 
       miny = y; 
       maxx = x; 
       maxy = y; 
      } 
      else 
      { 
       minx = min(minx, x); 
       miny = min(miny, y); 
       maxx = max(maxx, x); 
       maxy = max(maxy, y); 
      } 
     } 
     return {x: Math.round(minx), y: Math.round(miny), width: Math.round(maxx - minx), height: Math.round(maxy - miny)}; 
    }