【问题标题】:Need some math - Projecting Slope需要一些数学 - 投影斜率
【发布时间】:2012-01-23 23:34:22
【问题描述】:

我有一个矩形。 它的高度 (RH) 为 400。 它的宽度 (RW) 为 500。

我有圈子。 它的高度 (CH) 为 10。 其宽度 (CW) 为 10。 它的起始位置(CX1、CY1)是20、20。

圆圈移动了。 它的新位置(CX2、CY2)是 30、35。

假设我的圈子继续沿直线移动。 当它的边缘到达边界时,圆的位置是什么?

希望您能提供一个可重复使用的公式。

也许是一些带有这样签名的 C# 方法?

point GetDest(size itemSize, point itemPos1, point itemPos2, size boundarySize)

我需要计算该位置到达后的位置 - 知道它还不存在。

谢谢。

PS:我需要这个,因为我的应用程序正在监视我的 Windows Phone 上的加速度计。我正在计算用户倾斜设备时为矩形内的圆的运动设置动画所需的目标。

【问题讨论】:

  • 我不知道电话,但在winforws中应该是这样的:如果它是正确的,就像while(circle.Location.X < (this.Width - circle.Width)) { /* DO STUFF */};
  • 不,您正在尝试测试它是否已到达最终位置。我正在尝试在到达它之前计算最终位置。
  • 你知道两个圆的半径和圆心的位置,所以使用直线方程:y = m*x + b,没有微积分,只有代数。
  • @ChrisO,是的。我只是把它作为一个答案。我希望你发现任何错误。

标签: c# math windows-phone calculus


【解决方案1】:

距离边界 1 个半径(y/ies)。

【讨论】:

  • 我的回答仍然有效。考虑正常。
  • 你的答案太神秘了,没有用。对不起。
  • @IgnacioVazquez-Abrams。您的回答是正确的,但这只是说它处于边缘。他想知道边缘在哪里?
【解决方案2】:

答案是 X=270 Y=395

首先将斜率 V 定义为 dy/dx =(y2-y1)/(x2-x1)。在您的示例中:(35-20)/(30-20)=1.5

直线方程是 y = V * (x-x1) + y1。您对水平位置 x 感兴趣: y= CH/2 或 y= H-CH/2 所以(不是代码,只是数学)

if (y2-y1)<0:
 x=(CH/2 -y1)/V +x1     10 for your example. OR
if (y2-y1)>0:
 x=(H-CH/2 -y1)/V +x1   270 for your example
else (that is: y2==y1)
 the upper or lower lines were not hit.

if CH/2 <= x <= W-CH/2 the circle did hit the that upper or lower side: since V>0, we use x=270 and that is within CH/2 and W-CH/2. 

所以你的问题的答案是 y=H-CH/2 = 395 , X=270

侧线类似:

(if (x2-x1)<0)
 y=(CH/2 -x1)*V +y1   
(if (x2-x1)>0)
 y=(W-CH/2 -x1)*V +y1 
else (that is: x2==x1)
 the side lines were not hit.

if CH/2 <= y <= H-CH/2 the circle did hit that side at that y.

小心完全水平或垂直移动的琐碎情况,以免除以零。计算 V 或 1/V 时。还要处理圆完全不动的情况。

既然您现在问了,这里是 元代码,您应该可以轻松地将其转换为真正的方法。它也处理特殊情况。输入是您在示例中列出的所有变量。我在这里只使用一个符号来表示圆的大小,因为它是圆而不是椭圆。

method returning a pair of doubles    getzy(x1,y1,W,H,CH){

  if (y2!=y1){ // test for hitting upper or lower edges
    Vinverse=(x2-x1)/(y2-y1)
    if ((y2-y1)<0){
       xout=(CH/2 -y1)*Vinverse +x1 
       if (CH/2 <= y <= H-CH/2) {
           yout=CH/2
           return xout,yout
       }
     }
    if ((y2-y1)>0){
       xout=(H-CH/2 -y1)*Vinverse +x1 
       if (CH/2 <= y <= H-CH/2) {
           yout=H-CH/2
           return xout,yout
       }
    }
  }     
  // reaching here means upper or lower lines were not hit.
  if (x2!=x1){ // test for hitting upper or lower edges
    V=(y2-y1)/(x2-x1)
    if ((x2-x1)<0){
       yout=(CH/2 -x1)*V +y1 
       if (CH/2 <= x <= W-CH/2) {
           xout=CH/2
           return xout,yout
       }
     }
    if ((x2-x1)>0){
       yout=(H-CH/2 -x1)*V +y1 
       if (CH/2 <= x <= W-CH/2) {
           xout=H-CH/2
           return xout,yout
       }
    }
  }     
  // if you reach here that means the circle does not move...
   deal with using exceptions or some other way.
}

【讨论】:

  • 你能把它重构成一个方法吗?
  • @JerryNixon 我添加了类似 C 的元代码,您应该可以使用它。
【解决方案3】:

这很容易;不需要微积分。

你的圆的半径是R = CW/2 = CH/2,因为圆的直径是D = CW = CH.

为了让圆在切点处接触矩形的垂直边缘,您必须将圆向右移动一段距离(W - (CX1 + CW/2))

同样,当您将圆向下移动一段距离(H - (CY1 + CH/2)) 时,该圆将在切点处接触矩形的底边。

如果您在两个单独的翻译中执行此操作(例如,首先按给定的数量向右移动,然后按给定的数量向下移动,反之亦然),您会看到圆圈将同时触及右手垂直方向和切点处的底部水平边缘。

【讨论】:

    【解决方案4】:

    当移动的圆到达墙壁(边界)时,它将与圆上的四个点之一相切,称为 N、S、E 和 W。您知道它们的初始坐标。

    这些点沿着一条你知道的斜率行进:m=(y2-y1)/(x2-x1);在您的示例中, (x1, y1) - (20,20) 和 (x2, y2)= (30, 35)。

    你的问题是找到到达任何墙壁的第一个点 N、S、E 或 W 的轨迹。轨迹将是一条斜率为 m 的线。

    您可以通过将线的方向向量添加(或减去)到点 N、S、E 或 W 来实现此目的,并按 t 缩放。

    例如,N 是 (20, 15)。方向向量为 (x2-x1,y2-y1) = (10, 15)。然后 (20, 15) + t * (10, 15) 将在不同的 t 处撞击边界线。你可以解决这些;例如 20 + t*10 = 0,以及 20 + t*10 = 400 等。

    在所有四个轨迹上,幅度最小的 t 为您提供切点。

    【讨论】:

      【解决方案5】:

      不确定它的微积分..它不会只是以下内容:

      如果 y >= 390 则到达矩形的上边缘

      如果 x >= 490 则到达矩形的右边缘

      如果 y

      如果 x

      【讨论】:

      • 不,这是确定何时到达的计算。但它还没有。我需要在到达该位置之前计算最终位置。
      猜你喜欢
      • 1970-01-01
      • 2011-08-31
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      相关资源
      最近更新 更多