C-8 圆、圆弧与平面

C-8 圆、圆弧与平面

圆的定义

  • 定义圆心以及半径就可以了

圆弧的定义

  • 定义圆心、起始点和结束点
  • 起始点和结束点到圆心的距离必须要一样
  • 连接方式一般是逆时针连接(一般来说外轮廓是逆时针连接,内轮廓是顺时针)

在这里插入图片描述

平面的定义

  • 平面定义有很多方式,最常用的是定义平面上的一个点和平面的法向量,occ也采用这样的定义方式
  • 当然也可以定义平面上不共线的三个点来定义平面
  • 以下是利用occ的接口进行定义
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <gp_Dir.hxx>

// 定义原点和法向量
gp_Pnt origin(0.0, 0.0, 0.0); // 原点
gp_Dir normal(0.0, 0.0, 1.0); // 法向量
// 创建平面
gp_Pln plane(origin, normal);

线与圆的位置关系,相切、相离、相交

  • 这个问题就是点与线的问题,求圆心与线的距离,并和半径进行判断是否相切、相离、相交
  • 和某个点是否落在圆内这一问题等价

离散化圆弧,将某段圆弧离散化为一段段的线段

//输入的是向量的两个点,求该向量与x轴的角度,角度大小是0到2*pi
double angle(Point center,Point point) {
	if (center == point) return -1;
	double	theangle = asin((point.y - center.y)/point.distance(center));
	//第一象限不用处理
	if ((point.x - center.x) >= 0) {
		if (theangle < 0) theangle = theangle + M_PI*2;//第四象限

	}
	else {
		 theangle = M_PI - theangle;//第二,第三象限
		
	}
	return theangle;
}
//给定角度与需要离散化的段数n对圆弧进行离散化
std::vector<Point> discret(Point Arc_center, double r, double angle_begin, double angle_end, int n) {
	std::vector<Point> Points;
	if (abs(angle_begin - angle_end)<0.01) return Points;
	//std::cout << angle_begin << "," << angle_end << std::endl;
	double small_angle = (angle_end - angle_begin) / n;
	
	for (int i = 0; i <= n; i++) {
		Point p(Arc_center.x+r * std::cos(angle_begin + small_angle * i), Arc_center.y + r * std::sin(angle_begin + small_angle * i), Arc_center.z );
		Points.push_back(p);
	}
	return Points;
}

//输入圆弧的圆心与起始点、结束点
std::vector<Point> discret(Point Arc_center, Point Arc_begin,Point Arc_end) {
	int n = 16; 
	if (Arc_begin == Arc_end) return discret(Arc_center, Arc_center.distance(Arc_begin), 0, 2 * M_PI, n);


	double angle_begin = angle(Arc_center, Arc_begin);
	double angle_end = angle(Arc_center, Arc_end);
    //分两种情况,要是结束点的角度比起始点大,就按部就班的离散化
    //若结束角度比起始角度小,那就分割成两端离散化,一段是起始点到2*pi点,以及2*pi点到结束点
	if(angle_end>angle_begin) return discret(Arc_center, Arc_center.distance(Arc_begin), angle_begin, angle_end, n);
	else if (angle_end < angle_begin) {
		
		double r = Arc_center.distance(Arc_begin); 
		std::vector<Point> Points1 = discret(Arc_center , r , angle_begin, 2 * M_PI, n / 2); 
		std::vector<Point> Points2 = discret(Arc_center , r , 0          ,angle_end, n / 2);
		   if(Points1.size()>0) Points1.pop_back();
			Points1.insert(Points1.end(), Points2.begin(), Points2.end());
			
		return Points1;
		
	}

}
  • 利用该代码进行离散化绘制的圆弧
  • 外围是利用clipper生成的轮廓线

在这里插入图片描述

圆与直线的交点

  • 利用参数直线和参数圆进行求交
//求由线段延伸的直线与圆的交点,且该交点是离该线段较近的一个点
//p1,p2是线上面的两个点
Point circleLineIntersection(Point center, double radius, Point p1, Point p2) {
	double a = p1.x * p1.x + p2.x * p2.x - 2 * p1.x * p2.x + p1.y * p1.y + p2.y * p2.y - 2 * p1.y * p2.y;

	double b = -2 * center.x * p1.x + 2 * center.x * p2.x + 2 * p1.x * p2.x - 2 * p2.x * p2.x - 2 * center.y * p1.y + 2 * center.y * p2.y + 2 * p1.y * p2.y - 2 * p2.y * p2.y;

	double c = center.x * center.x + center.y * center.y + p2.x * p2.x - 2 * center.x * p2.x + p2.y * p2.y - 2 * center.y * p2.y - radius * radius;

	double d = b * b - 4 * a * c;

	double t = (-b + sqrt(d)) / (2 * a);

	if (t < 1 && t>0) {
		Point p(p1.x * t + p2.x * (1 - t), p1.y * t + p2.y * (1 - t), 0);
		return p;
	}
	else {
		t = (-b - sqrt(d)) / (2 * a);
		Point p(p1.x * t + p2.x * (1 - t), p1.y * t + p2.y * (1 - t), 0);
		return p;
	}
}

其余问题

  • 两个圆的位置关系,如果相交、相切如何求交点?

    • 相切的话很容易求交点
    • 相交的话利用参数圆求交点
  • 点A在平面内还是平面上,平面下?

    • 利用法向量和起始点到点A的向量进行点乘。若是等于0就在平面上,若是小于0就在平面下,若是大于0就是平面上
  • 除圆之外还有三维的球,球和平面的截面圆如何计算等等。

相切的话很容易求交点

  • 相交的话利用参数圆求交点

  • 点A在平面内还是平面上,平面下?

    • 利用法向量和起始点到点A的向量进行点乘。若是等于0就在平面上,若是小于0就在平面下,若是大于0就是平面上
  • 除圆之外还有三维的球,球和平面的截面圆如何计算等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值