光线投射(Raycasting)原理详解
首先光线投射(Raycasting)是一种基本的计算机图形学技术,用于检测和处理三维空间中的对象。它通过在场景中投射一条或多条光线,确定这些光线与场景中物体的交点,从而实现渲染、碰撞检测、路径规划等任务。下面将详细介绍光线投射的原理及其在各种应用中的实现方法。
基本原理
光线投射的核心思想是从视点(或相机)发射光线,沿着光线方向检查它们是否与障碍物点重合,可以用做Line of sight的判断。
碰撞检测
光线投射在碰撞检测中用于检测光线与物体的相交情况,以确定物体之间是否发生碰撞。以下是光线投射碰撞检测的具体步骤:
- 光线定义:
光线由一个起点和一个方向向量定义。数学表达式为:R(t) = O + t * D
R(t) 是光线的点。
O是光线的起点。
D是光线的方向向量。
t是参数,表示光线在方向向量上的位移。 - 物体表示:
使用几何体(如球体、平面、AABB等)表示场景中的物体。 - 相交检测算法:
对每个物体,使用相应的相交检测算法,判断光线是否与物体相交。
常用的相交检测算法包括:
光线与球体相交检测。
光线与平面相交检测。
光线与AABB相交检测。 - 碰撞处理:
如果光线与物体相交,记录相交点和表面法线。
根据碰撞情况,执行相应的处理操作,如反弹、阻挡等。
这是定义raycast类的头文件,后面会着重介绍一下里面的几个函数
raycast.h
#ifndef RAYCAST_H_
#define RAYCAST_H_
#include <Eigen/Eigen>
#include <vector>
//符号函数,用于返回x的符号(正数返回1,负数返回-1,零返回0)。
double signum(double x);
//模运算函数,返回value除以modulus的余数,处理了负数情况。
double mod(double value, double modulus);
//计算并返回沿某一方向(由ds指示)从s出发,到达下一个整数边界所需的距离。
double intbound(double s, double ds);
//这里提供了两个重载的射线投射函数,用于计算从start到end点的射线与由min和max定义的轴对齐边界框(Axis-Aligned Bounding Box, AABB)的交点。
//第一个函数将交点存储在预分配的数组中,而第二个函数使用std::vector<Eigen::Vector3d>动态存储交点。
void Raycast(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const Eigen::Vector3d& min,
const Eigen::Vector3d& max, int& output_points_cnt, Eigen::Vector3d* output);
void Raycast(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const Eigen::Vector3d& min,
const Eigen::Vector3d& max, std::vector<Eigen::Vector3d>* output);
/*
这个头文件定义了用于射线投射(Raycasting)的一系列函数和RayCaster类。
射线投射是计算机图形学和机器人领域中的一个常用技术,它模拟从一个起点沿特定方向发射的“射线”,并计算这条射线与场景中对象的交点。
这个技术在视觉模拟、地形分析、碰撞检测等多个领域都有应用。以下是对提供的代码及其功能的详细解释:*/
class RayCaster {
private:
/* data */
//包括射线的起点、终点、方向,以及遍历过程中的当前位置、步长、最大距离等。
Eigen::Vector3d start_;
Eigen::Vector3d end_;
Eigen::Vector3d direction_;
Eigen::Vector3d min_;
Eigen::Vector3d max_;
int x_;
int y_;
int z_;
int endX_;
int endY_;
int endZ_;
double maxDist_;
double dx_;
double dy_;
double dz_;
int stepX_;
int stepY_;
int stepZ_;
double tMaxX_;
double tMaxY_;
double tMaxZ_;
double tDeltaX_;
double tDeltaY_;
double tDeltaZ_;
double dist_;
int step_num_;
// 分辨率和偏移量
double resolution_;
Eigen::Vector3d offset_;
Eigen::Vector3d half_;
public:
RayCaster