2015-01-21 4 views
0

(x, y)가 아닌 (x, z)가 사용되는 3D 공간 내에서 입방 형 베 지어 곡선을 따라 이동할 때 접선에 관한 문제가 있습니다. 커브 이미지가 추가되었습니다.C++ 베 지어 곡선 접선 방향 문제

이미지에 표시되는 빨간색 줄을 누르면이 문제가 발생합니다. 접선은 0.0에서 1.0까지 점진적으로 시작하지만 빨간색 선을 치고 1.0에서 0.0으로 점진적으로 감소하기 시작하여 엔터티의 방향이 바뀝니다.

현재이 잘린 접선을 담당 :

const Vector3 Class::getTangent(const float s) const 
{ 
    const float t { 1 - s }; 

    return (3 * t * t * (points.at(1) - points.at(0)) + 
      6 * s * t * (points.at(2) - points.at(1)) + 
      3 * s * s * (points.at(3) - points.at(2))); 
} 

는 I는이 기능을 사용

Vector3 firstDerivative = curve.getTangent(segment); 
firstDerivative.normalise(); 

Vector3 normal = firstDerivative.crossProduct(Vector3(0, 0, 1)); // Z = forward 
normal.normalise(); 

Vector3 b = firstDerivative.crossProduct(normal); 
b.normalise(); 

그럼 곡선을 따라 엔티티의 방향을 설정하기위한 간단한 사용 b. 엔티티를 반전시키는 지점에 도달하면 b의 부호를 -b으로 전환하여 간단하거나 더러운 수정을 작성했습니다. 현재이 "고정"에도 불구하고 커브가 변경되면 나중에 문제가 발생할 것이라고 나는 믿습니다.

누구든지 내가 잘못했을 수도 있고 해결해야 할 수도있는 부분을 발견하면 도움이 될 것입니다. 가상 또는 C++ 코드를 통해 주어진 문제와 함께 솔루션의 예를 제공 할 수도 있습니다.

enter image description here

+1

귀하의 질문은 명확하지 않습니다. 정확하고 길이가 0 또는 1보다 훨씬 큰 벡터를 생성합니다. 그 대신에 교차 제품을 왜 사용하고 있습니까? 벡터 교차 제품은 3D에서만 의미가 있습니다. 2d의 경우 점 t에 대한 접선 벡터를 취하여 단위 길이로 정규화 한 다음 90도 회전 할 수 있습니다. 끝난! 정규화 된 접선 벡터가 (vx, vy)이면 법선 벡터는 간단히 (-vy, vx)입니다. http://pomax.github.io/bezierinfo/#pointvectors를 참조하십시오. –

+0

아, 아마도 제가 언급 했어야합니다. 3D 공간에서. y 벡터는 위로, x와 z는 보통 x와 y와 같은 위치 지정에 사용됩니다. 나는 당신이 말했던 것을 이해하고 정규화 된 접선으로 시도했다고 생각합니다 : \t'float fdx = firstDerivative.x * cos (90) - firstDerivative.z * sin (90); \t float fdz = firstDerivative.x * sin (90) + firstDerivative.z * cos (90); \t Vector3 newVec = Vector3 (fdx, 0, fdz); '그러나 이렇게하면 빨간색 선에 다시 도달 한 후 엔터티가 튀어서 같은 결과가 나타납니다. _ 그러나 나는이 경우에 일반을 사용하지 않았습니다 ... _ – SharkBytes

답변

0

베 지어 곡선이 (x, z) 평면에 있기 때문에 왜 1 차 미분과 z 축 (0, 0, 1)간에 교차 곱을 취하고 싶지는 않습니다. 이 방법으로 발견 된 '정상'벡터는 1 차 미분 값이 (0, 0, 1) 방향으로 갈 때 제로가됩니다.

곡선의 주어진 점에서 법선 방향을 찾으려면 먼저 1 차 미분 C '(t)와 2 차 미분 C "(t)를 먼저 계산 한 다음 법선 벡터 vec (n)을 계산해야합니다.

