几何向量(6):二维点与直线

这一篇是几何向量的扩展篇之一,因为后面要讲到的CG技术需要这一篇的数学基础,所以额外开一篇进行讲解。


       这次我们就观察学习二维中点与直线的重要关系,垂线或者说图形学中的法线,因为这和后续的反射向量、光追计算、镜面计算等有很大依赖关系,比如说我们有一个顶点P处于一块二维镜面前,求这个顶点P在二维镜面中的倒影顶点P',这就需要求出顶点P到镜面所处的直线L的垂线及距离了,如下图:


image.png

 首先确定镜面直线L的方程:A*x+B*y+C = 0,这个方程怎么来的呢?无非就是一元一次方程y = K*x+B的另一种写法形式,具体如下:

image.png

  那么接下来我们已知一个顶点P(x0,y0),想求出顶点P在镜面直线L中的倒影P'(x',y'),我们连接P和P'得到的新直线垂直于直线L,同时相交点为P1(x1,y1),那么我们先起码得求出新直线L'的方程,求法如下:

8379.png这里有一个关键的斜率的问题,我们把直线L方程y = K*x + B中K称为斜率,意思就是以单位圆为参考,直线与x坐标轴的夹角θ的正切值,也就是tanθ,那么直线L的垂线L'的斜率就是-1/k,如下图:

image.png

我们抛开平移不谈,只谈y和x的比例K也就是斜率符合三角函数中正切值tan的定义。

       这里我们就总结一下,我们已经把垂线L'方程和相交点P1得到了,如下图:

image.png

接下来就是求解倒影点P'的坐标公式了,无非就是根据向量相等去计算,如下图:

1986.png

  推到这里基本没什么问题了,最后为了程序实现,我们顺便写上根据两已知顶点求直线的公式,这里我们通过上面讲的斜率方法推导,如下图:

6940.png

  求直线的方程无非就是求动点P的坐标公式。

       最后我们就来程序模拟了,假设我有一条随时变化的镜面直线L,镜面直线L前方有一个物体P,求物体P在镜面中倒影P',模拟程序如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ReflectObject : MonoBehaviour
{
    public LineRenderer mLineRender;
 
    public Transform mMirrorPosA;
    public Transform mMirrorPosB;
 
    public Transform mObjectP;
    public Transform mObjectPInvert;
 
    private float mA;
    private float mB;
    private float mC;
    private Vector3 mInvertPos;
 
    void Start()
    {
 
    }
 
    void Update()
    {
        //计算镜面直线的方程参数,A*x + B*y + C = 0
        //根据之前推导的方程我们可以得出
        mA = mMirrorPosB.position.y - mMirrorPosA.position.y;
        mB = mMirrorPosA.position.x - mMirrorPosB.position.x;
        mC = mMirrorPosB.position.x * mMirrorPosA.position.y - mMirrorPosA.position.x * mMirrorPosB.position.y;
        //同样根据之前推导的倒影点P'坐标公式计算出坐标参数
        float x0 = mObjectP.position.x;
        float y0 = mObjectP.position.y;
        float x = (mB * mB * x0 - 2 * mA * mB * y0 - 2 * mA * mC - mA * mA * x0) / (mA * mA + mB * mB);
        float y = (mA * mA * y0 - 2 * mA * mB * x0 - 2 * mB * mC - mB * mB * y0) / (mA * mA + mB * mB);
        float z = 0;
        mInvertPos = new Vector3(x, y, z);
        mObjectPInvert.position = mInvertPos;
        //给镜面直线画个linerender方便显示
        mLineRender.positionCount = 2;
        mLineRender.SetWidth(0.2f, 0.2f);
        mLineRender.SetPosition(0, mMirrorPosA.position);
        mLineRender.SetPosition(1, mMirrorPosB.position);
    }
}

       代码很简单,我只进行了简单的注释,无非就是通过上面推导的公式进行模拟,效果图如下:

307.gif

   讲到这里,这一篇博客的目的就达到了,后面我们继续深入,在立体几何中进行讲解点与面的关系,最终实现我们想要的真实反射和光追。

   so,我们接下来继续。




————————————————

版权声明:本文为CSDN博主「羊羊2035」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/yinhun2012/article/details/83717347



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864