/** * Copyright (C) BBNT Solutions LLC. All Rights Reserved * $Id: Quadratic.java,v 1.1 2005/11/18 14:57:46 mthome Exp $ */ package com.bbn.openmap.geo; /** * Computes 0 to 2 real roots of the quadratic: * * <pre> * a*x^2 + b*x + c = 0 * </pre> * * See http://web.cs.mun.ca/courses/cs2710-w02/lab5/assignment/assign5.html. * http://www.1728.com/quadratc.htm * <p> * Access the roots as a double iterator with methods hasNext() and next(). */ public class Quadratic { double a, b, c; double[] solution; int index = 0; public Quadratic(double a, double b, double c) { this.a = a; this.b = b; this.c = c; solve(); } /** Returns the solution, x, to the equation a*x+b = 0 **/ public static double linear(double a, double b) { return -b / a; } /** * Solve a*x^2 + b*x + c = 0 for x for real values of x. * <p> * * See Winston and Horn, LISP p. 167-169. */ public void solve() { if (a == 0.0 && b == 0.0) values(); else if (a == 0.0 && b != 0.0) values(linear(b, c)); else if (a != 0.0 && c == 0.0) values(0.0, linear(a, b)); else { double d = b * b - 4.0 * a * c; if (d < 0.0) values(); // Complex roots. else if (d == 0.0) values(-b / (2.0 * a)); else values((-b + Math.sqrt(d)) / (2.0 * a), (-b - Math.sqrt(d)) / (2.0 * a)); } } /** Evaluate the Quadratic at x. **/ public double eval(double x) { return (a * x + b) * x + c; } public boolean hasNext() { return index < solution.length; } public double next() { if (this.hasNext()) return solution[index++]; else throw new java.util.NoSuchElementException(); } public String toString() { return "{" + a + "*x^2 + " + b + "*x + " + c + " = 0 [" + solutionToString() + "]}"; } private String solutionToString() { switch (solution.length) { case 0: return ""; case 1: return String.valueOf(solution[0]); case 2: return String.valueOf(solution[0]) + " " + String.valueOf(solution[1]); default: return ""; // Can't happen. } } private void values() { solution = new double[0]; } private void values(double s1) { solution = new double[] { s1 }; } private void values(double s1, double s2) { solution = new double[] { s1, s2 }; } public String test() { String s = this + " test: "; switch (solution.length) { case 0: return ""; case 1: return s + this.eval(solution[0]); case 2: return s + this.eval(solution[0]) + " " + this.eval(solution[1]); default: return ""; // Can't happen. } } static private void p(double a, double b, double c) { System.out.println((new Quadratic(a, b, c)).test()); } public static void main(String[] args) { p(0.0, 0.0, -30.0); p(0.0, 4.0, 0.0); p(0.0, 4.0, -30.0); p(2.0, 4.0, 0.0); p(2.0, 4.0, -30.0); p(1.0, 4.0, 1.0); } }