方向角或将 3D 角度指向空间中的某个位置

发布于 2024-09-27 22:11:34 字数 292 浏览 3 评论 0原文

我试图将一个实体指向 3D 矢量。 (基本上是设置一个实体角度,使其指向 3D 空间中的一个位置)。目前,我一直坚持从向量获取角度。

//Vectors in the bracket are 3D, first is the entity position, second is a position in space where I want to point at.
( myEntity.Pos - posToPointAt ).Angle

我目前正致力于将方向向量转换为角度。非常感谢您的帮助。

I'm trying to point an entity to a 3D vector. (basically setting an entities angle so it points to a position in 3D space). At the moment, I'm stuck with getting an angle from a vector.

//Vectors in the bracket are 3D, first is the entity position, second is a position in space where I want to point at.
( myEntity.Pos - posToPointAt ).Angle

I'm currently stuck at transforming the direction vector into an angle. Help is much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏尔 2024-10-04 22:11:34

这不是它的工作原理,您丢失了一个重要的信息:您需要弄清楚您的实体现在指向什么方向,而不是使用实体位置?获取该信息可能就像使用当前的旋转矩阵并将其与沿 z 轴(或实体的“中性”方向)的单位向量相乘一样简单,但这一切都取决于您的特定设置。

一旦您拥有两个方向向量(您当前的方向,以及到新的所需位置的方向...最后一个是标准化的“myEntity.Pos - posToPointAt”),您可以使用如下所示的函数计算方向之间的旋转。请注意,我在这里使用四元数,您可能需要旋转矩阵。

function RotationBetweenVectors( const aV1, aV2: TVector3): TQuaternion;
const
  EPSILON = 0.000001;

var
  v1: TVector3;
  v2: TVector3;
  dot: FloatT;
  s: FloatT;
  invS: FloatT;
  c: TVector3;

begin
  v1 := aV1.normalize;
  v2 := aV2.normalize;

  dot := VectorDotProduct( v1, v2 );

  if dot >= 1 then
  begin
      // INFO: DotProduct = 1 -> vectors are the same
      result := QUATERNION_IDENTITY
  end
  else if ( dot < EPSILON - 1 ) then
  begin
      raise Exception.create( '180 degree rotation currently not supported.' );
  end
  else
  begin
      s := sqrt( 2 * ( 1 + dot ));
      invS := 1 / s;

      c := VectorCrossProduct( v1, v2 );

      result.x := c.x * invS;
      result.y := c.y * invS;
      result.z := c.z * invS;
      result.w := 0.5 * s;
      result := result.normalize;
  end;
end;

That's not how it works, you are missing an essential bit of information: in stead of using the entity position, you need to figure out what way your entity is pointing right now? Acquiring that info might be as simple as using your current rotation matrix and multiplying it with a unit vector down the z-axis (or whatever the "neutral" direction of the entity is), but that all depends on your particular setup.

Once you have both direction vectors (your current direction, and the direction to the new desired location... the last one being the normalized "myEntity.Pos - posToPointAt"), you use a function like below to calculate the rotation between the directions. Notice I use quaternions here, you might be needing a rotation matrix.

function RotationBetweenVectors( const aV1, aV2: TVector3): TQuaternion;
const
  EPSILON = 0.000001;

var
  v1: TVector3;
  v2: TVector3;
  dot: FloatT;
  s: FloatT;
  invS: FloatT;
  c: TVector3;

begin
  v1 := aV1.normalize;
  v2 := aV2.normalize;

  dot := VectorDotProduct( v1, v2 );

  if dot >= 1 then
  begin
      // INFO: DotProduct = 1 -> vectors are the same
      result := QUATERNION_IDENTITY
  end
  else if ( dot < EPSILON - 1 ) then
  begin
      raise Exception.create( '180 degree rotation currently not supported.' );
  end
  else
  begin
      s := sqrt( 2 * ( 1 + dot ));
      invS := 1 / s;

      c := VectorCrossProduct( v1, v2 );

      result.x := c.x * invS;
      result.y := c.y * invS;
      result.z := c.z * invS;
      result.w := 0.5 * s;
      result := result.normalize;
  end;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文