算法(一) 两圆公切线

经检测,如下公式能做出左右方向的梯形图形。

function getPointBySq(startX,startY,startW,endX,endY,endW){
	var ED=sqr(distance(startX,startY,endX,endY))-sqr(endW-startW);
		var a=4*(sqr(startY-endY)+sqr(startX-endX));
		var b=4*(
				(
					sqr
						(
							endX-startX
						)+sqr
						(
							startW
						)-(
							sqr(
							endW
							)+ED
						)-sqr(
							endY
						)+sqr(
							startY
						)
					)*(endY-startY)-2*sqr(endX-startX)*startY
				);
		var c=sqr(sqr(endX-startX)+sqr(startW)-sqr(endW)-ED-sqr(endY)+sqr(startY))-4*sqr(endX-startX)*(sqr(startW)-sqr(startY));
		var y1=(-b- Math.sqrt(sqr(b)-4*a*c))/(2*a);
		var y2=(-b+ Math.sqrt(sqr(b)-4*a*c))/(2*a);
		var x1=Math.sqrt(sqr(startW)-sqr(y1-startY))+startX;
		var x2=Math.sqrt(sqr(startW)-sqr(y2-startY))+startX;
		var twoPoint=[[x1,y1],[x2,y2]];
		return twoPoint;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
ACM 很全的计算几何模板 基础部分 1.几何公式 5 1.1三角形 5 1.2四边形 5 1.3正n边形 5 1.4 5 1.5棱柱 6 1.6棱锥 6 1.7棱台 6 1.8柱 6 1.9锥 6 1.10台 7 1.11球 7 1.12球台 7 1.13球扇形 7 2.直线与线段 7 2.0预备函数 7 2.1判三点是否共线 8 2.2判点是否在线段上 9 2.3判断两点在线段的同一侧 9 2.4判断两点是否在线段的异侧 9 2.5求点关于直线的对称点 10 2.7判断两线段是否相交 10 2.7.1常用版 10 2.7.2不常用版 11 2.8 求两条直线的交点 11 2.9点到直线的最近距离 12 2.10点到线段的最近距离 12 3.多边形 12 3.0 预备浮点函数 12 3.1判定是否是凸多边形 13 3.2判定点是否在多边形内 14 3.3 判定一条线段是否在一个任意多边形内 15 4. 三角形 16 4.0预备函数 16 4.1求三角形的外心 17 4.2求三角形内心 17 4.3求三角形垂心 17 5. 18 5.0预备函数 18 5.1判定直线是否与相交 19 5.2判定线段与相交 19 5.3判相交 19 5.4计算上到点p最近点 19 5.5计算直线与的交点 20 5.6计算两个的交点 20 6. 球面 21 6.0给出地球经度纬度,计算心角 21 6.1已知经纬度,计算地球上两点直线距离 21 6.2已知经纬度,计算地球上两点球面距离 21 7. 三维几何的若干模板 22 7.0预备函数 22 7.1判定三点是否共线 23 7.2判定四点是否共面 23 7.1判定点是否在线段上 23 7.2判断点是否在空间三角形上 24 7.3判断两点是否在线段同侧 24 7.4判断两点是否在线段异侧 25 7.5判断两点是否在平面同侧 25 7.6判断两点是否在平面异侧 25 7.7判断两空间直线是否平行 25 7.8判断两平面是否平行 26 7.9判断直线是否与平面平行 26 7.10判断两直线是否垂直 26 7.11判断两平面是否垂直 26 7.12判断两条空间线段是否相交 27 7.13判断线段是否与空间三角形相交 27 7.14计算两条直线的交点 28 7.15计算直线与平面的交点 28 7.16计算两平面的交线 29 7.17点到直线的距离 29 7.18 计算点到平面的距离 29 7.19计算直线到直线的距离 30 7.20空间两直线夹角的cos值 30 7.21两平面夹角的cos值 30 7.22直线与平面夹角sin值 31 1.最远曼哈顿距离 31 2. 最近点对 32 3. 最近点对 34 4. 最小包围 36 5. 求两个的交点 39 6. 求三角形外接心 40 7. 求凸包 42 8.凸包卡壳旋转求出所有对踵点、最远点对 44 9. 凸包+旋转卡壳求平面面积最大三角 47 10. Pick定理 50 11. 求多边形面积和重心 51 12. 判断一个简单多边形是否有核 52 13. 模拟退火 54 14. 六边形坐标系 56 15. 用一个给定半径的覆盖最多的点 60 16. 不等大的弧表示 62 17. 矩形面积并 62 18. 矩形的周长并 66 19. 最近对 70 20. 求两个的面积交 74
㈠ 点的基本运算 1. 平面上两点之间距离 1 2. 判断两点是否重合 1 3. 矢量叉乘 1 4. 矢量点乘 2 5. 判断点是否在线段上 2 6. 求一点饶某点旋转后的坐标 2 7. 求矢量夹角 2 ㈡ 线段及直线的基本运算 1. 点与线段的关系 3 2. 求点到线段所在直线垂线的垂足 4 3. 点到线段的最近点 4 4. 点到线段所在直线的距离 4 5. 点到折线集的最近距离 4 6. 判断是否在多边形内 5 7. 求矢量夹角余弦 5 8. 求线段之间的夹角 5 9. 判断线段是否相交 6 10.判断线段是否相交但不交在端点处 6 11.求线段所在直线的方程 6 12.求直线的斜率 7 13.求直线的倾斜角 7 14.求点关于某直线的对称点 7 15.判断两条直线是否相交及求直线交点 7 16.判断线段是否相交,如果相交返回交点 7 ㈢ 多边形常用算法模块 1. 判断多边形是否简单多边形 8 2. 检查多边形顶点的凸凹性 9 3. 判断多边形是否凸多边形 9 4. 求多边形面积 9 5. 判断多边形顶点的排列方向,方法一 10 6. 判断多边形顶点的排列方向,方法二 10 7. 射线法判断点是否在多边形内 10 8. 判断点是否在凸多边形内 11 9. 寻找点集的graham算法 12 10.寻找点集凸包的卷包裹法 13 11.判断线段是否在多边形内 14 12.求简单多边形的重心 15 13.求凸多边形的重心 17 14.求肯定在给定多边形内的一个点 17 15.求从多边形外一点出发到该多边形的切线 18 16.判断多边形的核是否存在 19 ㈣ 的基本运算 1 .点是否在内 20 2 .求不共线的三点所确定的 21 ㈤ 矩形的基本运算 1.已知矩形三点坐标,求第4点坐标 22 ㈥ 常用算法的描述 22 ㈦ 补充 1.两圆关系: 24 2.判断是否在矩形内: 24 3.点到平面的距离: 25 4.点是否在直线同侧: 25 5.镜面反射线: 25 6.矩形包含: 26 7.两圆交点: 27 8.两圆公共面积: 28 9. 和直线关系: 29 10. 内切: 30 11. 求切点: 31 12. 线段的左右旋: 31
实现两圆公切线交点计算,需要先判断两个是否有公切线,如果有,则可以根据两圆心和半径计算两个切点的坐标。 假设两个分别为A和B,心坐标分别为(xa,ya)和(xb,yb),半径分别为ra和rb。如果两个公切线,则公切线两个的切点坐标分别为(x1,y1)和(x2,y2)。 首先,根据两圆心之间的距离d,判断两个是否有公切线: 1. d > ra + rb,两个外离,无公切线; 2. d < |ra - rb|,一个包含在另一个内,无公切线; 3. d = 0,两圆重合,无公切线; 4. 其他情况,两圆相交,有公切线。 如果存在公切线,则可以根据两个心和半径计算切点坐标: 1. 求出两圆心的连线斜率k和截距b; 2. 以A的心为起点,向切点方向移动ra个单位长度,求出切点坐标(x1,y1); 3. 以B的心为起点,向切点方向移动rb个单位长度,求出切点坐标(x2,y2)。 下面是C++代码实现: ```cpp #include <iostream> #include <cmath> using namespace std; // 判断两个浮点数是否相等 bool isEqual(double a, double b) { return fabs(a - b) < 1e-6; } // 计算两圆公切线交点 bool getTangentialPoints(double xa, double ya, double ra, double xb, double yb, double rb, double &x1, double &y1, double &x2, double &y2) { double d = sqrt((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb)); // 两圆心之间的距离 if (isEqual(d, 0) || d > ra + rb || d < fabs(ra - rb)) { // 两圆重合或相离或包含,无公切线 return false; } double A = (ra - rb + d) * (ra + rb - d) * (ra + rb + d) * (ra - rb - d); double B = 2 * (ra + rb + d) * (ra + rb - d) * (rb - ra + d) * (ra - rb + d); double C = (ra + rb + d) * (ra - rb - d) * (ra - rb + d) * (rb - ra + d); double x3 = (xa + xb) / 2.0 + (xb - xa) * (ra * ra - rb * rb) / (2.0 * d * d); double y3 = (ya + yb) / 2.0 + (yb - ya) * (ra * ra - rb * rb) / (2.0 * d * d); if (isEqual(A, 0) && isEqual(B, 0)) { // 两圆相切,只有一条公切线 x1 = x3; y1 = y3; return true; } double k = sqrt(B * B - 4 * A * C); double x4 = (2.0 * C * x3) / (-B + k); double y4 = (-B * x3 + 2.0 * A * y3) / (-B + k); x1 = x4 + (xb - xa) * sqrt(ra * ra - (x4 - xa) * (x4 - xa) - (y4 - ya) * (y4 - ya)) / d; y1 = y4 + (yb - ya) * sqrt(ra * ra - (x4 - xa) * (x4 - xa) - (y4 - ya) * (y4 - ya)) / d; x2 = x4 - (xb - xa) * sqrt(ra * ra - (x4 - xa) * (x4 - xa) - (y4 - ya) * (y4 - ya)) / d; y2 = y4 - (yb - ya) * sqrt(ra * ra - (x4 - xa) * (x4 - xa) - (y4 - ya) * (y4 - ya)) / d; return true; } int main() { double xa = 0, ya = 0, ra = 3; double xb = 6, yb = 0, rb = 2; double x1, y1, x2, y2; if (getTangentialPoints(xa, ya, ra, xb, yb, rb, x1, y1, x2, y2)) { cout << "Circle A and Circle B have tangential points:" << endl; cout << "(" << x1 << ", " << y1 << ")" << endl; cout << "(" << x2 << ", " << y2 << ")" << endl; } else { cout << "Circle A and Circle B don't have tangential points." << endl; } return 0; } ``` 其中,isEqual()函数是用来判断两个浮点数是否相等的,getTangentialPoints()函数根据上述算法实现了两圆公切线交点的计算。在主函数中,我们可以设置两个心坐标和半径,然后调用getTangentialPoints()函数计算切点坐标。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值