zoukankan      html  css  js  c++  java
  • 光线求交-面、三角形、球 (Ray intersection)

    光线求交

    • 光线定义:position (a(t)) = (o) + (tvec{d});
    • 球定义: center p, radius r;
    • 平面定义:normal (vec{n}) , offset t;
    • 三角形定义:position (a_1), (a_2), (a_3), normal (vec{n});

    光线与球相交 (Ray/Sphere Intersection)


    c++代码 :

    bool HitTest(const Ray& ray, HitTestResult* result)
    {
    	Vector eo = Center - ray.Position;
    	float v = eo * ray.Direction;
    	auto disc = Radius * Radius - (eo * eo) + v * v;
    	if (disc < 0) return false;
    	disc = v - sqrt(disc);
    	if (disc < 0.001f || disc >= ray.MaxDistance) return false;
    	result->Shape = const_cast<Sphere*>(this);
    	result->Normal = (disc * ray.Direction - eo).Normalize();
    	result->Distance = disc;
    	return true;
    }
    

    光线与平面相交 (Ray / Plane Intersection)

    线与平面相交 Ray/Plane Intersection
    平面在空间几何中可以用一个向量(法向量)和平面中的一点P0来表示。

    平面就是满足下式的点集:(vec{n}(vec{P}-vec{P_0})= 0)

    得到:(vec{n}cdotvec{P}=d); (d=vec{n}cdotvec{P_0});

    给定射线r(t) = o +td,平面方程为n.p+d=0,将p(t)带入到平面方程,最后求得t:

    (t = (-d-(vec{n}cdotvec{p_0}))/(vec{n}cdotvec{d}))


    c++代码:

    bool HitTest(const Ray& ray, HitTestResult* result)
    {
    	auto denom = Normal * ray.Direction;
    	if (denom > 0) return false;
    	auto d = (Normal * ray.Position + Offset) / (-denom);
    	if (d >= ray.MaxDistance) return false;
    	result->Shape = const_cast<Plane*>(this);
    	result->Normal = Normal;
    	result->Distance = d;
    	return true;
    }
    

    光线与三角形相交 (Ray/Triangle Intersection)

    • 判断射线是否与平面相交
    • 判断点是否在三角形内
    //构造函数:
    Triangle(const Vector& Point1, const Vector& Point2, const Vector& Point3)
    		: Point1(Point1), Point2(Point2), Point3(Point3)
    {
    	auto n1 = Point2 - Point1;
    	auto n2 = Point3 - Point1;
    	normal = Vector::Cross((Point2 - Point1), (Point3 - Point1)).Normalize();
    }
    	
    bool HitTest(const Ray& ray, HitTestResult* result)
    {
    	float eo;
    	if (normal.Length() != 0 && (eo = ray.Direction * normal) < 0)
    	{
    		auto S = (Point1 - ray.Position) * normal / eo;
    		if (S < 0.001f || S >= ray.MaxDistance)
    			return false;
    
    		auto V = S * ray.Direction + ray.Position;
    
    		if (IsInner(V))
    		{
    			result->Shape = const_cast<Triangle*>(this);
    			result->Normal = normal;
    			result->Distance = S;
    			return true;
    		}
    		return false;
    	}
    	return false;
    }
    

    另一种方法:[用三角形重心求交

  • 相关阅读:
    腾讯云Windows Server下nodejs websocket ssl配置
    Windows下运行MapReduce程序出现Could not locate executable nullwinutils.exe in the Hadoop binaries.
    2.4寒假学习记录
    2.3寒假学习记录
    2.2寒假记录
    2.1日寒假学习记录
    DFA敏感词过滤实现
    手机号和邮箱合法性验证+焦点事件
    复选框显示隐藏
    table+分页+模糊查询
  • 原文地址:https://www.cnblogs.com/yoyo-sincerely/p/8401861.html
Copyright © 2011-2022 走看看