几何处理代码集合

三维空间求两向量逆时针角度

double CCWangle(Point3D A,Point3D B,Point3D n){//A->B 沿n方向看的逆时针角度
	double a = ACOS(A ^ B / (A.Len() * B.Len()));
	Point3D C = A * B;
	double p = C ^ n;
	if (p > 0.0) a = 2 * PI - a;
	return a;
}

三维空间求线段与平面(or三角形)交点

求AB线段和三角面片(abc)的交点,并储存在re中

bool line_in_face(Point3D& a, Point3D& b, Point3D& c, Point3D& A, Point3D& B, Point3D& re) {
	//(1)求线段与面交点
	Point3D n = VectorCross(a, b, c);
	Point3D S = A - B;
	if (S ^ n == 0) return 0;//点乘 共面
	n.Normalize();S.Normalize();
	double d1 = (A - a) ^ n;
	double d2 = (B - a) ^ n;
	if (d1 * d2 > 0) return 0;//同侧 
	d1 = fabs(d1); d2 = fabs(d2);
	re = (d1 / (d1 + d2)) * B + (d2 / (d1 + d2)) * A;//re此时是与面的交点
	//(2)判断交点是否在abc内部
	Point3D AR=a-re;
	Point3D BR=b-re;
	Point3D CR=c-re;
	double angle1 = CCWangle(AR,BR,n);
	if(angle1>PI) angle1=-angle1;
	double angle2 = CCWangle(BR,CR,n);
	if(angle2>PI) angle2=-angle2;
	double angle3 = CCWangle(CR,AR,n);
	if(angle3>PI) angle3=-angle3;
	double ans=angle1+angle2+angle3;
	if(angle==0) return 0;
	return 1;
}

这里判断点是否在三角形内部使用的方法是:回转数法
另外还有一种方法是:
Z 1 = P 1 P 2 × P 1 Q Z_1=P_1P_2 \times P_1Q Z1=P1P2×P1Q
Z 2 = P 2 P 3 × P 2 Q Z_2=P_2P_3 \times P_2Q Z2=P2P3×P2Q
Z 3 = P 3 P 1 × P 2 Q Z_3=P_3P_1 \times P_2Q Z3=P3P1×P2Q
若在内部,则 Z 1 ⋅ Z 2 ⋅ Z 3 > 0 Z_1 \cdot Z_2 \cdot Z_3>0 Z1Z2Z3>0

三维空间异面直线公垂线及交点坐标求取(含共面直线交点求取)

异面直线公垂线及交点坐标求取(Q为直线 k 上一点,S为方向向量)
也能处理共面直线交点
参考思路

Point3D Get_common_perpendicular(int i,int j) {//输出公垂线在j处的交点(要求S1和S2不平行)
	Point3D Q1 = ProjV[i].first;
	Point3D S1 = ProjV[i].second;
	Point3D Q2 = ProjV[j].first;
	Point3D S2 = ProjV[j].second;
	if((S1*S2).Len()==0){
		cout<<"平行"<<endl;
		return Point3D(-1,-1,-1);
	}
	double c1 = (Q1 - Q2) ^ S2;
	double c2 = (Q1 - Q2) ^ S1;
	double a1 = S1 ^ S2;
	double b2 = -a1;
	double a2 = S1.Len2();
	double b1 = -S2.Len2();
	//double t1 = (-b2 * c1 + c2 * b1) / (a1 * b2 - a2 * b1);
	double t2 = (-a1 * c2 + a2 * c1) / (a1 * b2 - a2 * b1);
	return Q2 + t2 * S2;
}

三维空间点在平面上的投影点

Point3D Get_proj(Point3D A, Point3D n, Point3D B) {//n为平面单位法向量,平面过点B 
	double l = ((A - B) ^ n);
	Point3D S1 = A - n * l;
	return S1;
}

三维空间平面两圆交点求取

获得平面Plane上两圆交点 圆1:(A,r1) 圆2:(B,r2)
Plane:平面单位法向量n(该平面过AB)
返回交点要求与点P在AB同侧
方法参考思路

Point3D get_circle_intersection(Point3D &A,Point3D &B,double r1,double r2,Point3D &n,Point3D &P) {//获得两圆交点 圆1:(A,r1) 圆2:(B,r2) 平面单位法向量n(该平面过AB) 返回点与点P在AB同侧
	Point3D e = B - A; e.Normalize();//x轴
	Point3D k = e * n; k.Normalize();//y轴
	double d = (B-A).Len();
	if (dcmp(d) == 0) {
		cout << "error: get_circle_intersection:A B 重合!!" << endl;
		return Point3D(0, 0, 0);
	}
	double a = (d * d + r1 * r1 - r2 * r2) / (2 * d);
	if (dcmp(a * a - r1 * r1) == 0) {//相切
		cout << "error: get_circle_intersection:A B 相切!!" << endl;
		//p = A + a * e;
		return A + a * e;
	}
	if (a * a - r1 * r1 > 0.0) {//相离
		cout << "error: get_circle_intersection:A B 相离!!" << endl;
		cout << "a :" << a << " r1 :" << r1 << endl;
		return A + a * e;
	}
	//相交处理:p = A + a * e ± h * k;
	double h = sqrt(r1 * r1 - a * a);
	Point3D t = A + a * e + h * k;//交点
	//判断t是否和P在AB同一侧
	Point3D C = (B - A) * (P - A);
	Point3D D = (B - A) * (t - A);
	double q = C ^ D;
	if (q> 0.0) {
		//cout << "Get insect" << endl;
		return t;
	}
	t = A + a * e - h * k;
	//判断t是否和P在AB同一侧
	C = (B - A) * (P - A);
	D = (B - A) * (t - A);
	q = C ^ D;
	if (q > 0.0) {
		//cout << "Get insect" << endl;
		return t;
	}
	cout << "error: get_circle_intersection:两侧的点都不满足和P在一侧!!(P在AB线上)" << endl;
	return Point3D(0, 0, 0);
}

