Java实现椭圆于直线的位置关系

1. 创建一个EllipseLine类实现椭圆于直线的位置关系,如下

public class EllipseLine {
    /**
     * 椭圆与直线位置关系
     *
     * @param a 半长轴
     * @param b 半短轴
     * @param c 半焦距
     * @param k 斜率:必须存在,可以为0
     * @param m 纵截距:可以为零
     */
    public static void math(double a, double b, double c, double k, double m) {
        if (a < 0 || b < 0 || c < 0) {
            System.out.println("a, b, c都必须大于0");
            return;
        } else if (a < b) {
            System.out.println("a必须大于b");
            return;
        } else if (k == 0 || m == 0) {
            System.out.println("k和m不能同时为0");
            return;
        }
        // 椭圆和直线相交与点M和点N
        // 设M(x_1, y_1)和N(x_2, y_2)
        /* M点 */
        double x1 = 0;
        double y1 = 0;
        /* N点 */
        double x2 = 0;
        double y2 = 0;
        // 获取椭圆的a,b,c
        // x^2/a^2+y^2/b^2=1
        // double a;
        // double b;
        // double c;
        // 获取直线的k和m
        // y=kx+m;
        // double k;
        // double m;
        // 联立得出
        // (b^2+a^2k^2)x^2+2ka^2mx+a^2(m^2-b^2)
        // a1 = b^2+a^2k^2
        double a1 = b * b + a * a * k * k;
        // b2 = 2ka^2m
        double b1 = 2 * k * a * a * m;
        // c2 = a^2(m^2-b^2)
        double c1 = a * a * (m * m - b * b);
        // b^2-4ac
        double delta = b1 * b1 - 4 * a1 * c1;
        if (delta >= 0) {
            // 求两点坐标
            // x = (-b ± sqrt(delta)) / (2a)
            x1 = (-b1 + Math.sqrt(delta)) / (2 * a1);
            x2 = (-b1 - Math.sqrt(delta)) / (2 * a1);
            y1 = k * x1 + m;
            y2 = k * x2 + m;
        } else {
            // delta < 0 没有交点
            System.out.println("椭圆和直线相离");
        }
        // 韦达定理
        double x1AndX2 = -(b1 / a1);
        double x1x2 = c1 / a1;
        System.out.println("x_1 * x_2:" + x1x2);
        System.out.println("x_1 + x_2:" + x1AndX2);
        // 求AB弦长
        // 方法一:|AB| = sqrt(1 + k^2) * |x_1 - x_2|
        double ab1 = Math.sqrt(1 + k * k) * Math.abs(x1 - x2);
        System.out.println("AB的弦长为:" + ab1);
        // 获取两个交点
        System.out.println("点M(" + x1 + ", " + y1 + ")");
        System.out.println("点N(" + x2 + ", " + y2 + ")");
    }

    public static void math(double a, double b, double k, double m) {
        math(a, b, 0, k, m);
    }

2. 设置椭圆基本属性

/**
     * 椭圆基本属性
     *
     * @param a 半长轴
     * @param b 半短轴
     * @param c 半焦距
     */
    public static void properties(double a, double b, double c) {
        if (a < 0 || b < 0 || c < 0) {
            System.out.println("a, b, c都必须大于0");
            return;
        }
        if (a > b) {
            if (c == 0) {
                c = Math.sqrt(a * a - b * b);
                // 焦点F_1和F_2
                System.out.println("点F1(" + -c + ", " + 0 + ")");
                System.out.println("点F2(" + c + ", " + 0 + ")");
            } else {
                System.out.println("点F1(" + -c + ", " + 0 + ")");
                System.out.println("点F2(" + c + ", " + 0 + ")");
            }
            // 顶点
            System.out.println("点A1(" + -a + ", " + 0 + ")");
            System.out.println("点A2(" + a + ", " + 0 + ")");
            System.out.println("点B1(" + -b + ", " + 0 + ")");
            System.out.println("点B2(" + b + ", " + 0 + ")");
            // 离心率
            double e = c / a;
            System.out.println("e为:" + e);
        }
    }

3. 进行测试

public class Main {
    public static void main(String[] args) {
        // 计算AB弦长和M、N两点位置
        EllipseLine.math(5, 3, 1, 1);
        System.out.println("----------");
        // 输出椭圆基本属性
        EllipseLine.properties(5, 3, 0);
    }
}

4. 结果展示

x_1 * x_2:-5.882352941176471
x_1 + x_2:-1.4705882352941178
AB的弦长为:7.1682691805611425
点M(1.7990717558256009, 2.799071755825601)
点N(-3.2696599911197186, -2.2696599911197186)
----------
点F1(-4.0, 0)
点F2(4.0, 0)
点A1(-5.0, 0)
点A2(5.0, 0)
点B1(-3.0, 0)
点B2(3.0, 0)
e为:0.8
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值