概述
其实圆与直线的交点方程并不难解,难得是算法实现,废话不多说,直接上代码:
核心类
/**
* @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的类
public class CGPoint {
public double x;
public double y;
public CGPoint(double x, double y) {
this.x = x;
this.y = y;
}
}
建立一个直线函数CGLine的类
/**
* @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程序设计:求直线与圆的交点坐标所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复