`
izuoyan
  • 浏览: 9221857 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

从零实现3D图像引擎:(8)参数化直线与3D平面函数库

阅读更多

1. 数学分析

1) 参数化直线

还记得我们在学习向量时介绍的位移向量吗?参数化直线的原理和他相同。其实所谓参数化直线,就是通过一个参数t来表示直线上的一个线段,当t为0时,则取线段的一端的端点,当t取1时,则取到另一端的端点。如图:

位移向量与参数化直线

核心原理就是向量加法的几何意义,Vd是加数,通过t(从0到1)去乘以这个Vd,则可以描述向量p,而p在某个t时的坐标值,就是从点P1到点P2的线段在t时的坐标值。注意这里我们使用的是图中的p = p1 + t * vd,这样t的取值是0到1,如果是p = p1 + t * v',那t的取值就是0到|Vd|,还需要去先算|Vd|,没有必要这么做,而且0和1是特殊的数字,运算方便。

所以参数化方程为:P(x,y,z) = p0 + v*t

我们为什么要用参数化的形式表示线段呢,因为在求两个线段的交点时,只要求两个参数方程组成的方程组,并求出t1和t2,只要他们都在0到1之间,那么就可以知道他们是有交点的。比如:

线段1:

x = 1 + 2*t1;

y = 3 + 4*t1;

线段2:

x = 5 + 6*t2;

y = 7 + 8*t2;

四个方程,四个未知数,可求得t1,t2,如果他们都在0和1之间,那他们相交。

具体怎么求?忘记上一章所讲的求逆矩阵的吗?要先算出行列式,然后。。。

注意,这里我们有很多的情况还没有考虑,比如:

1. 两条直线平行,没有交点

2. 两条线段在同一直线上,但互不重叠

3. 两条线段在同一直线上,部分重叠

4. 两条线段在同一直线上,只有一点重叠

在我的实现函数中,我把这4种特殊情况都看做是不相交或者说是无意义,当他们平行或共线时都会返回回传码0。因为这时计算出来的t1和t2以及交点都是没有任何意义的。

2) 3D平面

我们如何定义一个3D平面呢,看下图:

3D平面

如果你认真看图了,那么无需我多说了,只要有一个点P0,和平面的法线向量n,就可以确定一个平面了。

定义:对于空间中的任意一点P,如果线段P->P0与法线向量n垂直,则点P在平面上。

还记得向量点积吗?其最最重要的性质就是其几何意义:可以确定两个向量之间的夹角。当两个向量的点积为0时,这两个向量互相垂直。

所以:n.(P->P0) = 0

展开:<a, b, c> . <x-x0, y-y0, z-z0> = 0

最终,可以拿到平面的点-法线表示的形式:a*(x-x0) + b*(y-y0) + c(z-z0) = 0

我们可以另d = (-a*x0 - b*y0 - c*z0)

那么上面的形式可以化为:

a*x + b*y + c*z + d = 0

这个就是3D平面的通用形式,以通用形式计算两个平面之间的交线非常方便。

再扩展一下思维,就可以知道,对于任意一点<x,y,z>,a*(x-x0) + b*(y-y0) + c(z-z0)的值与0的关系,可以判断出,这个点在平面的哪一边。而这个性质则非常非常的重要,我打算先举个实例再给出答案。

还是参照上图,这是个特殊的平面,是X-Z平面,所以法线向量n为<0,1,0>,平面上的一点,我们选原点<0, 0, 0>,那么现在我们来取任意一点,比如(5, 5, 5),那么把这些数据代入a*(x-x0) + b*(y-y0) + c(z-z0),得:

1*(5-0) = 5 > 0,所以点(5, 5, 5)在平面的正方向。

再取点(5, -5, 5),则1*(-5-0) = -5 < 0 ,所以点(5, -5, 5)在该平面的负方向。

因为这个概念经常要用到,所以在举了一点的例子之后我想再通过理论证明一下,请看下图:

点与平面关系推导

这幅图是上图的平面版,其实任意一个3D点与平面的关系都可以找到这样一个角度来看。这里的X轴就是X-Z平面的水平视角中的线,Y轴的正半轴就是这个平面的法线向量,这个图左上提示了大家,u.v = |u| * |v| * Cos(theta)。左下角则根据向量范数的求法,给出了u.v是否大于0,取决于Cos(theta)的结果。图上4种颜色的点,标出了任意一点可能在平面附近的位置。还记得余弦函数线吗?不多说了。到此我们已经证明了在任意3D卦限的某点,与某3D平面,计算u.v > 0 则在平面正方向,u.v < 0 则在负方向。

3) 参数化直线与3D平面的交点

其实就是解方程组,把直线方程和3D平面方程放在一起进行简化。

参数化直线:

x = x0 + vx * t

y = y0 + vy * t

z = z0 + vz * t

其中x0, y0, z0为参数化直线上一直的一点

3D平面:

a*x + b*y + c*z + d = 0

a = nx

b = ny

c = nz

d = -nx*x0' -ny*y0' - nz*z0'

其中x0', y0', z0'是3D平面上已知的一点,所以加了'来区分直线上已知的一点

将这几个方程代入做整理变换可以得到t的表示形式:

t = -(a*x0 + b*y0 + c*z0 + d) / (a*vx + b*vy + c*vz)

通过这个t就可以知道线段与平面是否存在交点了,不用我再说了吧,看t是不是在0和1之间即可。

这几个方程也可以表示出x, y, z,即交点的坐标:

x = x0 + vx*t

y = y0 + vy*t

z = z0 + vz*t

哈哈,其实不就是把t代回原线段的形式了么。。。

2. 代码实现

1)结构定义

首先我们定义表示参数化直线和3D平面的结构:

2) 常用函数实现

3. 代码下载

完整项目代码下载:>>点击进入下载页<<

分享到:
评论

相关推荐

    基于最小二乘法的平面拟合,图像背景去除

    本文将深入探讨如何使用基于最小二乘法的平面拟合技术来实现这一功能,以及如何结合OpenCV库来完成这一过程。 首先,我们要理解最小二乘法(Least Squares Fitting)的基本原理。在数学上,最小二乘法是一种优化...

    Hough直线变换自己实现

    在参数空间(m-c空间)中,每一点对应图像平面上的一条直线,通过为图像中的每个像素点对参数空间进行投票,可以找到那些获得高票数的点,这些点对应的直线就是图像中最可能存在的直线。 实现Hough变换的步骤如下:...

    线结构光平面方程自动标定

    标题“线结构光平面方程自动标定”涉及的是计算机视觉...总的来说,这个项目的目标是建立一个自动化系统,能够准确地从线结构光图像中提取平面信息,这对于工业自动化、机器人导航、精密测量等领域具有重要的应用价值。

    三线法相机标定

    三线法相机标定基于三个非共面的直线在图像平面上的投影。在理想情况下,这些直线在三维空间中是相互平行的,但在二维图像上则表现为交于一点的射影。通过解这个几何问题,可以推导出相机的内参矩阵和外参矩阵。 1....

    基于android opencv图片相似度计算结构相似性感知哈希算法轮廓直线检测圆检测直线交点旋转角度矫正图像匹配灰度.zip

    在Android平台上,使用OpenCV库进行图像处理是一个常见的选择,特别是在进行高级图像分析任务时,如图片相似度计算、结构相似性检测、感知哈希算法、轮廓检测、直线和圆的识别、直线交点计算、图像旋转角度矫正以及...

    python实现SVM图像识别分类

    在实现过程中,我们需要注意数据预处理,如归一化特征,以及选择合适的参数进行调优,如C(惩罚参数)和γ(RBF核的宽度)。交叉验证可以帮助我们找到最佳参数组合。 本项目中的代码示例将详细展示这些步骤,通过...

    my code1_拟合角平分线_直线识别_

    6. **Matlab编程**:作为实现这些算法的工具,Matlab提供了丰富的图像处理函数库,如`imread`、`imwrite`、`im2bw`、`edge`、`hough`、`houghpeaks`、`houghlines`、`ransac`等,使得图像处理任务变得相对简单。...

    Cabri_3D作图工具

    例如,你可以轻松地绘制平面直线、圆、锥、球等基本形状,也可以通过旋转、平移、缩放等操作自由变换这些图形,实现对三维空间的直观把握。 二、交互式探索与动画功能 软件的交互性是其一大亮点。用户可以实时调整...

    光剑程序 hough直线检测法

    为了实现这个程序,开发者通常会使用如OpenCV这样的计算机视觉库,因为它提供了丰富的函数来实现上述步骤。通过编程,我们可以将Hough变换应用于实时视频流或静态图像,实现动态的光剑追踪。 总之,Hough直线检测法...

    基于OPENCV与VS2010实现对相机畸变参数的计算与标定

    本文将详细探讨如何使用OpenCV库与Visual Studio 2010(VS2010)来计算并校正相机的畸变参数,从而提高图像的准确性。首先,我们来看一下相机畸变是什么。 相机畸变是指由于镜头和传感器的物理特性,导致真实世界的...

    opencv之霍夫变换-直线实例下载

    而在霍夫变换中,我们转而考虑极坐标系统,即每条直线可以由两个参数ρ和θ来描述,ρ是从原点到直线的距离,θ是该距离与X轴之间的角度。通过在极坐标系中累加这些点,我们可以找到那些积累量达到阈值的ρ和θ值,...

    SVM-classification-localization-master_svm图像分类_svm图像分类_daily167_

    3. SVM模型训练:利用Python的Scikit-learn库或者其他SVM实现(如libSVM),选择合适的核函数(如线性核、多项式核、RBF核等)和参数,训练SVM模型。 4. 分类与评估:用训练好的模型对测试集进行预测,通过准确率、...

    Python-一个单文件Python库用于生成SVG格式的3D线框

    8. **用户交互**:虽然未明确提及,但该库可能还支持用户输入参数,例如旋转角度、缩放比例等,以实现3D视图的调整。 在使用这个库时,开发者可能需要首先导入库,然后创建3D几何对象,指定其位置和形状,接着调用...

    基于libsvm的图像分割

    6. 评估与优化:使用评价指标(如精度、召回率、F1分数等)评估分割效果,并根据评估结果调整参数,如核函数类型、惩罚系数C、软间隔参数等,以优化模型性能。 总之,基于libsvm的图像分割利用了SVM的强大分类能力...

    最小二乘法-使用Python实现的基于最小二乘法优化图像重影.zip

    这个方法尤其适用于解决线性回归问题,即寻找一条直线(或更高维度的超平面)来最好地描述两个或多个变量之间的关系。 在图像处理中,图像重影可能由相机抖动、光学系统缺陷或其他因素引起。最小二乘法可以用于校正...

    高三理科数学下册月考试卷(七)[精选].doc

    以上知识点覆盖了高中理科数学中的多个核心概念,包括集合论、数列、复数、空间几何、概率统计、函数与导数、平面几何、立体几何、数列求和、函数图像变换、不等式解法、向量运算、椭圆性质、三角函数等,这些都是...

    分形图像的c++程序和图像

    4. **图像处理库**:为了将分形数据转换为可视化图像,这些程序可能利用了如OpenCV或SFML这样的图像处理库,它们提供了在C++中绘制像素和保存图像的功能。 5. **颜色映射**:分形图像的美观之处在于其色彩的丰富性...

    Hough变换

    2. **初始化参数空间**:创建一个二维数组(ρ-θ平面),数组的大小取决于预期检测直线的最大长度和角度范围。 3. **投票过程**:遍历图像中的每一个白色像素点,对于每个点,在参数空间的ρ-θ平面上进行投票。...

Global site tag (gtag.js) - Google Analytics