2013-04-01 3 views
0

사용자가 시작과 끝점을 정의 할 수있는 html 캔버스를 만들려고합니다. 시작점과 끝점 사이에 흔들린 선을 그립니다. bezierCurveTo를 그리기.시작과 끝점 만있는 베 지어 곡선 만들기

샘플 :

sample wave

나는이를 그리는 데 사용하는 코드는 다음과 같은 : 나는만큼에만 X 또는 단지 Y 좌표이 작업을 할 수

var wave = new Kinetic.Shape({ 
     drawFunc: function (canvas) { 
      var ctx = canvas.getContext(); 
      ctx.beginPath(); 
      ctx.moveTo(50, 50); 
      var waveCount = 0; 
      var controlPoint1X = 55; 
      var controlPoint2X = 60; 
      var endPointX = 65; 
      while(waveCount < 10) { 
       ctx.bezierCurveTo(controlPoint1X, 35, controlPoint2X, 65, endPointX, 50); 
       controlPoint1X += 20; 
       controlPoint2X += 20; 
       endPointX += 20; 
       waveCount++; 
      } 
      ctx.stroke(_this); 
     }, 
     stroke: '#000000', 
     strokeWidth: 2 
    }); 

변경. 이제 위와 같이 x, y 좌표가 다른 웨이브 된 선을 만들 수있게하려고합니다. 예를 들어 시작점 x : 50 y : 50 및 종단점 x : 100 y : 100. 컨트롤 포인트를 계산해야한다는 것을 알고 있지만 사용할 수식을 찾을 수 없습니다. 누군가 나를 도울 수 있습니까?

+0

당신의 squiggle을 생성하기 위해 반원 호를 사용할 수 있습니까?조금 더 균일하게 나타나고 베 지어 곡선을 생성하는 것과 동일한 복잡성을 가지지 않습니다. – Jlange

답변

1

원과 사인파를 직선으로 시뮬레이션 해 봅시다. 반원의 경우, 각 "기간"세그먼트와, 두 개의 세그먼트 중 하나의 존재로 구성

cDist = 4/3 * amplitude 

(우리가 http://pomax.github.com/bezierinfo/#circles_cubic에서이 알을)

S = (x1, 0), 
C1 = (x1, cDist) 
C2 = (x2, cDist) 
E = (x2, 0) 

세그먼트이 존재 :

S = (x2, 0), 
C1 = (x2, -cDist) 
C2 = (x3, -cDist) 
E = (x3, 0) 

사인파의 경우 제어점이 거의 동일합니다. y 좌표는 같은 높이에 머무르지 만 시작점과 끝점에서 모양이 수정 된 각도를 갖도록 x 좌표를 이동해야합니다 (원이 수직 인 경우 사인파의 경우 대각선입니다).

S = (x1, 0), 
C1 = (x1 + cDist/2, cDist) 
C2 = (x2 - cDist/2, cDist) 
E = (x2, 0) 

세그먼트 두 가지이다 : 당신이 고정 된 각도로이 라인을 원하는 경우에 http://jsfiddle.net/qcUyC/6

, 내 조언은 다음과 같습니다 :

S = (x2, 0), 
C1 = (x2+cDist, -cDist) 
C2 = (x3-cDist, -cDist) 
E = (x3, 0) 

난에서 이것의 논증을 넣어 회전 당신의 맥락. 실제로 좌표를 변경하지 마십시오. 그냥 context.rotate (...)를 사용하면 끝난다. 당신 절대적으로 실제 각도 라인을 나타내는 좌표를 바로 올바른 위치에 그려지지 좌표를해야하지만이있는 경우, http://jsfiddle.net/qcUyC/7

를 참조하지만, 다음 각도로 시작 :

angle = some value you picked, in radians (somewhere between 0 and 2*pi) 

와 그 각도, 우리는 우리의 점을 배치 할 수 있습니다

dx = some fixed value we pick 
dy = some fixed value we pick 

ox = the x-offset w.r.t. 0 for the first coordinate in our line 
oy = the y-offset w.r.t. 0 for the first coordinate in our line 

x1 = ox 
y1 = oy 

x2 = (dx * cos(angle) - dy * sin(angle)) + ox 
y2 = (dx * sin(angle) + dy * cos(angle)) + oy 

x3 = (2*dx * cos(angle) - 2*dy * sin(angle)) + ox 
y3 = (2*dx * sin(angle) + 2*dy * cos(angle)) + oy 

... 

xn = ((n-1)*dx * cos(angle) - (n-1)*dy * sin(angle)) + ox 
yn = ((n-1)*dx * sin(angle) + (n-1)*dy * cos(angle)) + oy 

당신이 그런 다음 세그먼트의 시작점을 기준 벡터로 제어 지점을 치료하기 위해 C1 그래서 '= C1-S, 및 C2'가 = C2-S , 그리고 너 로타 같은 변화를 가진 사람들을 말하십시오. 그런 다음 해당 벡터를 시작점까지 다시 추가하면 이제 올바르게 회전 된 제어점을 갖게됩니다.

그건 그렇다고하지 마세요. canvas2d API가 당신을 위해 회전을하고 그냥 직선을 그려 보자. 그것은 삶을 훨씬 쉽게 만듭니다.

+0

나는 A.x, A.y, B.x 및 B.y가 오는 지점을 철저히 따르지 않습니다. 저의 출발점과 종점입니까? –

+0

아니요, 이러한 것들은 "무엇이든간에"일반적인 것입니다. "A와 B라고 부르 자"라는 두 가지 점이 있다면, 이것은 A의 B에 대한 회전 방법입니다. A와 B를 당신의 점수로 바꾸고 끝내십시오. –

+0

아직 서클에 도착하지 못했습니다. 서클에서 두 개의 임의의 조절 점을 가져야 만합니까 (그리고 서클에있는 점을 선택하려면 어떻게해야합니까?) 원과 반지름을 계산하는 코드는 정확합니다. var radius = Math.sqrt (Math.pow ((x2 - x1), 2) + Math.pow ((y2 - y1), 2))/2; var angle = Math.atan ((x2 - x1)/(y2 - y1)); 이것은 제어 포인트 (내가 잘못 될 지점)를 계산하는 방법입니다. var cp1x = x1 + ((x2 - x1)/3); var cp1y = y1 + ((y2 - y1)/3); –