叉乘在图形学中的几何意义 ---- 判断一个点是否在三角形内

1 叉乘是什么

先简单介绍一下叉乘(cross product)
在这里插入图片描述

a → × b → \overrightarrow{a} \times \overrightarrow{b} a ×b ,其结果,还是一个向量。
其方向,符合右手螺旋定则(右手手指头从a转向b,看大拇指指向哪里);
其模,等于 ∣ a → ∣ ∣ b → ∣ s i n θ |\overrightarrow{a}||\overrightarrow{b}|sin\theta a ∣∣b sinθ (其实就是a和b组成的平行四边形面积)

也可以直接用下面的式子表示:
a → × b → = ∣ i → j → k → a x a y a z b x b y b z ∣ = ( a y b z − a z b y ) i → + ( a z b x − z x b z ) j → + ( a x b y − a y b x ) k → \overrightarrow{a} \times \overrightarrow{b} = \left | \begin{matrix} \overrightarrow{i} & \overrightarrow{j} & \overrightarrow{k}\\ a_x & a_y & a_z\\ b_x & b_y & b_z \end{matrix} \right | = (a_ybz - a_zb_y)\overrightarrow{i} + (a_zb_x - z_xb_z)\overrightarrow{j} + (a_xb_y - a_yb_x)\overrightarrow{k} a ×b = i axbxj aybyk azbz =(aybzazby)i +(azbxzxbz)j +(axbyaybx)k
其中, i → , j → , k → \overrightarrow{i}, \overrightarrow{j}, \overrightarrow{k} i ,j ,k 是3个轴的单位向量

还可以用矩阵来表示:
a → × b → = A b → = [ 0 − a z a y a z 0 − a x − a y a x 0 ] [ b x b y b z ] \overrightarrow{a} \times \overrightarrow{b} = A \overrightarrow{b} = \begin{bmatrix} 0 & -a_z & a_y\\ a_z & 0 & -a_x\\ -a_y & a_x & 0 \end{bmatrix} \begin{bmatrix} b_x\\ b_y\\ b_z \end{bmatrix} a ×b =Ab = 0azayaz0axayax0 bxbybz

他的重要性质:
a → × a → = 0 → \overrightarrow{a} \times \overrightarrow{a} = \overrightarrow{0} a ×a =0
a → × b → = − b → × a → \overrightarrow{a} \times \overrightarrow{b} = - \overrightarrow{b} \times \overrightarrow{a} a ×b =b ×a
a → × ( b → + c → ) = a → × b → + a → × c → \overrightarrow{a} \times (\overrightarrow{b} + \overrightarrow{c}) = \overrightarrow{a} \times \overrightarrow{b} + \overrightarrow{a} \times \overrightarrow{c} a ×(b +c )=a ×b +a ×c

2 几何意义

在图形学中,向量的叉乘主要用于计算两个向量所在平面的法向量,以及计算出相机朝向和物体朝向之间的旋转轴,具体应用包括:

  1. 计算表面法向量:通过计算两个相邻的三角形的法向量来得到表面法向量,可以用于光照计算和渲染中的纹理映射等。

  2. 计算相机朝向和物体朝向之间的旋转轴:在相机跟随和相机旋转等操作中使用。

  3. 计算三角形面积:通过向量叉积的模长可以计算三角形面积,可以用于计算多边形的面积和法向量。

  4. 计算向量夹角:通过向量叉积的模长和点积的结果可以计算向量之间的夹角,可以用于计算光源和物体的夹角以及阴影的计算等。

  5. 判断一个点是否在三角形内

下文针对5,具体讲一下如何使用。

3 使用例子- 判断一个点是否在三角形内

3.1 使用背景

判断一个点,是否在三角形内,有什么用途呢?一个经典的用途是,在光栅化阶段,GPU会去挨个处理每个像素,应该显示什么数据,或者说,显示哪个三角形面的数据。
咱们来最简化的描述这个过程:
假色我们的3D画面非常简单,只有4个顶点,即2个三角形,映射到屏幕上,如下图所示
在这里插入图片描述

现在开始扫描每个像素该显示啥。方法就是,判断是否在2个三角形内,如果不在,就显示默认色了,如果在,就采样三角形的对应纹理色值。
所以,现在的问题,就可以归纳为一个函数:
isInTringle(Trangle tr)

3.2 如何判断

请看下面一组图,Q点在三角形内,可以看看有什么规律:
在这里插入图片描述
向量P1P2与P1Q,右手螺旋定则,朝外;
向量P2P3与P2Q,右手螺旋定则,朝外;
向量P3P1与P3Q,右手螺旋定则,朝外;

再看一组图,Q点在三角形外:
在这里插入图片描述
向量P1P2与P1Q,右手螺旋定则,朝内
向量P2P3与P2Q,右手螺旋定则,朝外;
向量P3P1与P3Q,右手螺旋定则,朝外;

极端情况,如果Q刚好在三角形的边上,例如P1P2的边上,那么,向量P1P2与P1Q为同方向,螺旋定则芭比Q了,找不到z轴方向,即,z值为0。

结论:只要计算三次叉乘,如果z值有一个为0,则在三角形边上; 如果z值正负一致,则在里面;如果z值正负不一致,则在外面

3.3 代码实现

