其实圆与直线的交点方程并不难解,难得是算法实现,废话不多说,直接上代码:
核心类
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89/** * @Author: Zhangwenshun * @Description: * @Date: Created in 10:20 2020/9/10 * @Modified by: */ public class CGGeometryLib { /** * 封装一下 Math 的 pow 、sqrt 方法,调用起来方便一些~ * * @param d1 * @param d2 * @return */ public static double pow(double d1, double d2) { return Math.pow(d1, d2); } public static double sqrt(double d) { return Math.sqrt(d); } public static double sin(double theta) { return Math.sin(theta); } public static double cos(double theta) { return Math.cos(theta); } /** * 传入直线上的两个点以及圆心和半径 * 返回直线过圆心与圆的两个交点 * * @param p1 直线上一个点 * @param p2 直线上另一个点 * @param coc 圆心 * @param radius 圆半径 * @return 直线过圆心与圆的两个交点 * @author zhangwenshun */ public static CGPoint[] getLineCircleNode(CGPoint p1, CGPoint p2, CGPoint coc, double radius) { CGPoint[] target = new CGPoint[2]; CGLine l1 = new CGLine(p1, p2); if (l1.iskExists()) { if (l1.k != 0) { // 经过数学运算,得出二元一次方程组的表达式 double A = pow(l1.k, 2) + 1; double B = 2 * (l1.k * l1.b - l1.k * coc.y - coc.x); double C = pow(coc.x, 2) + pow((l1.b - coc.y), 2) - pow(radius, 2); double delta = pow(B, 2) - 4 * A * C; if (delta < 0) { // 经实践检验有一定几率走入该分支,必须做特殊化处理~ // 2012。04。28。20。01,精度不够所致,换成double后无该情况出现~ target[0] = new CGPoint(coc.x, coc.y - radius); target[1] = new CGPoint(coc.x, coc.y + radius); } else { double x1 = (-B + sqrt(delta)) / (2 * A); double y1 = l1.k * x1 + l1.b; target[0] = new CGPoint(x1, y1); double x2 = (-B - sqrt(delta)) / (2 * A); double y2 = l1.k * x2 + l1.b; target[1] = new CGPoint(x2, y2); } } else { target[0] = new CGPoint(coc.x - radius, coc.y); target[1] = new CGPoint(coc.x + radius, coc.y); } } else { target[0] = new CGPoint(coc.x, coc.y - radius); target[1] = new CGPoint(coc.x, coc.y + radius); } return target; } /** * 测试实用性 * * @param args */ public static void main(String[] args) { CGPoint p1 = new CGPoint(4, 0); CGPoint p2 = new CGPoint(6, 2); CGPoint coc = new CGPoint(6, 2); CGPoint[] whatIWanted = getLineCircleNode(p1, p2, coc, 2); for (int i = 0; i < whatIWanted.length; i++) { System.out.println(whatIWanted[i]); } } }
建立一个坐标点CGPoint的类
复制代码
1
2
3
4
5
6
7
8
9public class CGPoint { public double x; public double y; public CGPoint(double x, double y) { this.x = x; this.y = y; } }
建立一个直线函数CGLine的类
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88/** * @Description: *这个是对通用一次直线方程 A*x + B*y + C = 0 的封装~ * * 本来封装的是斜截式,不过发现当斜率k不存在的时候会比较麻烦,因此该用一般式 * * 再个就是接着用一般式的演变方式 x + B/A*y + C/A = 0,但是考虑到可能存在x == 0 的情况,因此又舍弃 * * 一个boolean表示k是否存在,一个额外的float表示k不存在的时候直线方程 x=***, *** 等于多少 */ public class CGLine { private boolean kExists;// 大部分情况下 k 都应该是存在的,因此提供一个 true 的默认值 public double k = 77885.201314f; public double b = 13145.207788f; public double extraX = 52077.881314f; /** * 这是当 k 存在时的构造方法~ * * @param k * @param b */ public CGLine(double k, double b) { this.kExists = true; this.k = k; this.b = b; } /** * 已知两点,求直线的方程~ * * @param p1 * @param p2 */ public CGLine(CGPoint p1, CGPoint p2) { if ((p1.x - p2.x) != 0) { System.out.println("y = k*x + b, k exits!!"); this.kExists = true; this.k = (p1.y - p2.y) / (p1.x - p2.x); this.b = (p1.y - p1.x * k); } else { System.out.println("y = k*x + b, k doesn't exists!!"); // 如果走进这个分支,表示直线垂直于x轴,斜率不存在,保留k的默认值~ this.kExists = false; this.extraX = p1.x; } System.out.print("过p1(" + p1.x + ", " + p1.y + "), p2(" + p2.x + ", " + p2.y + ")两点的直线方程表达式为: "); if (kExists) { System.out.println("y = " + k + "*x + " + b); } else { System.out.println("x = " + extraX + "(垂直于x轴!)"); } } /** * 点斜式~ * * @param p 某点 * @param k 过该点的直线的斜率 */ public CGLine(double k, CGPoint p) { /** * (y-y') = k*(x-x') * 变形成斜截式为: * y = k*x + y' - k*x' * k = k, b = y'-k*x' */ this.kExists = true; this.k = k; this.b = p.y - k * p.x; } /** * 这是当 k 不存在时的构造方法~ * * @param extraX */ public CGLine(double extraX) { this.kExists = false; this.extraX = extraX; } @Override public String toString() { return "Line.toString()方法被调用,y = k*x + b斜截式, k=" + this.k + ", b=" + this.b + ", kExists=" + this.kExists + ", extraX=" + this.extraX; } public boolean iskExists() { return kExists; } public void setkExists(boolean kExists) { this.kExists = kExists; } }
参考:https://www.cnblogs.com/pengyingh/articles/2516990.html
最后
以上就是鲜艳鼠标最近收集整理的关于JAVA程序设计:求直线与圆的交点坐标的全部内容,更多相关JAVA程序设计:求直线与圆内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复