Quadric Error Mactrics

参考:
在这里插入图片描述

void testQEM() {

	vector<Eigen::Vector3d>     InputPos;//读入点
	vector<Eigen::Vector3d>     InputNormal;
	InputPos.push_back(Eigen::Vector3d(1.0, 1.0, 0.0));
	InputPos.push_back(Eigen::Vector3d(1.0, 0.0, 1.0));
	InputPos.push_back(Eigen::Vector3d(0.0, 1.0, 1.0));
	InputPos.push_back(Eigen::Vector3d(1.0, 1.0, 1.0));

	InputNormal.push_back(Eigen::Vector3d(0.0, 0.0, 1.0));
	InputNormal.push_back(Eigen::Vector3d(0.0, 1.0, 0.0));
	InputNormal.push_back(Eigen::Vector3d(1.0, 0.0, 0.0));
	InputNormal.push_back(Eigen::Vector3d(0.0, 0.0, 1.0));


	set<int> s;
	s.insert(0);
	s.insert(1);
	s.insert(2);
	s.insert(3);

	Eigen::Matrix4d Q, A;//默认列优先
	Eigen::Vector4d n, x;
	Eigen::Vector4d b(0, 0, 0, 1);
	Q = Eigen::Matrix4d::Zero();
	for (auto ite = s.begin(); ite != s.end(); ite++) {
		if (*ite == -1) continue;
		double fd = InputNormal[*ite].dot(InputPos[*ite]);
		n = Eigen::Vector4d(InputNormal[*ite].x(), InputNormal[*ite].y(), InputNormal[*ite].z(), -fd);
		Q += n * n.transpose();
	}
	A(0, 0) = Q(0, 0);
	A(1, 0) = Q(0, 1);
	A(2, 0) = Q(0, 2);
	A(3, 0) = 0.0;
	A(0, 1) = Q(0, 1);
	A(1, 1) = Q(1, 1);
	A(2, 1) = Q(1, 2);
	A(3, 1) = 0.0;
	A(0, 2) = Q(0, 2);
	A(1, 2) = Q(1, 2);
	A(2, 2) = Q(2, 2);
	A(3, 2) = 0.0;
	A(0, 3) = Q(0, 3);
	A(1, 3) = Q(1, 3);
	A(2, 3) = Q(2, 3);
	A(3, 3) = 1.0;

	Q = A.transpose() * A;
	x = Q.inverse() * A.transpose() * b;
	x /= x[3];
	cout << x << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CATIA 几何内核是三维计算机辅助设计 (CAD) 软件的核心组成部分,用于处理三维模型的几何信息。它是用来处理三维图形的数学算法的集合,可以创建、编辑、分析和渲染三维模型。 CATIA 几何内核的源代码是被保密的,不对外公开。因此,我们不能告诉您关于它的详细信息和源代码。 ### 回答2: CATIA 是一款三维计算机辅助设计(CAD)软件,它是由法国达索系统公司(Dassault Systèmes)开发的。CATIA的几何内核是由达索系统公司独立开发的,称为Geomache。该几何内核是专门用于处理三维几何模型的核心引擎,可以处理复杂的几何数据并提供各种几何操作和计算功能。 CATIA的源代码是由达索系统公司开发团队编写的,它们使用一种面向对象的编程语言(如C++)来实现CATIA的功能。源代码包含各种模块、函数和类,用于实现CATIA的各种功能,如几何建模、装配设计、曲面设计、分析和渲染等。通过这些源代码,开发人员可以对CATIA进行二次开发和定制,以满足各种不同行业和应用的需求。 CATIA的几何内核和源代码是达索系统公司的核心技术之一。通过不断的研发和创新,他们不断优化几何内核的性能和功能,并持续更新源代码以提供更好的用户体验和更强大的功能。这些技术的发展和应用促使CATIA成为了全球领先的三维设计软件之一,被广泛应用于航空航天、汽车、机械制造、船舶等领域,为用户提供高效的设计和工程解决方案。 ### 回答3: CATIA(计算机辅助三维交互应用)是一种专业的机械设计软件,由达索系统公司开发。CATIA的几何内核是由达索系统公司独立开发的CATIA V5内核。几何内核是指软件用来计算和处理物体形状和结构的部分,它负责处理CAD模型的几何拓扑表示、构建和修改。 CATIA是基于面向特征的设计(Feature-Based Design)的几何建模软件,它的内核采用了多边形网格和B样条(B-Spline)曲线等技术来描述和计算物体的形状和结构。内核主要包括了几何建模、拓扑处理、参数化建模、曲线和曲面、零件和装配体、笛卡尔坐标系等方面的功能。 对于CATIA的源代码,达索系统公司并未公开其完整的源代码。CATIA的源代码是经过专门的编程团队开发和维护的,包含了大量的算法、数据结构和函数库等。这些源代码是达索系统公司作为商业秘密保护起来的,不对外公开。 CATIA的几何内核和源代码是作为软件的核心部分,它支持CATIA的各种功能和工具,如零件设计、装配体设计、运动分析、工艺规划等。通过几何内核和源代码,CATIA可以实现高效、精确的几何计算和模型构建,为用户提供全面的机械设计解决方案。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值