및 법선 벡터 VEC는 (b) VEC 같이 계산 될 수있다 (b) = VEC (t |

VEC (N) = C 'XC "| C /'|| C"로 계산 될 수있다) X vec (n) 여기서 vec (t)는 단위 접선 벡터입니다. vec (t) = C '(t)/| C'(t) |

1

이것은 지형 도구에서 도로 발전기를 할 때 동료가 직면 나중에 경주 트랙 게임 데모에 대한 발전기 (wipeout97 스타일) 등을하면서 나는 또한 직면 한, 사실은 꽤 일반적인 문제입니다 잘 알려진 3D 상업용 콘텐츠 제작 도구입니다.

는이 가능한 것들 중 하나가 필요합니다이 문제를 해결하려면 다음

  • 하드 수직
  • 관성

하드 수직은 단순히 크로스 제품을 만들 어렵지 않다 고정 벡터 (예 : (0,1,0))를 사용하면 곡선이이 방향으로 정확하게 이동하지 않을 수 있습니다. 그렇지 않으면 교차 제품이 언젠가 null이되며 모든 지옥이 느슨해집니다.

관성 시스템은 곡선을 반복적으로 따라 가며 처음에는 참조 하드 벡터 하나를 사용하지만 한 번만 사용합니다.
그런 다음 곡선에 델타 증가분이오고 이전 세그먼트의 탄젠트 및 비트 대 (TBN 기준)를 점진적으로 변경하여 새로운 탄젠트 및 비트 대가 발견 될 때마다 곡선이옵니다. 작은 t (커브 매개 변수) 증가분이 거대한 TBN 변경으로 이어질 수 없다는 사실을 사용하고 이전 TBN 벡터 중 하나를 사용하여 새로운 접선을 가진 교차 곱을 만들어 새로운 B와 N을 찾습니다. 이렇게하면 거의 모든 종류의 짐벌 잠금 효과가 발생하지 않을 것입니다.

각 단계에서 TBN 기준으로 최대 회전 속도를 강요하는 등 다양한 가능한 재미있는 매개 변수가 가능합니다. 트랙을 만드는 경우에는 많은 예술적 힘이납니다.

+0

의사 나 C++ 코드, 특히 관성 시스템을 사용하여 두 시스템 모두의 예제를 들려 줄 수는 없을 것입니다. 나는 그것에 관련된 어떤 정보를 찾는다? – SharkBytes

+1

베 지어 곡선의 경우 베 지어 곡선이 커 스프 된 곡선을 모델링 할 수 있기 때문에 작은 't'증분으로 거대한 TBN 델타로 이어질 수 없다는 개념은 false입니다. 첨단을 가로 지르는 작은 't'증분은 어느 한쪽에 크게 다른 접선 값과 탄젠트 값을 산출합니다. –

+0

@ Mike'Pomax'Kamermans waw 나는 전에 "cusped"라는 말을 들어 본 적이 없었다. 너 나 한테 그걸 줬어. 그리고 지금 당신이 의미하는 바를 봅니다, 당신은 절대적으로 옳습니다. 필자는 "아티스트 케어"에 의해 이러한 사례를 제외한다고 가정 했었습니다. 그러나 절대적으로 옳았습니다. Paint Shop Pro에서 벡터 화살표를 조작 할 때 이러한 커 스프를 만드는 것을 기억합니다. –

0

좋아, 몇 가지 추가 실험을 통해 나는 그걸 작동시킬 수 있었고 이것이 괜찮은 해결책이라고 생각합니다. 누군가가이 사실을 제게 설명 할 수 있다면 감사 할 것입니다.

어쨌든 난에서 코딩있어 패키지 (현재 사용) setDirection (원래 사용)lookAt 을했다하는 두 가지 기능을 가지고 있었다.

코드 전에 :

entity->setDirection (firstDerivative, WorldSpace, secondDerivative); 

후 :

entity->lookAt (point - firstDerivative, WorldSpace); 
secondDerivative가 완전히 잘되는 지금은 사용되지 않습니다 그러나 이것은 더 즐기실 솔루션입니다 결과로 지금

또는 아니?