从第一节可知,计算叉乘的 z z z值,很简单,为
( a x b y − a y b x ) (a_xb_y - a_yb_x) (axbyaybx)
所以,从程序上,可以非常简单的实现了,我们来写个python:

#!/usr/bin/python

#这是一个判断一个点是否在三角形内的例子


print("Hello, World! Let's do some test");

def check_signs(a, b, c):
    """
    判断三个浮点数的符号
    :param a: 第一个浮点数
    :param b: 第二个浮点数
    :param c: 第三个浮点数
    :return: True 如果三个数都为正数或都为负数,True 否则False
    """
    if a > 0 and b > 0 and c > 0:
        return True
    if a < 0 and b < 0 and c < 0:
        return True
    return False

def cal_z_value(v1, v2):
    """
    计算2个三维向量,叉乘的z值
    """
    return v1[0] * v2[1] - v1[1]* v2[0]

def subtract_vectors(vector1, vector2):
    """
    计算两个三维向量的差向量
    :param vector1: 第一个向量,格式为 [x, y, z]
    :param vector2: 第二个向量,格式为 [x, y, z]
    :return: 差向量,格式为 [x, y, z]
    """
    x = vector1[0] - vector2[0]
    y = vector1[1] - vector2[1]
    z = vector1[2] - vector2[2]
    return [x, y, z]

def is_point_in_triangle(p1, p2, p3, q):
    """
    判断一个点是否在某个三角形内
    """
    p1_q = subtract_vectors(q, p1)
    p1_p2 = subtract_vectors(p2, p1)
    z1 = cal_z_value(p1_p2, p1_q)

    p2_q = subtract_vectors(q, p2)
    p2_p3 = subtract_vectors(p3, p2)
    z2 = cal_z_value(p2_p3, p2_q)

    p3_q = subtract_vectors(q, p3)
    p3_p1 = subtract_vectors(p1, p3)
    z3 = cal_z_value(p3_p1, p3_q)

    print("z1 ",z1)
    print("z2 ",z2)
    print("z3 ",z3)
    return check_signs(z1, z2, z3)

"""
p1=[0, 0, 0]
p2=[0.5, 0.5, 0]
p3=[0.5, 1, 0]
q=[0.25, 0.5, 0]
"""

#测试代码
p1=[0, 0, 0]
p2=[1, 0, 0]
p3=[0.5, 1, 0]
q=[0.25, 0.35, 0]

result = is_point_in_triangle(p1, p2, p3, q)
print("result ",result)
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 向量叉乘向量的结果是一个向量,这个向量垂直于原来两个向量所在的平面,并且方向由右手定则决定。如果再用这个向量叉乘原来的其一个向量,得到的向量就是三个向量构成的体积。这个体积的大小等于原来两个向量所在平面上的平行四边形的面积,方向由右手定则决定。因此,向量叉乘向量再叉乘向量的几何意义是计算三个向量所构成的体积。 ### 回答2: 向量的叉乘是指给定两个向量,通过运算得到一个新的向量。当一个向量与另一个向量进行叉乘后再与另一个向量再次进行叉乘,这种操作的几何意义是构造一个垂直于原始平面的新向量。 具体来说,假设有向量A和向量B,根据向量的叉乘定义,得到向量C=A×B。向量C垂直于原始平面,其方向可由右手法则确定。意味着C与向量A和向量B共面,并且C的大小等于A和B所在平面的面积乘以sinθ,其θ为A和B之间的夹角。 当我们将C与向量B进行叉乘后,得到向量D=C×B。向量D不再垂直于原始平面,而是沿着A和B共线的方向。这是因为向量B的方向与向量C共面,所以向量D与向量C共线,并且其方向由右手法则确定。向量D的大小等于C和B所在平面的面积乘以sinφ,其φ为C和B之间的夹角。 因此,当一个向量与另一个向量进行叉乘后再与另一个向量再次进行叉乘时,结果向量沿着原始平面的垂直方向和共线方向分别表达了原始平面的法向量和垂直向量。这种操作可以用于计算平面的法线方向、计算两个向量构成的平面的面积,或者用于构造与多个向量共面且垂直于它们的向量。 ### 回答3: 向量的叉乘是一种在三维空间定义的运算,它用来产生一个新的向量,该向量与原来的两个向量垂直,并且符合右手法则。向量的叉乘有一个重要的几何意义,即两个向量的叉乘结果可以得到一个垂直于这两个向量所构成的平面的向量。 当我们对一个向量a叉乘向量b再叉乘向量c时,可以表示为(a×b)×c。这个结果代表了一个新的向量,它垂直于向量a×b和向量c所构成的平面。具体来说,向量a×b所表示的是一个平面,而向量c在该平面上的垂直向量,所以(a×b)×c表示了平面上的一个垂直于该平面的向量。 几何意义上来讲,向量a×b表示了由向量a和向量b所构成的平面的法向量,而(a×b)×c则表示了由向量a、向量b和向量c所构成的平面的法向量。具体来说,这个法向量垂直于这个平面并指向其一个方向。这个结果在三维几何有广泛的应用,例如计算平面的法向量、计算线段之间的夹角等。 总之,向量的叉乘向量再叉乘向量的几何意义是得到一个垂直于两个向量构成的平面的向量,它在几何上表示了这个平面的法向量,可以用来解决与平面相关的几何问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

newchenxf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值