多边形裁剪圆的实现细节之求直线段与圆的交点
2015-05-25 20:23
274 查看
1.求直线段与圆的交点
(1)由线段端点P1(x1,y1)P2(x2,y2)得到线段所在直线的方程
ax+by+c=0
(2)由圆心P0(x0,y0)和半径r得到圆的方程
(x-x0)2+(y-y0)2=r2
(3)由点到圆的距离公式算出圆心到线段的距离d
(4)我先假设圆与线段有两个公共点,将线段P1P2写成参数方程形式,t为参数。
x=x1+(x2-x1)*t
y=y1+(y2-y1)*t
0<=t<=1
这里我分别持有两个公共点类的对象,含有属性x,y和t。x与y是公共点坐标信息,参数t用来表示该点即使为直线与圆公共点是否不在线段范围内。
(5)若d>r则没有公共点,我们将两个公共点对象的参数t置为不合法,这样讲不被记录为多边形与圆的公共点。
(6)若d<=r则通过圆方程与线段参数方程求解公共点坐标与参数,将参数t合法的公共点对象记录为多边形与圆的公共点。这里对于d=r的情况视为有两个相同的公共点输出。
实现表现为项目中的SegCrossoverCircle函数
(1)由线段端点P1(x1,y1)P2(x2,y2)得到线段所在直线的方程
ax+by+c=0
(2)由圆心P0(x0,y0)和半径r得到圆的方程
(x-x0)2+(y-y0)2=r2
(3)由点到圆的距离公式算出圆心到线段的距离d
(4)我先假设圆与线段有两个公共点,将线段P1P2写成参数方程形式,t为参数。
x=x1+(x2-x1)*t
y=y1+(y2-y1)*t
0<=t<=1
这里我分别持有两个公共点类的对象,含有属性x,y和t。x与y是公共点坐标信息,参数t用来表示该点即使为直线与圆公共点是否不在线段范围内。
(5)若d>r则没有公共点,我们将两个公共点对象的参数t置为不合法,这样讲不被记录为多边形与圆的公共点。
(6)若d<=r则通过圆方程与线段参数方程求解公共点坐标与参数,将参数t合法的公共点对象记录为多边形与圆的公共点。这里对于d=r的情况视为有两个相同的公共点输出。
实现表现为项目中的SegCrossoverCircle函数
void SegCrossoverCircle(MyLine line, MyCircle circle, CrossoverPoint &cp1, CrossoverPoint &cp2) { //初始化图像信息 double x1, y1, x2, y2, x0, y0, r; x1 = line.startpoint.x; y1 = line.startpoint.y; x2 = line.endpoint.x; y2 = line.endpoint.y; x0 = circle.center.x; y0 = circle.center.y; r = circle.radius; //寻找交点解参数方程 double a, b, c, a1, b1, c1, d, delta, t1, t2; a = y0 - y1; b = x1 - x0; c = x0*y1 - x1*y0; d = abs(a*x0 + b*y0 + c) / sqrt(a*a + b*b + esp); a1 = x1*x1 + x2*x2 + y1*y1 + y2*y2 - 2 * x1*x2 - 2 * y1*y2; b1 = 2 * (x0*x1 + x1*x2 + y0*y1 + y1*y2 - x0*x2 - y0*y2 - x1*x1 - y1*y1); c1 = x0*x0 + x1*x1 + y0*y0 + y1*y1 - 2 * x0*x1 - 2 * y0*y1 - r*r; delta = b1*b1 - 4 * a1*c1; //出交点 if (d <= r) { if (delta < esp) { //相切只出一个 double cos1, sin1; cp1.t = 2; t1 = (-b1 + sqrt(delta)) / (2 * a1); cp1.t = t1; cp1.x = x1 + t1*(x2 - x1); cp1.y = y1 + t1*(y2 - y1); cos1 = (cp1.x - x0) / r; sin1 = (cp1.y - y0) / r; if (abs(sin(acos(cos1)) - sin1) < esp) { cp1.a = acos(cos1); } else { cp1.a = 2 * PI - acos(cos1); } //让pt2报废不算 cp2.t = 2; } else { double cos1, sin1, cos2, sin2; t1 = (-b1 + sqrt(delta)) / (2 * a1); t2 = (-b1 - sqrt(delta)) / (2 * a1); cp1.t = t1; cp1.x = x1 + t1*(x2 - x1); cp1.y = y1 + t1*(y2 - y1); cos1 = (cp1.x - x0) / r; sin1 = (cp1.y - y0) / r; if (abs(sin(acos(cos1)) - sin1) < esp) { cp1.a = acos(cos1); } else { cp1.a = 2 * PI - acos(cos1); } cp2.t = t2; cp2.x = x1 + t2*(x2 - x1); cp2.y = y1 + t2*(y2 - y1); cos2 = (cp2.x - x0) / r; sin2 = (cp2.y - y0) / r; if (abs(sin(acos(cos2)) - sin2) < esp) { cp2.a = acos(cos2); } else { cp2.a = 2 * PI - acos(cos2); } } } else { //没交点让pt1,pt2都报废 cp1.t = 2; cp2.t = 2; } }
相关文章推荐
- 多边形裁剪圆的实现细节之求出一段圆弧的中点
- java 使用TexturePaint和Graphics2D可以实现多边形图片裁剪
- 任意多边形切割/裁剪(附C#代码实现)
- 任意多边形裁剪圆的实现思路
- ArcEngine调用GP工具实现多边形Clip裁剪功能
- android实现使用绘图作出一种裁剪任意多边形快速算法 (转自 cafelette)
- 如何在微信公众号开发中实现图片裁剪
- Android拍照及选择图片及裁剪及兼容6.0权限实现
- (转)Dubbo扩展点实现细节
- [转]Java中的Switch对整型、字符型、字符串型的具体实现细节
- [Python]croppic 裁剪图片的Python后台实现
- Android 图片裁剪功能实现详解(类似QQ自定义头像裁剪)
- 利用ffmpeg的配置configure来实现裁剪
- ImageView实现适屏和裁剪图片的功能
- 使用jquery.uploadify、jquery.Jcrop和php实现炫酷的图片裁剪
- Android弹幕实现:基于B站弹幕开源系统(3)-文本弹幕的完善和细节调整
- 简单选择排序的几种实现和细节
- Java+jquery实现裁剪图片上传到服务器
- 求两条直线的交点,运用面向对象的思想编程实现C++源码
- 17.8.19 校内赛 解题报告【求线段交点+凸包+求多边形面积】【判定点是否在多边形内】【二分答案+半平面交】