osg 两个面求交线

面用osg::Matrix  来表示。

osg::Vec3 ptOri = osg::(0,0,0) * mat;(面的原点)

osg::Vec3 vecX = mat.getRotate() * osg::X_AXIS ;(X轴)

osg::Vec3 vecY = mat.getRotate() * osg::Y_AXIS ;(Y轴)

要求两个面的交线,首先要判断两个面是否相交,方法是判断两个面的Z轴夹角,如果夹角差不多为0或者Pi那么认为面不想交,没有相交。


<pre name="code" class="cpp">double AngleTo(const osg::Vec3d &vec1, const osg::Vec3d&vec2)
{
	assert(vec1.length() > 1.E-7 && vec2.length() > 1.E-7);

	osg::Vec3d v1 = vec1, v2 = vec2;
	v1.normalize();
	v2.normalize();
	double dTemp = (v1 * v2) / (v1.length() * v2.length());
	if (dTemp > 1.0)
	{
		dTemp = 1.0;
	}
	if (dTemp < -1.0)
	{
		dTemp = -1;
	}
	return acos(dTemp);
}


int Intersect3dLineSegmentWithPlane( const osg::Vec3d &lineStartPoint, const osg::Vec3d &lineEndPoint, 
				const osg::Vec3d &planeNormal, const osg::Vec3d &planePoint, osg::Vec3d &intPoint )
{
	osg::Vec3d other = lineEndPoint - lineStartPoint;
	osg::Vec3d vector2 = lineStartPoint - planePoint;
	double num = planeNormal * other;
	double num2 = -planeNormal * vector2;
	if (fabs(num) < 1.0E-6))
	{
		if (num2 == 0.0)
		{
			return 2;
		}
		else
		{
			return 0;
		}
	}

	double num3 = num2 / num;
	if ((num3 < 0.0) || (num3 > 1.0))
	{
		return 0;
	}

	intPoint = lineStartPoint + other * num3;
	return 1;
}

// 描述:	求两个面的交线 
// matBase:一个面的位置矩阵
// matThis: 另外一个面的位置矩阵
// pt1: 交线点1	(世界坐标系)
// pt2: 交线点2 (世界坐标系)
// dTolAngle: 面夹角容差(如果两个面夹角小于等于这个值,那么认为面平行)
// 返回值:是否相交
bool IntersectWith( const osg::Matrix &matBase, const osg::Matrix &matThis,
				   osg::Vec3d &pt1, osg::Vec3d &pt2, double dTolAngle /*= osg::PI / 36.0*/ )
{
	bool bOk = false;
	osg::Vec3d vecZThis = matThis.getRotate() * osg::Z_AXIS;
	osg::Vec3d vecZBase = matBase.getRotate() * osg::Z_AXIS;
	double dAngle = AngleTo(vecZThis, vecZBase);
	if ( dAngle - osg::PI_2 > 1.0E-7)
	{
		dAngle = osg::PI - dAngle;
	}
	// 判断方向 
	if (dAngle - dTolAngle > 1.0E-7)
	{
		osg::Vec3d vecLine = vecZBase ^ vecZThis;	// 两个面相交线向量
		osg::Vec3d vecLineInThis = matThis.getRotate().inverse() * vecLine;	// 到自身坐标系里
		// 相交线垂直的向量
		osg::Quat quat;
		quat.makeRotate(osg::PI_2, osg::Z_AXIS);
		vecLineInThis = quat * vecLineInThis;
		double dLength = 10000.0;
		osg::Vec3d pt1InThis = vecLineInThis * dLength;
		osg::Vec3d pt2InThis = -pt1InThis;
		// 变换到世界坐标系
		pt1InThis = pt1InThis * matThis;
		pt2InThis = pt2InThis * matThis;

		// 计算这条垂线和基本面的交点
		osg::Vec3d ptRet;
		osg::Vec3d ptOri = osg::Vec3d(0,0,0) * matBase;
		int iRet = Intersect3dLineSegmentWithPlane(pt1InThis, pt2InThis, vecZBase, ptOri, ptRet);
		assert(iRet == 1);

		// 然后根据交线向量求出两个点来
		pt1 = ptRet + vecLine * dLength;
		pt2 = ptRet - vecLine * dLength;
		bOk = true;
	}
	return bOk;
}


 



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TheDeaf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值