- 积分
- 30318
- 明经币
- 个
- 注册时间
- 2016-9-16
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 fangmin723 于 2024-6-11 10:40 编辑
2022.5.9更新:优化当X轴相同时报错!
- ;;说明:求两圆交点
- ;;参数:cen1:圆心1
- ;;参数:r1:半径1
- ;;参数:cen2:圆心2
- ;;参数:r2:半径2
- ;;返回:有交点侧返回交点列表,没有则返回nil
- (defun 2ci(cen1 r1 cen2 r2 / a1 a2 a3 b2 b3 c3 cx1 cx2 cy1 cy2 delta x1 x12 x2 y1 y12 y2)
- (setq cx1 (car cen1) cy1 (cadr cen1) cx2 (car cen2) cy2 (cadr cen2))
- (cond
- ((and (= cx1 cx2) (/= cy1 cy2))
- (setq y12 (/ (+ (- (* r1 r1) (* r2 r2)) (- (* cy2 cy2) (* cy1 cy1))) 2.0 (- cy2 cy1)))
- (setq a3 1 b3 (* -2 cx1) c3 (+ (* (- y12 cy1) (- y12 cy1)) (* cx1 cx1) (* -1.0 r1 r1)))
- (setq delta (- (* b3 b3) (* 4.0 a3 c3)))
- (cond
- ((> delta 0)
- (setq x1 (/ (+ (* -1.0 b3) (sqrt (- (* b3 b3) (* 4.0 a3 c3)))) (* 2.0 a3)))
- (setq x2 (/ (- (* -1.0 b3) (sqrt (- (* b3 b3) (* 4.0 a3 c3)))) (* 2.0 a3)))
- (list (list x1 y12) (list x2 y12))
- )
- ((= delta 0) (list (list (/ (* -1.0 b3) (* 2.0 a3)) y12)))
- (t (princ "\n没有交点!") nil)
- )
- )
- ((and (/= cx1 cx2) (= cy1 cy2))
- (setq x12 (/ (+ (- (* r1 r1) (* r2 r2)) (- (* cx2 cx2) (* cx1 cx1))) 2.0 (- cx2 cx1)))
- (setq a3 1 b3 (* -2 cy1) c3 (+ (* (- x12 cx1) (- x12 cx1)) (* cy1 cy1) (* -1.0 r1 r1)))
- (setq delta (- (* b3 b3) (* 4.0 a3 c3)))
- (cond
- ((> delta 0)
- (setq y1 (/ (+ (* -1.0 b3) (sqrt (- (* b3 b3) (* 4.0 a3 c3)))) (* 2.0 a3)))
- (setq y2 (/ (- (* -1.0 b3) (sqrt (- (* b3 b3) (* 4.0 a3 c3)))) (* 2.0 a3)))
- (list (list x12 y1) (list x12 y2))
- )
- ((= delta 0) (list (list x12 (/ (* -1.0 b3) (* 2.0 a3)))))
- (t (princ "\n没有交点!") nil)
- )
- )
- ((and (= cx1 cx2) (= cy1 cy2))
- (cond
- ((= r1 r2) (alert "\n同一个圆求交点,怕不是个傻子吧你!"))
- (t (alert "\n同心圆求交点,你没毛病吧!"))
- )
- nil
- )
- (t
- (setq a1 (+ (- (* r1 r1) (* r2 r2)) (- (* cx2 cx2) (* cx1 cx1)) (- (* cy2 cy2) (* cy1 cy1))))
- (setq a2 (/ a1 2.0 (- cy2 cy1)))
- (setq b2 (/ (* 1.0 (- cx2 cx1)) (- cy2 cy1)))
- (setq a3 (+ 1.0 (* b2 b2)))
- (setq b3 (* -1 (+ (* 2.0 cx1) (* 2.0 (- a2 cy1) b2))))
- (setq c3 (- (+ (* cx1 cx1) (* (- a2 cy1) (- a2 cy1))) (* r1 r1)))
- (setq delta (- (* b3 b3) (* 4.0 a3 c3)))
- (cond
- ((> delta 0)
- (setq x1 (/ (+ (* -1.0 b3) (sqrt (- (* b3 b3) (* 4.0 a3 c3)))) (* 2.0 a3)))
- (setq x2 (/ (- (* -1.0 b3) (sqrt (- (* b3 b3) (* 4.0 a3 c3)))) (* 2.0 a3)))
- (setq y1 (- a2 (* b2 x1)))
- (setq y2 (- a2 (* b2 x2)))
- (list (list x1 y1) (list x2 y2))
- )
- ((= delta 0) (list (list (setq x1 (/ (* -1.0 b3) (* 2.0 a3))) (- a2 (* b2 x1)))))
- (t (princ "\n没有交点!") nil)
- )
- )
- )
- )
- (2ci (list 100.0 100.0) 50 (list 120.0 30.0) 70.0)
- ((149.569 93.4483) (61.3745 68.2499))
2024.6.11新增:.NET方式求交:
- /// <summary>
- /// 数学方式求两圆交点
- /// </summary>
- /// <param name="center1">圆心1</param>
- /// <param name="radius1">半径1</param>
- /// <param name="center2">圆心2</param>
- /// <param name="radius2">半径2</param>
- /// <returns>两圆焦点集合</returns>
- public static List<Point3d> CircleInsert(this Point3d center1, double radius1, Point3d center2, double radius2)
- {
- //两圆同心
- if ((center1.X - center2.X).Abs() <= 1e-8 && (center1.Y - center2.Y).Abs() <= 1e-8 && (center1.Z - center2.Z).Abs() <= 1e-8)
- return [];
- //两圆相离或大圆包含小圆
- if (center1.DistanceTo(center2) > radius1 + radius2 || (center1.DistanceTo(center2) + radius1.Min(radius2)) < radius1.Max(radius2))
- return [];
- var centerX1 = center1.X;
- var centerY1 = center1.Y;
- var centerX2 = center2.X;
- var centerY2 = center2.Y;
- if (centerX1 == centerX2 && centerY1 != centerY2)
- {
- var resultY = (radius1.Pow() - radius2.Pow() + (centerY2.Pow() - centerY1.Pow())) / 2.0 / (centerY2 - centerY1);
- var argA = 1.0;
- var argB = -2 * centerX1;
- var argC = centerX1.Pow() + (resultY - centerY1).Pow() - radius1.Pow();
- var delta = argB.Pow() - (4.0 * argA * argC);
- return delta switch
- {
- > 0 =>
- [
- new(((-1 * argB ) + delta.Sqrt()) / 2.0 / argA, resultY, 0),
- new(((-1 * argB ) - delta.Sqrt()) / 2.0 / argA, resultY, 0)
- ],
- 0 => [new((-1 * argB) / 2.0 / argA, resultY, 0)],
- _ => [],
- };
- }
- else if (centerX1 != centerX2 && centerY1 == centerY2)
- {
- var resultX = (radius1.Pow() - radius2.Pow() + (centerX2.Pow() - centerX1.Pow())) / 2.0 / (centerX2 - centerX1);
- var argA = 1.0;
- var argB = -2 * centerY1;
- var argC = centerY1.Pow() + (resultX - centerX1).Pow() - radius1.Pow();
- var delta = argB.Pow() - (4.0 * argA * argC);
- return delta switch
- {
- > 0 =>
- [
- new( resultX,((-1 * argB ) + delta.Sqrt()) / 2.0 / argA, 0),
- new( resultX,((-1 * argB ) - delta.Sqrt()) / 2.0 / argA, 0)
- ],
- 0 => [new(resultX, (-1 * argB) / 2.0 / argA, 0)],
- _ => [],
- };
- }
- else
- {
- var argA1 = radius1.Pow() - radius2.Pow() + (centerX2.Pow() - centerX1.Pow()) + (centerY2.Pow() - centerY1.Pow());
- var argA2 = argA1 / 2.0 / (centerY2 - centerY1);
- var argB2 = (centerX2 - centerX1) / (centerY2 - centerY1);
- var argA3 = 1 + argB2.Pow();
- var argB3 = -2 * (centerX1 + (argA2 - centerY1) * argB2);
- var argC3 = centerX1.Pow() + (argA2 - centerY1).Pow() - radius1.Pow();
- var delta = argB3.Pow() - (4.0 * argA3 * argC3);
- if (delta > 0)
- {
- var x1 = ((-1 * argB3) + delta.Sqrt()) / 2.0 / argA3;
- var x2 = ((-1 * argB3) - delta.Sqrt()) / 2.0 / argA3;
- var y1 = argA2 - (argB2 * x1);
- var y2 = argA2 - (argB2 * x2);
- return [new(x1, y1, 0), new(x2, y2, 0)];
- }
- else if (delta == 0)
- {
- var x1 = (-1 * argB3) / 2.0 / argA3;
- var y1 = argA2 - (argB2 * x1);
- return [new(x1, y1, 0)];
- }
- else return [];
- }
- }
.NET方式求交所用扩展方法:
- /// <summary>
- /// 获取最小值
- /// </summary>
- /// <param name="value">数值参数</param>
- /// <param name="ints">数值参数,可变</param>
- /// <returns>最小值</returns>
- public static int Min(this int value, params int[] ints)
- {
- return Math.Min(value, ints.Min());
- }
- /// <summary>
- /// 获取最大值
- /// </summary>
- /// <param name="value">数值参数</param>
- /// <param name="ints">数值参数,可变</param>
- /// <returns>最大值</returns>
- public static int Max(this int value, params int[] ints)
- {
- return Math.Max(value, ints.Max());
- }
- /// <summary>
- /// 获取最小值
- /// </summary>
- /// <param name="value">数值参数</param>
- /// <param name="doubles">数值参数,可变</param>
- /// <returns>最小值</returns>
- public static double Min(this double value, params double[] doubles)
- {
- return Math.Min(value, doubles.Min());
- }
- /// <summary>
- /// 获取最大值
- /// </summary>
- /// <param name="value">数值参数</param>
- /// <param name="doubles">数值参数,可变</param>
- /// <returns>最大值</returns>
- public static double Max(this double value, params double[] doubles)
- {
- return Math.Max(value, doubles.Max());
- }
- /// <summary>
- /// 返回双精度浮点数字的绝对值。
- /// </summary>
- /// <param name="value">大于或等于 Double.MinValue 但小于或等于 Double.MaxValue 的数字</param>
- /// <returns>双精度浮点数 x,使 0 ≤ x ≤ Double.MaxValue</returns>
- public static double Abs(this double value) => Math.Abs(value);
- /// <summary>
- /// 返回指定数字的指定次幂
- /// </summary>
- /// <param name="x">要乘幂的双精度浮点数</param>
- /// <param name="y">指定幂的双精度浮点数,默认:2</param>
- /// <returns>数字 x 的 y 次幂</returns>
- public static double Pow(this double x, double y = 2) => Math.Pow(x, y);
- /// <summary>
- /// 返回指定数字的平方根
- /// </summary>
- /// <param name="d">将查找其平方根的数字</param>
- /// <returns>
- /// <code>
- /// d为零或正数 => d 的正平方根
- /// d为负数 => NaN
- /// d等于NaN => NaN
- /// d等于PositiveInfinity => PositiveInfinity
- /// </code>
- /// </returns>
- public static double Sqrt(this double d) => Math.Sqrt(d);
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
评分
-
查看全部评分
"觉得好,就打赏"
共1人打赏
|