왜 물체가 90 도보 다 45도 더 빠르게 움직입니까?


32

게임에 45도에서 90 도로 더 빠르게 움직이는 물체가 있습니다.

각 개체는

  • 점 (x, y) 위치
  • Vector2D (x, y) 방향
  • INT 속도

그리고 업데이트하는 동안 새 위치는 다음과 같이 계산됩니다.

position.x += direction.x * speed
position.y += direction.y * speed

이 문제를 어떻게 해결합니까? 어떤 각도에서도 같은 속도로 움직이기를 원합니다.


8
사용하기 전에 방향 벡터를 정규화하십시오. 문제 해결됨.
감속 캐비어

1
구글 정규화해야했습니다 :)이 유용한 사이트 fundza.com/vectors/normalize/index.html을
Jason94

그리고이 객체를 제어하기 위해 사용자 입력을 사용하는 경우 XNA 개발자를 위해 여기에 설명 된대로 xona.com/2010/05/03.html 12,3,6,9 방향으로 잠그는 것에주의하십시오 . RPG 게임과 같이 원하는 것이거나 (지오메트리 전쟁 스타일의 게임과 같은) 것이 아닐 수도 있습니다.
Xonatron

오래된 게임 Descent 에서 이것은 기능 이었습니다.
J. Holmes

@ 32bitkid 예, 참조 운명이 straferunning
bobobobo

답변:


55

이것은 피타고라스 정리 (Pythagorean Theorem) 로 설명 될 수 있으며 , 이는 다음 공식입니다 :

a² + b² = c²

귀하의 경우, 오른쪽으로 이동할 때 (x : 1, y : 0)을 사용하여

c² = 1 + 0 = 1
c = sqrt(1) = 1.00

위아래로 움직일 때 (x : 1, y : 1)을 사용하면

c² = 1 + 1 = 2
c = sqrt(2) = 1.41

보시다시피 대각선 길이는 기본 축의 길이보다 깁니다.

다른 사람들이 언급했듯이 방향 벡터를 정규화해야합니다. XNA를 사용하면 다음과 같이 수행됩니다.

var normalizedDirection = direction;
normalizedDirection.Normalize();
position += normalizedDirection * speed

나는 당신의 도움에 +1을주는거야 내 질문 :
마틴.

12

사용하기 전에 방향 벡터를 정규화하십시오.

MindWorX가 설명했듯이, 방향 벡터가 슬픔을 줄 수 있다고 걱정한다면 단위 벡터 (크기 / 길이 1)인지 확인하십시오.

Length(Vector2(1, 1)) == 1.4142135623730951 // first hint of grief
Length(Vector2(1, 0)) == 1

Vector2(1, 1) * 2 == Vector2(2, 2)
Vector2(1, 0) * 2 == Vector2(2, 0)

Length(Vector2(2, 2)) = 2.8284271247461903 // second hint
Length(Vector2(2, 0)) = 2

표준화 된 경우 :

normal(Vector2(1, 1)) == Vector2(0.707107, 0.707107)
Length(Vector2(0.707107, 0.707107)) == 1 // perfect

14
유용한 답변이 아닙니다. 질문자는 "방향 벡터 정규화"의 의미를 알고 있다면 질문을하지 않았을 것입니다.
Kristopher Johnson

@KristopherJohnson 그것은 질문자가 벡터를 정규화하는 방법을 모른다는 것이 분명하지 않았습니다. 그럼에도 불구하고 질문자는 아무리 중요하지 않을만큼 충분히 유익한 것처럼 보입니다.
감속 캐비어

2
@ 크리스토퍼 존슨 (KristopherJohnson) : 질문자가 "방향 벡터 정규화"의 의미를 모르는 경우 Google에 입력하고 언어 이름을 추가하고 설명이 포함 된 코드를 가져 오기만하면됩니다.
Lie Ryan

6

방향을 어떻게 계산합니까? 45 도라면 (1,1)확실히 90 도보 다 빠를 것 (1,0)입니다.

나는 당신이 다음과 같은 것을 사용하는 것이 좋습니다 :

direction.x = Math.Cos(angleInRadians);
direction.y = Math.Sin(angleInRadians);

각도를 라디안으로 표시하려면 각도를 곱 PI / 180하거나 더 곱해야 합니다 MathHelper. 예 :

angleInRadians = 45.0 * Math.PI / 180.0; // first method
angleInRadians = MathHelper.ToRadians(45f); //second method

6

제이슨,

세 가지 객체 속성이 아니라

  • 점 (x, y) 위치
  • Vector2D (x, y) 방향
  • INT 속도

방향과 속도를 속도 벡터로 결합하는 것이 훨씬 쉽습니다. 그러면 두 가지 속성 만 있습니다.

  • 점 (x, y) 위치
  • Vector2D (x, y) 속도

위치 업데이트

객체의 위치를 ​​업데이트해야 할 때 다음과 같이 간단합니다.

position.x += velocity.x * Δt;
position.y += velocity.y * Δt;

Δt시차 또는 시차 또는 시차는 어디에 있습니까 ?

위치 및 속도 업데이트

이 방법으로 가속도 (중력 등)를 처리하는 것도 매우 쉽습니다. 가속도 벡터가있는 경우 속도와 위치를 다음과 같이 업데이트 할 수 있습니다.

position.x += (velocity.x * Δt) + (0.5 * acceleration.x * Δt * Δt);
position.y += (velocity.y * Δt) + (0.5 * acceleration.y * Δt * Δt);

velocity.x += acceleration.x * Δt;
velocity.y += acceleration.y * Δt;

(이것은 기본적으로 Physics 101의 s = vt + ½at² 공식입니다.)

속도 적용

일정한 속도로 주어진 속도를 적용하려면 다음과 같이 속도를 설정할 수 있습니다.

velocity.x = normalizedDirection.x * speed;
velocity.y = normalizedDirection.y * speed;

속도 도출

그리고 주어진 속도 벡터에서 속도와 방향을 도출하기 위해 반대로해야 할 경우, 피타고라스 정리 또는 .Length()방법을 사용하면됩니다 .

speed = velocity.Length();

속도를 알고 나면 속도를 속도로 나눠서 정규화 된 방향을 계산할 수 있습니다 (0으로 나누지 않도록주의).

if (speed != 0) {
    normalizedDirection.x = velocity.x / speed;
    normalizedDirection.y = velocity.y / speed;
} else {
    normalizedDirection.x = 0;
    normalizedDirection.y = 0;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.