计算垂直平面与三维线段交点

三维空间中垂直平面映射到xy平面是一条线段,三维线段映射到xy平面,得到两条xy平面的两条线段。

 

计算xy平面中两条线段的交点分为两部分内容:

1.判断两条线段是否相交

http://www.cnblogs.com/wuwangchuxin0924/p/6218494.html

2.计算线段的交点

这样能通过第一个条件的,计算出来的交点肯定在线段上,不会在线段延长线上。

https://blog.csdn.net/gongwenkai90/article/details/38519623

 

函数的参数:

表示垂直平面线段:seg0   线段两个端点:seg0 _P0  seg0_P1

三维空间的线段:seg1   线段两个端点:seg1 _P0  seg1_P1

交点:intersectP     计算交点的高程使用简单的线性插值

bool segmentIntersect(const osg::Vec3& seg0_P0, const osg::Vec3& seg0_P1, const osg::Vec3& seg1_P0, const osg::Vec3& seg1_P1, osg::Vec3& intersectP )
{
	//首先判断两条线段是否相交
	{
		if (!(fmin(seg1_P0.x(), seg1_P1.x()) <= fmax(seg0_P0.x(), seg0_P1.x())
			&& fmin(seg0_P0.y(), seg0_P1.y()) <= fmax(seg1_P0.y(), seg1_P1.y())
			&& fmin(seg0_P0.x(), seg0_P1.x()) <= fmax(seg1_P0.x(), seg1_P1.x())
			&& fmin(seg1_P0.y(), seg1_P1.y()) <= fmax(seg0_P0.y(), seg0_P1.y()))
			)
			return false;

		float u, v, w, z;

		u = (seg0_P0.x() - seg1_P0.x())*(seg1_P1.y() - seg1_P0.y()) - (seg1_P1.x() - seg1_P0.x())*(seg0_P0.y() - seg1_P0.y());

		v = (seg0_P1.x() - seg1_P0.x())*(seg1_P1.y() - seg1_P0.y()) - (seg1_P1.x() - seg1_P0.x())*(seg0_P1.y() - seg1_P0.y());

		w = (seg1_P0.x() - seg0_P0.x())*(seg0_P1.y() - seg0_P0.y()) - (seg0_P1.x() - seg0_P0.x())*(seg1_P0.y() - seg0_P0.y());

		z = (seg1_P1.x() - seg0_P0.x())*(seg0_P1.y() - seg0_P0.y()) - (seg0_P1.x() - seg0_P0.x())*(seg1_P1.y() - seg0_P0.y());

		if (!(u*v <= FLT_EPSILON && w*z <= FLT_EPSILON))      //排除了平行不共线
		{
			return false;
		}
	}


	//计算交点
	double a0 = seg0_P0.y() - seg0_P1.y();
	double b0 = seg0_P1.x() - seg0_P0.x();
	double c0 = seg0_P0.x()*seg0_P1.y() - seg0_P1.x()*seg0_P0.y();

	double a1 = seg1_P0.y() - seg1_P1.y();
	double b1 = seg1_P1.x() - seg1_P0.x();
	double c1 = seg1_P0.x()*seg1_P1.y() - seg1_P1.x()*seg1_P0.y();


	double D;
	D = a0*b1 - a1*b0;

	intersectP.x() = (b0*c1 - b1*c0) / D;
	intersectP.y() = (c0*a1 - c1*a0) / D;


	double zLength2_1 =(intersectP._v[0]- seg1_P0._v[0])*(intersectP._v[0] - seg1_P0._v[0]) 
		              + (intersectP._v[1] - seg1_P0._v[1])* (intersectP._v[1] - seg1_P0._v[1]);
	double zLength2_2 = (seg1_P1._v[0] - seg1_P0._v[0])*(seg1_P1._v[0] - seg1_P0._v[0])
		+ (seg1_P1._v[1] - seg1_P0._v[1])* (seg1_P1._v[1] - seg1_P0._v[1]);  


//条件1 可以保证 zLength2_2 != 0.0
	intersectP.z() = seg1_P0.z() + (seg1_P1.z() - seg1_P0.z())*sqrt(zLength2_1 / zLength2_2);

	return true;

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值