日期:2014-05-20  浏览次数:20743 次

纯真时期的解析几何,谁人能够铭记?
遇到一个有问题,三顾大牛求辅佐!!
1.问题:
现有一条线段,已知线段的两个端点。
求出该线段的中点,以该中点半径为 smallRadius 的圆,求该线段中垂线与圆的两个交点。

2.按理说:
过圆中心做一条直线,必有2解(画图可以看到直线和圆有两个交点)

3.蛋疼的地方:
求解的过程中竟然时不时的出现 delta = b^2-4*a*c < 0 的情况,和2 严重矛盾。

4.我的测试方案:
我写了一个方法,传入线段的两个点,和以线段中点为圆心的一个圆。
我100%确定,该线段的长度大于上述圆的直径(必须保证有两个交点么~)。
返回一个点数组,点数组包含了2解。

5。尾声:
为什么出现 delta < 0 这种奇葩的情况,求指点。
如能点醒我这块朽木,100整分奉送,在线等!!高手素来~~~

代码如下:
Java code

package org.bruce.vertices.controller.geometry;

/**
 * @author Bruce Yang
 * 用于打印调试~
 */
public class CGDbg {
    public static final boolean DEBUG_MODE = true;
    
    // 方便进行调试信息的输出,开关~
    public static void println(Object info) {
        if(DEBUG_MODE) {            
            System.out.println(info);
        }
    }
    public static void print(Object info) {
        if(DEBUG_MODE) {            
            System.out.print(info);
        }
    }
}


***********************************************
Java code

package org.bruce.vertices.controller.geometry;


/**
 * @author BruceYang
 * 这个是对通用一次直线方程 A*x + B*y + C = 0 的封装~
 * 本来封装的是斜截式,不过发现当斜率k不存在的时候会比较麻烦,因此该用一般式
 * 再个就是接着用一般式的演变方式 x + B/A*y + C/A = 0,但是考虑到可能存在x == 0 的情况,因此又舍弃~
 * 
 * 娘的,一般式还是他妈的无济于事啊,改回斜截式,多提供两个成员变量:
 * 一个boolean表示k是否存在,一个额外的float表示k不存在的时候直线方程 x=***, *** 等于多少~
 */
public class CGLine {
    // 特别声明为public类型,免得到时候访问的时候麻烦,到时候直接点就行了
    private boolean kExists;    // 大部分情况下 k 都应该是存在的,因此提供一个 true 的默认值~

    public float k = 77885.201314f;
    public float b = 13145.207788f;
    public float extraX = 52077.881314f;
    
    
    /**
     * 这是当 k 存在时的构造方法~
     * @param k
     * @param b
     */
    public CGLine(float k, float 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) {
            CGDbg.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 {
            CGDbg.println("y = k*x + b, k doesn't exists!!");
            // 如果走进这个分支,表示直线垂直于x轴,斜率不存在,保留k的默认值~
            this.kExists = false;
            this.extraX = p1.x;
        }
        CGDbg.print("过p1("+p1.x+", " +p1.y + "), p2("+p2.x+", "+p2.y+")两点的直线方程表达式为: ");
        if(kExists) {
            CGDbg.println("y = " + k + "*x + " + b);
        } else {
            CGDbg.println("x = " + extraX + "(垂直于x轴!)");
        }
    }
    
    /**
     * 点斜式~
     * @param p    某点
     * @param k    过该点的直线的斜率
     */
    public CGLine(float 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.y;
    }
    
    /**
     * 这是当 k 不存在时的构造方法~
     * @param extraX
     */
    public CGLine(float 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;
    }
}


***********************************************
Java code

package org.bruce.vertices.controller.geometry;

/**
 * @author BruceYang
 * 对点的抽象~
 */
public class CGPoint {
    public float x;
    public float y;
    
    public CGPoint() {
        
    }
    public CGPoint(float x, float y) {
        this.x = x;
        this.y = y;
    }
    
    @Override
    public String toString() {
        return "x=" + this.x + ", y=" + this.y;
    }
}