2013-08-28 3 views
1

Android 태블릿에서 음악을 표시하는 애플리케이션을 작성 중입니다.큐빅 베 지어에 대한 제어점 계산

두 개의 메모를 함께 연결하는 곡선과 매듭을 그릴 때가 왔습니다.

이 경우 저는 3 차 베 지어를 사용하려고합니다. 그러나 두 제어점의 위치를 ​​결정하는 방법을 모르겠습니다.

나는 곡선 (A)과 끝 (B) 점 (2D)뿐만 아니라 커브를 원하는 선 A - B까지의 거리를 분명히 알고 있습니다. 커브가 반드시 수평면에있을 필요는 없기 때문에 이것을 이렇게 넣었습니다.

결과 곡선이 하나의 주어진 점을 통과하도록 필요한 제어점을 결정하는 데 도움을 줄 수있는 사람이 있습니까? 예 : 평면으로부터의 거리와 A-B 평면상의 옵셋?

수학 전문가가 아니기 때문에 수학 공식 대신 프로그래밍 수식을 사용해 주시면 감사하겠습니다.

slur example

내가이 각 라인의 시작과 끝 지점뿐만 아니라, 나는 곡선이 통과 할 점을 알고 여기에

은 구체적인 예이다.

그러나 Google에서 지난 2 일 동안 검색 한 결과,이 곡선을 재현하는 데 필요한 두 개의 제어점 위치를 결정하는 올바른 수식을 찾을 수 없었습니다.

+0

그냥 시작과 끝 지점에서 너에게 잘 보이는 높이에 놓습니다. 좋은 곡선을 그리기 위해 수학이 필요하지 않습니다. 실험 만하면됩니다. 배우는 방법입니다. –

+0

귀하의 의견은 선이 항상 상단 호이며 항상 동일한 값을 사용할 수 있다는 전제로 사용됩니다. 그렇지 않다. 원호는 A-B면이 수평이거나 대각선이보다 작거나 적은 상태에서 위 또는 아래가 될 수 있습니다. 나는 대략적인 추정치가 아닌 정확성을 찾고있다. – Simon

+0

표면 위의 "높이"는 위 또는 아래로 가야하는지 여부에 따라 음수 값이 될 수 있습니다. 진짜 질문은 얼마나 많은 커브 클래스가 필요한가입니다. 귀하의 예는 매우 다른 두 개의 곡선을 보여 주므로 수학을 생략해도 최소한 "어떤 기능을 공유합니까?"분석을해야 할 수도 있습니다. 실제 답변을 작성하겠습니다. 정확성, 유익한 관계 및 비방을 원한다면 몇 가지 계산을 해보겠습니다. –

답변

10

수학에서 의존하지 않고이 작업을 수행 할 수있는 방법이 없습니다. 이미지에서 우리가 그릴 필요가있는 곡선의 종류는 첨부 된 항목에 달려 있기 때문입니다. 당신의 지정된 이미지가 두 곡선은 "건설"속성을 공유하지 않습니다 보여줍니다 분석 : 곡선에 맞게

빨간 선은, 시작/종료 기준선이며, 최대 변환을, 파란색 선은있다 첫 번째 컨트롤에서 두 번째 컨트롤을 종점으로 이동하면 녹색 선은 곡선의 수학적 중간 점 (t = 0.5)을 대략 나타내고 검은 선은 곡선의 최대 수직 확장을 표시합니다.

이러한 곡선을 형성하기 위해 표준 곡선에서 선형 대수학을 풀어서 우리가 그것을 얻는 곳을 살펴 보겠습니다.

우리가 표준 반원형 베 지어 곡선을 확장하여 만들 수있는 거의 대칭 곡선의로 오른쪽에있는 곡선은 실제로 구성 비교적 쉽게

:

{ (0,0), (0,0.552), (1,0.552), (1,0) } 

이 곡선 똑바로가는 것이 "밖으로", 그래서 약간의 각도에서 끝 곡선이 시작되도록 현실을 왜곡 할 수 : 직선 단위 선에, 그리고 반원의 높이 및 올라가고, 그래서 우리는 확장 할 필요가

{ (0,0), (0.2,0.552), (0.8,0.552), (1,0) } 

약 4 분의 1 높이로 떨어질 수 있습니다. y 좌표 앞에 몇 개의 빼기 기호를 붙이십시오.그들이에있어 있도록

{ (0,0), (0.2, +/- 0.138), (0.8, +/- 0.138), (1,0) } 

당신은 그것이 시작 지점 P1과 끝 지점 (P4)을 기반으로해야하는 라인 길이를 일치하도록 확장,

D = distance(p1, p4) 
{ (0,0), (0.2 * D, 0.138 * D), (0.8 * D, 0.138 * D), (D,0) } 

은 우리가 좌표를 회전 회전 행렬에서 그 각도를 당신의 라인과 수평 사이의 각도를 사용하고 고집, 각진 라인을 수정 :

phi = atan2(p4.y - p1.y, p4.x - p1.x) 

