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
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 OpenSceneGraph 中,可以使用 `osg::Geometry` 类来绘制曲线。 以下是一个简单的示例代码,用于绘制一条二次贝塞尔曲线: ``` osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array; vertices->push_back(osg::Vec3(0, 0, 0)); // 起点 vertices->push_back(osg::Vec3(1, 2, 0)); // 控制点 vertices->push_back(osg::Vec3(2, 0, 0)); // 终点 osg::ref_ptr<osg::Geometry> geom = new osg::Geometry; geom->setVertexArray(vertices); osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array; colors->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0)); // 曲线颜色 geom->setColorArray(colors); geom->setColorBinding(osg::Geometry::BIND_OVERALL); osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, 100); geom->addPrimitiveSet(drawArrays); osg::ref_ptr<osg::Geode> geode = new osg::Geode; geode->addDrawable(geom); osgViewer::Viewer viewer; viewer.setSceneData(geode); viewer.realize(); viewer.run(); ``` 在这个示例中,我们首先创建了包含曲线顶点的 `osg::Vec3Array` 对象,然后将其设置为几何体的顶点数组。接着,我们创建了一个 `osg::Vec4Array` 对象来设置曲线的颜色,并将其绑定到几何体上。最后,我们创建了一个 `osg::DrawArrays` 对象来设置绘制方式,并将其添加到几何体的原语集合中。最后,我们将几何体添加到 `osg::Geode` 中,并将其设置为场景图的根节点。 你可以根据需要修改这个示例代码来绘制不同类型的曲线

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值