【问题标题】:Find point in right triangle with given one vector and one point在给定一个向量和一个点的直角三角形中找到点
【发布时间】:2015-01-11 19:12:43
【问题描述】:

我正在开发一个用户用手指移动汽车的游戏。汽车表示为矢量(屏幕中的一个点和旋转角度)。当用户开始拖动汽车时,他会生成一个新点 P。我正在尝试平滑汽车的移动,因此如果该点位于汽车边缘 +/- 10px 的某个位置,它就不会改变其角度(汽车被表示为矩形)。这是一张图片,可以更好地解释:

如何找到点 M(x,y)?

(请注意,角度α是小车的旋转角度,不是O点和P点的角度)

【问题讨论】:

  • 澄清一点:角度(a)是角度MOP?你知道P的坐标吗?你知道长度OM吗?你知道OP的长度吗?
  • 角度 (a) 是红色矩形的旋转而不是 MOP,但这个角度很容易找到。 P是屏幕上的触摸点(已知)。所以长度 OP 又很容易找到。然而,距离 OP 是未知的,但我们可以找到它:OM = OP * cos(a)。我希望现在更清楚了。谢谢。
  • M 和 P 不一样。目前的解决方案就是这样(M=P),即使距离触摸点很近,汽车也在旋转,这很无聊。我想用这个来改善汽车的移动性。
  • OM = OP * cos(a) 仅当角度 (a) 是我所知的角度 MOP 时才为真。你是说角度 (a) 不是角度 MOP!
  • 是的,你是对的,我只是想解释一下,OM 很容易通过 OP 和 OM 夹角的 cos 找到。

标签: graphics geometry trigonometry


【解决方案1】:

OM 垂直于 PM 并在 a (alpha) 定义的方向上,即 OM= m.(cos a, sin a)。 p>

让我们取消点积:

m.(cos a, sin a).(x1 - m.cos a, y1 - m.sin a) = 0 = m.(x1.cos a + y1.sin a - m),

m = x1.cos a + y1.sin a

OM= (x1.cos a + y1.sin a).(cos a, sin a).

【讨论】:

    【解决方案2】:

    不确定我是否正确,但是:

    1. 您想消除小角度差异以避免振荡

      • 为此截断一些角度

        const double acc=5.0*M_PI/180.0; // truncate to 5 deg angle steps
        double a=atan2(P.y-O.y,P.x-O.x); // P direction [rad]
        a=round(a/acc)*acc;                // truncate
        M.x=x0+delta*cos(a);
        M.y=y0+delta*sin(a);
        
      • delta 是获取 M 作为新车位置的速度*时间

    2. 你想让汽车更逼真

      • 然后改用角度积分

        double alpha=0.0; // car direction [rad]
        double omega=0.0; // car rotation speed [rad/s]
        double epsilon=0.0; // car rotation acceleration [rad/s^2]
        // in timer (update) with interval dt [s]
        double a=atan2(P.y-O.y,P.x-O.x); // P direction [rad]
        a-=alpha; // get the difference and handle overflows
        while (a<-M_PI) a+=2.0*M_PI;
        while (a>+M_PI) a-=2.0*M_PI;
        epsilon=(some_rotation_speed_constant)*a/M_PI;
        omega+=epsilon*dt;
        alpha+=omega*dt;
        M.x=x0+delta*cos(alpha);
        M.y=y0+delta*sin(alpha);
        
      • 你也应该使用积分来定位...

      • 如果您不想手动操作,也可以为转轮 P、PI 或 PID 添加一些调节器
    3. 您只需要 M 并知道 P、O 和汽车方向角 a

      • 然后利用点积

        D.x=cos(a);
        D.y=sin(a);
        M=O+(D*dot(P-O,D));
        if (|M-P|<10px) ignore_turning;
        
      • 以防万一dot(A,B)=(A.x*B.x)+(A.y*B.y);

    【讨论】:

    • 感谢您花时间和精力写这个答案。我有两个问题: 1. 行 M=O+(D*dot(P-O,D)); P-O 是向量对吗? (P.x-O.x, P.y-O.y) 和 2。我认为点方程中的加号应该在 (A.y+B.y) 中相乘
    • @Ivica 是的,它是向量,是的,它是一个错字(已经编辑过) ps 点积为您提供一个向量到另一个大小的垂直投影,作为另一个向量的标量乘积...
    【解决方案3】:

    给定 O(x0, y0), alpha 和 P(x1, y1):

    M.x = 1/2 ( (y0 - y1) / tan(alpha) + x0 + x1 )
    M.y = 1/2 ( (x0 - x1) * tan(alpha) + y0 + y1 )
    

    您可能需要调整标志以匹配您的坐标系

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多