{ 
    (0, 0), 
    (0.2 * D * cos(phi) - 0.138 * D * sin(phi), 0.2 * D * sin(phi) + 0.138 * D * cos(phi)), 
    (D * cos(phi) - 0.138 * D * sin(phi), D * sin(phi) + 0.138 * D * sin(phi)), 
    (D * cos(phi), D * sin(phi) 
} 

이 "mathy"을 보이지만 그렇지 않다. cos (phi)와 sin (phi)는 이미 phi를 가지고 있다면, 단지 두 개의 숫자 일뿐입니다. 여기에 관련된 수학은 없으며, 그냥 바보 같은 arithmatics가 있습니다.

{ 
    (p1.x + 0, p1.y + 0), 
    (p1.x + 0.2 * D * cos(phi) - 0.138 * D * sin(phi), p1.y + 0.2 * D * sin(phi) + 0.138 * D * cos(phi)), 
    (p1.x + D * cos(phi) - 0.138 * D * sin(phi), p1.y + D * sin(phi) + 0.138 * D * sin(phi)), 
    (p1.x + D * cos(phi), p1.y + D * sin(phi) 
} 

완료 :

마지막 단계는이 페이지의 오른쪽 자리에있을 수 있도록 모든 좌표를 변환하는 다음이다. 두 번째 커브는 쉽게 만들 수 있습니다.

왼쪽의 곡선은 약간 더 효과적이지만 약간만 적용됩니다. 우리는 어쩌면 직관적이지 않은 방식으로 - 같은 방식으로 시작하여 이전과 똑같은 유형의 곡선을 형성하고 회전 전에 멈출 수 있습니다. 이미지에서 수평으로 곡선을 긋는다면 실제로는 반올림 된 반원이지만 크기는 오른쪽으로 기울어 짐을 볼 수 있습니다.

{ (0,0), (0.2 * D, 0.138 * D), (0.8 * D, 0.138 * D), (D,0) } 

수평

float sx = <strength of the shear> 
{ (0,0), (0.2 * D + 0.138 * D * sx, 0.138 * D), (0.8 * D + 0.138 * D * sx, 0.138 * D), (D,0) } 

전단 회전 :

회전하기 전에 :

phi = atan2(p4.y - p1.y, p4.x - p1.x) 

{ 
    (0, 0), 
    ((0.2 * D + 0.138 * D * sx) * cos(phi) - 0.138 * D * sin(phi), (0.2 * D + 0.138 * D * sx) * sin(phi) + 0.138 * D * cos(phi)), 
    ((D + 0.138 * D * sx) * cos(phi) - 0.138 * D * sin(phi), (D + 0.138 * D * sx) * sin(phi) + 0.138 * D * cos(phi)), 
    (D * cos(phi), D * sin(phi) 
} 

을 그리고 마지막 변환 단계는 동일합니다 그래서 그냥 그렇게하자. 다시 한번 말하지만, 이번에는 가장 잘 보이는 것을보기 위해 전단력 값으로 놀아야 만합니다.

무료 매개 변수

우리는 곡선 우리가 초기 반원을 확장 얼마나 많은 변화가 얼마나 "bowy"제어 할 수 있습니다. 0.25 요인은 비교적 단단하며 0.33은 비교적 거품이 많습니다. 우리는 또한 당신이 동점을 남긴 것처럼 곡선의 전단력이 얼마나 날카로운 지 제어 할 수 있습니다. 1의 전단력은 미묘하다. 1.75의 전단력은 급격히 급격하다. 이름에 단어 곡선에도 불구하고,이 작품을

베 지어 곡선을하지 왜

는 라인 ...의 선형 보간의 선형 보간이다. 커브를 구성하는 좌표에 선형 변환을 적용하면 커브의 속성이 유지되므로 전체 커브로 작업하는 대신 4 개의 좌표를 사용하여 커브를 올바르게 표시 할 수 있습니다.

그래서 우리는 우리의 좌표를 알고있는 곡선의 네 좌표를 복용하고, 다음 우리는 우리가 원하는 곡선을 얻기 위해 필요한 모든 변환을 적용

(x,y) . scale . (shearx?) . rotation, + (tx,ty) 

입니다 :

|x| . | D 0 | . | 1 shearx | . |cos(phi) -sin(phi)| + |tx| 
|y| | 0 D | | 0 1 | |sin(phi) cos(phi)| |ty| 

행렬 작업을 단일 행렬로 축소 할 수 있습니다. 따라서 컴퓨터는 2D/3D 작업에 뛰어납니다. 모든 행렬이므로 매우 복잡한 연산이 여전히 백만 개의 좌표에 적용되는 단일 행렬입니다.

z 값이 항상 1 인 좌표를 3 차원 좌표로 처리하면 실제로 행렬 연산으로 작업 할 수도 있습니다. 그러나 더 이상 사용자 질문과 관련성이 없습니다.

jsiddle

왼쪽 넥타이의 단계 구현에 의해 단계를위한 바이올린이 http://jsfiddle.net/CLbUF/1에서 찾을 수 있습니다,하지만이 모든 작업을 단일 작업으로 붕괴가 없습니다. 너 스스로 그렇게해야 해.