简体   繁体   English

找到最小的小行星c ++位置

[英]find closest position of asteroids c++

游戏小行星在圆环表面上播放。

Well, since you can wrap around any edge of the screen, there are always 4 straight lines between the asteroid and the ship (up and left, up and right, down and left, and down and right). 好吧,因为你可以环绕屏幕的任何边缘,小行星和船之间总是有4条直线(向上和向左,向上和向右,向下和向左,向下和向右)。 I would just calculate the length of each and take the smallest result. 我只计算每个的长度并取最小的结果。

int dx1 = abs(ship_x - asteroid_x);
int dx2 = screen_width - dx1;

int dy1 = abs(ship_y - asertoid_y);
int dy2 = screen_height - dy1;

// Now calculate the psuedo-distances as Pete suggests:
int psuedo1 = (dx1 * dx1) + (dy1 * dy1);
int psuedo2 = (dx2 * dx2) + (dy1 * dy1);
int psuedo3 = (dx1 * dx1) + (dy2 * dy2);
int psuedo4 = (dx2 * dx2) + (dy2 * dy2);

This shows how to calculate the various distances involved. 这显示了如何计算所涉及的各种距离。 There is a little complication around mapping each one to the appropriate direction. 将每一个映射到适当的方向有一点复杂性。

我推荐A *搜索算法

Find the sphere in reference to the ship. 找到参考船的球体。

To avoid decimals in my example. 为了避免我的例子中的小数。 let the range of x & y = [0 ... 511] where 511 == 0 when wrapped 在包装时,让x&y的范围= [0 ... 511],其中511 == 0

Lets make the middle the origin. 让中间成为原点。

So subtract vec2(256,256) from both the sphere and the ship's position 因此从球体和船舶的位置减去vec2(256,256)

sphere.position(-255,255) = sphere.position(1 - 256 ,511 - 256); sphere.position(-255,255)= sphere.position(1 - 256,511 - 256);

ship.position(255,-255) = ship.position(511 - 256, 1 - 256) ship.position(255,-255)= ship.position(511 - 256,1 - 256)

firstDistance(-510,510) = sphere.position(-255,255) - ship.position(255,-255) firstDistance(-510,510)= sphere.position(-255,255) - ship.position(255,-255)

wrappedPosition(254,-254) = wrapNewPositionToScreenBounds(firstDistance(-510,510)) // under flow / over flow using origin offset of 256 wrappedPosition(254,-254)= wrapNewPositionToScreenBounds(firstDistance(-510,510))//在流量/溢出流量下使用原点偏移量256

secondDistance(1,-1) = ship.position(255,-255) - wrappedPosition(254,-254) secondDistance(1,-1)= ship.position(255,-255) - wrappedPosition(254,-254)

#include <iostream>

template<typename Scalar>
struct vector2d {
  Scalar x;
  Scalar y;
};
template<typename Scalar>
struct position2d {
  Scalar x;
  Scalar y;
};

template<typename S>
S absolute( S in ) {
  if (in < S())
    return -in;
  return in;
}

template<typename S>
S ShortestPathScalar( S ship, S rock, S wrap ) {
  S direct = rock-ship;
  S indirect = (wrap-ship) + (rock);
  if (absolute( direct ) > absolute( indirect ) ) {
    return indirect;
  }
  return direct;
}

template<typename S>
vector2d<S> ShortestPath( position2d<S> ship, position2d<S> rock, position2d<S> wrap ) {
  vector2d<S> retval;
  retval.x = ShortestPathScalar( ship.x, rock.x, wrap.x );
  retval.y = ShortestPathScalar( ship.y, rock.y, wrap.y );
  return retval;
}


int main() {
  position2d<int> world = {1000, 1000};
  position2d<int> rock = {10, 10};
  position2d<int> ship = {500, 900};
  vector2d<int> path = ShortestPath( ship, rock, world );
  std::cout << "(" << path.x << "," << path.y << ")\n";
}

No point in doing crap with squaring stuff in a simple universe like that. 在这样一个简单的宇宙中用平方的东西做废话毫无意义。

Scalar support for any type that supports a < b , and default construction for a zero. Scalar支持任何支持a < b类型,以及支持零的默认构造。 Like double or int or long long . doubleintlong long

Note that copy/pasting the above code and handing it in as an assignment at the level of course where you are playing with that problem will get you looked at strangely. 请注意,复制/粘贴上述代码并将其作为一个作业在您正在玩该问题的级别处交付将使您看起来很奇怪。 However, the algorithm should be pretty easy to follow. 但是,算法应该很容易遵循。

If you need the smallest way to the asteroid, you don't need to calculate the actual smallest distance to it. 如果您需要最小的小行星方式,则无需计算与小行星的实际最小距离。 If I understand you correctly, you need the shortest way not the length of the shortest path. 如果我理解正确,你需要最短的路而不是最短路径的长度。

This, I think, is computationally the least expensive method to do that: 我认为,这在计算上是最便宜的方法:

Let the meteor's position be (Mx, My) and the ship position (Sx, Sy). 让流星的位置为(Mx,My)和船位(Sx,Sy)。 The width of the viewport is W and the height is H. Now, 视口的宽度为W,高度为H.现在,

dx = Mx - Sx, dy = My - Sy. dx = Mx - Sx,dy = My - Sy。

if abs(dx) > W/2 (which is 256 in this case) your ship needs to go LEFT, if abs(dx) < W/2 your ship needs to go RIGHT. 如果abs(dx)> W / 2(在这种情况下为256)你的船需要左转,如果abs(dx)<W / 2你的船需要右转。 IMPORTANT - Invert your result if dx was negative. 重要信息 - 如果dx为负数,则反转结果。 (Thanks to @Toad for pointing this out!) (感谢@Toad指出这一点!)

Similarly, if abs(dy) > H/2 ship goes UP, abs(dy) < H/2 ship goes DOWN. 同样,如果abs(dy)> H / 2船上升,则abs(dy)<H / 2船变为DOWN。 Like with dx, flip your result if dy is -ve. 和dx一样,如果dy是-ve,请翻转你的结果。

This takes wrapping into account and should work for every case. 这需要考虑因素,并且应该适用于每个案例。 No squares or pythagoras theorem involved, I doubt it can be done any cheaper. 没有广场或毕达哥拉斯定理,我怀疑它可以做得更便宜。 Also if you HAVE to find the actual shortest distance, you'll only have to apply it once now (since you already know which one of the four possible paths you need to take). 此外,如果您必须找到实际的最短距离,您现在只需要应用一次(因为您已经知道需要采取哪四种可能的路径)。 @Peter's post gives an elegant way to do that while taking wrapping into account. @ Peter的帖子提供了一种优雅的方式来实现这一点,同时考虑到包装。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM