2014-12-12 1 views
3

C++에서 베 지어 곡선을 렌더링하려고하므로 직접 구현하기 시작했습니다. 지금은 매우 효율적 일 필요는 없습니다. 내 코드는 어떻게 든 가까운 결과를 산출하지만 그 곡선은 정확하지 않습니다. (dvec2 두 배의 값의 벡터이다.) 현재왜 베지에 곡선 구현에 편향이 있습니까?

list<dvec2> bezier(list<dvec2> const &points, int resolution) 
{ 
    list<dvec2> samples; 
    double step = 1.0/resolution; 
    for (double time = 0.0; time <= 1.0; time += step) { 
     list<dvec2> sliders = points; 
     while (sliders.size() > 1) 
      sliders = slide(sliders, time); 
     samples.push_back(sliders.front()); 
    } 
    return samples; 
} 

list<dvec2> slide(list<dvec2> const &points, double time) 
{ 
    list<dvec2> result; 
    auto current = points.begin(); 
    dvec2 last = *current; 
    for (++current; current != points.end(); ++current) 
     result.push_back(last * time + *current * (1.0 - time)); 
    return result; 
} 

, I는 시간에 기초하므로, 제 2와 제 세 번째와 두 번째 및 보간하여 커브의 n-1 개의 점을 만들 티. 그런 다음, 같은 알고리즘으로이 새로운 세트의 포인트를 다시 축소합니다. 그 때까지 내가 그릴 수있는 포인트가 하나 남았습니다. 나는이 접근법이 효과가 있다고 생각한다.

렌더링 된 이미지에서 렌더링 된 여러 곡선에서 알고리즘 결과를 볼 수 있습니다.

rendering looks similar to bezier curves

예를 들어, 아래에서 화상의 좌측의 두 대향 곡선 대칭으로 생각한다. 내 것은 방향으로 치우쳐있다. 또한, 완전히 둘러싸인 커브는 t = 0.5에 대해 중심점을 적어도 그려야합니다. 이 원인은 무엇입니까?

+0

비 const 참조를 사용한다는 사실은 코드를 읽을 때 매우 짜증스럽고 혼란 스럽습니다. 나는 당신이 함수의 목록을 돌연변이시키고 있다고 확신했지만, 사실 당신은 그렇지 않다 ... 그리고 벡터 대신 목록을 사용하는 이유가 있는가? 목록은 거의 모든 유스 케이스 시나리오에서 느립니다. – leemes

+0

@leemes 조언 해 주셔서 감사합니다. 나는 그들을 추가 할 것입니다. – danijar

답변

4

접근 방법이 효과적입니다. 약간의 실수를했습니다. slide() 내에는 last을 루프에 업데이트하지 않습니다.

시도 :

(출처 : wikipedia)

베 지어 곡선의 다른 해석이이 제품의 합을 고려하여 부여 할 수 있음을

for (++current; current != points.end(); ++current) { 
    result.push_back(last * time + *current * (1.0 - time)); 
    last = *current; // <-- 
} 

주 일부 용어는 이러한 매개 변수 곡선과 관련되어 있습니다. 우리는 다항식

b_{i,n}(t) = {n\choose i} t^i (1 - t)^{n - i},\quad i = 0, \ldots, n

이 정도 N의 번스타인 기준 다항식으로 알려져있다

\mathbf{B}(t) = \sum_{i=0}^n b_{i, n}(t)\mathbf{P}_i,\quad t \in [0, 1]

있습니다. (N 실제로 상수에 의해 제한되는 고려 여기

, 당신이 (미리 계산 된) 이항 계수, 당신은 대신 두 개의 중첩 사람의 단일 루프를 끝낸다 std::pow 기능을 사용하여 필요로 만들려면 사전 계산 가능).

+0

고맙습니다, 지금 작동 중입니다. 예, 저는 나중에 최적화 할 것입니다. 왜냐하면 현재 계수를 계산하는 방법을 모르기 때문입니다. – danijar

+0

@danijar 임의의 수의 제어점에 대한 베 지어 곡선을 지원 하시겠습니까? 당신이 그것들을 제한 할 수 있다면 (20 절을 보자) 나는 이항 계수의 미리 계산 된 테이블을 제안한다. 이항 계수 함수를'constexpr' 함수로 작성하십시오. 그래서 컴파일 시간 동안 계산됩니다.만약 당신이 그들을 제한하고 싶지 않다면, 당신은 다음 트릭을 할 수 있습니다 : 더 많은 포인트 ('n')가 있다면'n-20' 포인트의리스트를 얻기 위해 다음의'20'을 줄입니다. 그런 다음 반복하십시오. 결국 두 개의 루프가 있지만 외부 루프에서 두 번 이상 반복 할 필요는 없습니다. 이 설명이 도움이되기를 바랍니다. – leemes

+0

아, 알겠습니다. 계수는 쉽습니다. 나는 최대 8 점의 커브 만 필요로하므로 아무런 문제가되지 않습니다. 계산에 시간을 어떻게 포함합니까? – danijar

관련 문제