【问题标题】:How do I calculate a normal?如何计算正常值?
【发布时间】:2011-07-25 11:39:26
【问题描述】:

好的,假设我得到了一个由 Thing A 的 x、y、宽度和高度组成的矩形(这都是 2d)。怎么算正常?

【问题讨论】:

  • 矩形的法线是什么意思?
  • 不知道,大概像它的朝向吧?
  • 我需要知道它面向哪个方向,以便我可以从它上面反射东西。
  • @CyanPrime 在 2d 中,矩形只有一种朝向,好吧,也许有两种:上下。我不认为那是你想要的。那你还需要这个正常做什么?
  • 他的意思是一条直线的法线,而不是矩形的法线。

标签: java math vector normalization


【解决方案1】:

青色,

您不是在寻找叉积或 3 维定义的法线。一分钟,我会解释..

编辑:

来自this answer,很明显您正在寻找的只是一个垂直于一条线的向量。不是垂直于平面的向量。

数学评估

R = A - 2<A, N> N

你首先要对Euclidean Vector有一个深刻的认识。

给定一个向量 A(你的入射角):

A = <ax, ay> 

给定向量 B(表示被反弹的墙壁的向量):

B = <bx, by>

这个向量的法线(垂直)简单地旋转了 90 度。数学上:

N = <nx, ny> = <-bx, by>

因此 R =

R = A - 2<A, N> N = ...

让我们首先评估点积

<A, N> = ax*nx + ay*ny = ax*(-bx) + ay*by = ay*by - ax*bx

然后:

R = <ax, ay> - 2*(ay*by - ax*bx) * N
  = <ax, by> - <2*(ay*by - ax*bx)*nx, 2*(ay*by - ax*bx)*ny>
  = <ax, by> - <2*(ay*by - ax*bx)*(-bx), 2*(ay*by - ax*bx)*(by)>
  = < ax + 2*bx*(ay*by - ax*bx), ay - 2*by*(ay*by - ax*bx) >

因此,您需要做的就是确定一个向量,该向量代表您要反弹的墙壁(即 B)和您的事件向量(即 A)。

编辑(因为评论):

您真的应该花时间查看我发布到欧几里得向量的链接...

基本思想是定义任意数学原点。 (例如,你的墙的底部)。代表你的墙的矢量只是一个箭头,从顶部到底部(或从底部到顶部)。以底部描述的原点为起点,此箭头将指向 x 方向上的 0 个单位,但指向 y 方向上的 100 个单位。因此,您的墙 (B) 向量就是:

B = < 0, 100 >

(请注意,墙的宽度并不重要 - 1px、50 px 或 100px 厚的墙会反弹)。

但是您需要对该向量进行归一化,使其具有单位大小(长度为 1)。于是向量变为:

B = <0, 1>

这来自:

Vector length = sqrt( bx^2 + by^2 ) = sqrt( 0^2 + 1^2 ) = 1

N 是:

N = <1, 0>  // for the left hand side wall
N = <-1, 0> // for the right hand side wall

【讨论】:

  • 抱歉回复晚了,我睡着了。但我想知道一些事情。 B = 现在我如何从一行中得到 1 个这样的数字?假设我的线是 (50, 0) 和 (50, 100) 使其宽 1 像素,高 100 像素,法线为 90(我认为?)我如何将这面墙变成 B 的一个向量?
  • @CyanPrime:见我的帖子。请查看我发布链接的向量数学。
  • @J T - 我认为你的情商。 'N = = ' 实际上应该是 ?
  • @ysap:顺时针旋转 90 度是正确的。但在这种情况下,我认为这并不重要。 :)
【解决方案2】:

如果“正常”是指垂直向量,请查看 cross product: 以获取向量

<a1, a2, a3>

<b1, b2, b3>

叉积是

<a2 * b3 - b2 * a3, a1 * b3 - b1 * a3, a1 * b2 - b1 * a2>

...但是纯 2D 中的“正常”没有多大意义。

【讨论】:

  • 叉积是 3 维空间中的坐标。
  • @Mahesh:是的,我认为这就是 OP 的意思,因为 2D 矩形的法线是 3D。
  • 使用这种方法,每个矩形的法线都是(0,0,1)。
  • @CyanPrime:它适用于 2D(正如其他人指出的那样,它为您提供&lt;0, 0, 1&gt; 的倍数),但根据定义,答案是 3D。 .
  • @CyanPrime 在这种情况下,您需要矩形边缘的法线。由于您的矩形始终与您的坐标对齐,因此您的法线将是 (0,1)、(0,-1)、(1,0) 或 (-1,0),具体取决于它是顶部、左侧、底部还是右边缘。
【解决方案3】:

去谷歌“交叉产品”。 (http://en.wikipedia.org/wiki/Cross_product)

将定义矩形边缘的向量作为您要跨越的向量。

【讨论】:

    【解决方案4】:

    小心。一个矩形有两个可能的法线:

    在平面上它有 4 个法线:

    【讨论】:

    • 虽然这幅画很漂亮,但矩形有无限多的法线。
    • @Blindy:哎呀,我不小心点了你的评论。 :( 不,它没有无限数量的法线...向量只是方向,而不是点。:\
    【解决方案5】:

    如果你的矩形在 XY 平面上,那么法线是 (0,0,1)。不需要代数!

    【讨论】:

    • @Andrew:注意@Blindy 说“a normal is (0,0,1)”,而不是“the normal”。
    • 如果旋转到60度角会怎样?我希望有一个公式,我可以编写代码并制作它,这样无论角度如何,东西都会从矩形反弹。
    • @Mehrdad,准确地说。 @CyanPrime,Mehrdad 已经给了你通用公式。我想你不明白什么是正常。
    【解决方案6】:

    整个矩形的法线将垂直于矩形的平面(沿第三个维度)。

    如果你的意思是垂直于矩形的一个(但与矩形在同一平面内),那么你可以计算边的斜率,法线的斜率为负它是法线侧的斜率的倒数。 (或者如果边的斜率为零,则未定义。)如果你想把这个法线放在矩形上,边的中点是一个很好的地方。

    【讨论】:

      【解决方案7】:

      cyanprime 正在寻找的是 2D 空间中 1 行的法线。

      该法线必须满足以下条件:

      m_line * m_normal = -1

      而 m_line 是线的大小,而 m_normal 是法线的大小。

      => m_normal = -1 / m_line

      如果 m_line = 0 显然会产生错误。因此您需要特别对待这种情况。

      如果 m_line 不为 0,则得到 2D 向量

      normal_vector = (1, m_normal)

      【讨论】:

        【解决方案8】:

        2D 中的法线是在对象中旋转 90 度的向量,与应该撞击它的对象的方向相反。

        这些法线有固定值,它们是:

        西 (1, 0); 东 (-1, 0); 北(0,-1); 南 (0, 1);

        【讨论】:

          猜你喜欢
          • 2021-06-19
          • 1970-01-01
          • 1970-01-01
          • 2018-11-04
          • 1970-01-01
          • 1970-01-01
          • 2021-08-05
          • 2020-07-21
          • 1970-01-01
          相关资源
          最近更新 更多