3D在考虑玩家Y旋转的情况下创建到距离的点 [英] 3D Create a point to a distance taking in consideration the Player Y rotation

查看:177
本文介绍了3D在考虑玩家Y旋转的情况下创建到距离的点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在一个Point(这是我们的玩家位置)前面定义一个2D平面区域,并检查其中包含哪些Point(敌人). 在游戏中,它用于通过X宽度,Y高度和Z长度来确定我们前面的盒子"中有哪些敌人.

I need to define a 2D plane area in front of a Point(which is our player position) and check which Points(enemies) are within it. In the game it is used to determine what enemies are within the "box" in front of us with X width, Y height and Z length.

我需要帮助计算飞机的左下角和右上角.

I need help calculating the bottom left and top right points of the plane.

输入:我们知道玩家的位置,我们知道玩家的旋转.只有飞机Y旋转很重要,因为飞机必须始终在运动员的前方.

Input : We know the player position and we know the player rotation. Only the player Y rotation matters, as the plane should always be in front of the player.

我们知道飞机的宽度和长度.在这种情况下,身高无关紧要,我知道如何计算.如果宽度为8米,长度为20,如果玩家位置为0,0,0,则左下角将为X = -4/Y = 0/Z = 0,右上角将为X = 4/Y = 0/Z = 20

We know the plane width and length. Height is irrelevant in this case, I know how to calculate it. If the width is 8 meters and the length 20, if player position is 0,0,0 the bottom left point would be X= -4 / Y = 0 / Z = 0 and the top right point would be X=4 / Y = 0 / Z = 20

我的代码仅在玩家Y旋转为0时有效,因为我只是将宽度/长度添加到当前的X和Z值.我需要正确的数学公式来确定左下角和右上角的位置,并输入玩家的Y旋转参数,以使平面区域始终与玩家面对的方向相同

My code only works when the player Y rotation is 0, because I simply add the width/length to current X and Z values. I need the correct math formula to determine where the bottom left and top right points would be, taking in parameter the Player's Y rotation, so that the plane area will always be in the same direction that the player is facing

这是我确切需要的视觉呈现:

Here is a visual representation of what I need exactly :

https://gyazo.com/fd5ad0e393f6db8236ee7fd766e7286b

`

float AreaWidth = 8;
float AreaLength = 20;
float AreaHeight = 10;

Point AreaBTMLeftPoint = new Point(PlayerPosition.getX()-(AreaWidth/2), 
PlayerPosition.getLoc().getY(), PlayerPosition.getLoc().getZ());

Point AreaTOPRightPoint = new Point(PlayerPosition.getLoc().getX()+ 
(AreaWidth/2), PlayerPosition.getLoc().getY(), 
PlayerPosition.getLoc().getZ()+(AreaLength));

float AreaBTMX = AreaBTMLeftPoint.getX();
float AreaBTMZ = AreaBTMLeftPoint.getZ();
float AreaTOPX = AreaTOPRightPoint.getX();
float AreaTOPZ = AreaTOPRightPoint.getZ();
float AreaMaxY = PlayerPosition.getLoc().getY()+(AreaHeight/2);
float AreaMinY = PlayerPosition.getLoc().getY()-(AreaHeight/2);

if (TargetPosition.getLoc().getX() > AreaBTMX && 
TargetPosition.getLoc().getX() < AreaTOPX &&
TargetPosition.getLoc().getY() > AreaMinY &&
TargetPosition.getLoc().getY() < AreaMaxY &&
TargetPosition.getLoc().getZ() > AreaBTMZ && 
TargetPosition.getLoc().getZ() < AreaTOPZ) {

This target is inside the area, do stuff.

}`

推荐答案

让玩家位置为P,方向角为Fi,目标位置为T.
单位方向向量D:

Let player position is P, direction angle is Fi, target position is T.
Unit direction vector D:

d.x = cos(Fi) //don't forget about radians
d.y = sin(Fi)

差异向量

PT = T - P = (T.x - P.x, T.y - P.y)

从T到玩家方向线的垂直距离是正交投影的长度

Perpendicular distance from T to direction line of player is length of orthogonal projection

perplen = Abs(Pt x D) =                  //cross product
          Abs(PT.x * d.y - Pt.y * d.x)
compare it with (AreaWidth/2)

沿方向线的距离:

alonglen = (Pt .dot. D) =                  //dot product
           PT.x * d.x + PT.y * d.y
it should be >=0 and <= than AreaLength

如果两个条件都成立,则目标位于倾斜的矩形

If both conditions are true, target lies in inclined rectangle

概念验证Delphi代码:

Proof-of-concept Delphi code:

var
  i, px, py, tx, ty, XX, YY, ptx, pty: Integer;
  perplen, alonglen: Double;
  wdt, lng: Integer;
  Fi, cs, sn: Double;
begin
  px := 300;    py := 300;
  wdt := 150;   lng := 250;
  Fi := Pi / 6;   cs := Cos(Fi);   sn := Sin(Fi);
  Canvas.Brush.Color := clBlack;
  Canvas.Ellipse(px - 5, py - 5, px + 6, py + 6);  //player

  Canvas.Brush.Style := bsClear;
  Canvas.MoveTo(px, py);
  XX := px - Round(Wdt / 2 * sn);  YY := py + Round(Wdt / 2 * cs);
  Canvas.LineTo(XX, YY);
  XX := XX + Round(lng * cs);   YY := YY + Round(lng * sn);
  Canvas.LineTo(XX, YY);
  XX := XX + Round(Wdt * sn);   YY := YY - Round(Wdt * cs);
  Canvas.LineTo(XX, YY);
  XX := XX - Round(lng * cs);   YY := YY - Round(lng * sn);
  Canvas.LineTo(XX, YY);
  Canvas.LineTo(px, py);  //rectangle finished

  for i := 0 to 99 do begin
    tx := 100 + Random(600);  //random target
    ty := 100 + Random(600);
    ptx := tx - px;
    pty := ty - py;
    perplen := Abs(ptx * sn - pty * cs);
    alonglen := ptx * cs + pty * sn;
    if (perplen <= Wdt / 2) and (alonglen >= 0) and (alonglen <= lng) then
      Canvas.Brush.Color := clBlue  // in region
    else
      Canvas.Brush.Color := clRed;
    Canvas.Ellipse(tx - 3, ty - 3, tx + 4, ty + 4);
  end;

这篇关于3D在考虑玩家Y旋转的情况下创建到距离的点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