I am writing a program which solves either quadratic or cubic equations. The thing is that I don't know if I am placing the Math.toRadians correctly.
The code is the following:
public double[] getRaices(double a,double b, double c, double d) throws ComplexException {
if (a==0){
double discriminante=Math.pow(c,2)+((-4)*b*d);
if(discriminante>=0){
this.Raices[0]=(c*(-1)+Math.sqrt(discriminante))/(2*b);
this.Raices[1]=(c*(-1)-Math.sqrt(discriminante))/(2*b);
}else{
throw new ComplexException("No hay solucion Real");
}
} else{
double f=((3*c/a)-(Math.pow(b,2)/Math.pow(a,2)))/3;
double g=((2*Math.pow(b,3)/Math.pow(a,3))-(9*b*c/Math.pow(a,2))+(27*d/a))/27;
double h=(Math.pow(g,2)/4)+(Math.pow(f,3)/27);
if(f+g+h==0){
Raices [0]=Math.cbrt(d/a)*(-1);
Raices [1]=Math.cbrt(d/a)*(-1);
Raices [2]=Math.cbrt(d/a)*(-1);
}else{
if(h<=0){
double i=Math.sqrt((Math.pow(g,2)/4)-h);
double j=Math.cbrt(i);
double k=Math.acos(Math.toRadians(-1*(g/2*i)));
System.out.println(" "+k+" ");
double l=j*(0-1);
double m=Math.toRadians(Math.cos(Math.toRadians(k/3)));
System.out.println(" "+m+" ");
double n=Math.sqrt(3)*Math.sin(Math.toRadians(k/3));
System.out.println(" "+n+" ");
double p=(b/(3*a)*(0-1));
Raices [0]=2*j*Math.cos(Math.toRadians(k/3))-(b/(3*a));
Raices [1]=(l*(m+n))+p;
Raices [2]=(l*(m-n))+p;
}else{
double r=((0-1)*(g/2))+Math.sqrt(h);
double s=Math.cbrt(r);
double t=((0-1)*(g/2))-Math.sqrt(h);
double u=Math.cbrt(t);
throw new ComplexException("2 de las raices son imaginarias pero una raiz es real: "+Math.floor(Raices [0]=(s+u)-(b/(3*a))));
}
}
}
return Raices;
}
But the problem is in the if (h<=0).
I tested your code against the web page and found several errors.
First is g /2i, you wrote g/2*i instead of g/2/i or (g/(2*i). And several Math.toRadians not necessary (webpage said calculations is in radians, so no need to convert).
I added println to help following the formula :
package test;
public class Cubic {
private double[] Raices = new double[3];
public static void main(String[] args) throws ComplexException {
double[] raices = new Cubic().getRaices(2, -4, -22, 24);
System.out.println(raices[0] + "," + raices[1] + "," + raices[2]);
}
public double[] getRaices(double a, double b, double c, double d) throws ComplexException {
if (a == 0) {
double discriminante = Math.pow(c, 2) + ((-4) * b * d);
if (discriminante >= 0) {
this.Raices[0] = (c * (-1) + Math.sqrt(discriminante)) / (2 * b);
this.Raices[1] = (c * (-1) - Math.sqrt(discriminante)) / (2 * b);
} else {
throw new ComplexException("No hay solucion Real");
}
} else {
double f = ((3 * c / a) - (Math.pow(b, 2) / Math.pow(a, 2))) / 3;
System.out.println("f=" + f);
double g = ((2 * Math.pow(b, 3) / Math.pow(a, 3)) - (9 * b * c / Math.pow(a, 2)) + (27 * d / a)) / 27;
System.out.println("g=" + g);
double h = (Math.pow(g, 2) / 4) + (Math.pow(f, 3) / 27);
System.out.println("h=" + h);
if (f + g + h == 0) {
Raices[0] = Math.cbrt(d / a) * (-1);
Raices[1] = Math.cbrt(d / a) * (-1);
Raices[2] = Math.cbrt(d / a) * (-1);
} else {
if (h <= 0) {
double i = Math.sqrt((Math.pow(g, 2) / 4) - h);
double j = Math.cbrt(i);
double k = Math.acos(-1 * (g / 2 / i));
System.out.println("k=" + k + " ");
double l = j * (0 - 1);
System.out.println("l=" + l + " ");
double m = Math.cos(k / 3);
System.out.println("m= " + m + " ");
double n = Math.sqrt(3) * Math.sin(k / 3);
System.out.println("n= " + n + " ");
double p = (b / (3 * a) * (0 - 1));
System.out.println("p= " + p + " ");
Raices[0] = 2 * j * Math.cos(k / 3) - (b / (3 * a));
Raices[1] = (l * (m + n)) + p;
Raices[2] = (l * (m - n)) + p;
} else {
double r = ((0 - 1) * (g / 2)) + Math.sqrt(h);
double s = Math.cbrt(r);
double t = ((0 - 1) * (g / 2)) - Math.sqrt(h);
double u = Math.cbrt(t);
throw new ComplexException(
"2 de las raices son imaginarias pero una raiz es real: " + Math.floor(Raices[0] = (s + u) - (b / (3 * a))));
}
}
}
return Raices;
}
}
Related
How to write this theorem correctly as is written in the formula?
package com.company;
public class Exercise8 {
public static void main(String[] args) {
double AB = 6;
double AC = 16;
double Angle = 60;
double CosOfAngle = 0.5;
// Почему-то значение косинуса 60 градусов вместо 0.5, пишет
// -0.9524129804151563 ? ? ? (Do not pay attention)
// Formula is BC^2 = AB^2 + AC^2 - 2AB*AC * cos A
double bc = (2 * (Math.pow(AB, 2) + Math.pow(AC, 2) - ((AB * AC))) * CosOfAngle);
double BC = Math.sqrt(bc);
double P = AB + BC + AC;
double p = 0.5 * P; // Где p - полупериметр
double S0 = (p * ((p - AB) * (p - BC) * (p - AC)));
double S1 = Math.sqrt(S0);
double S = Math.round(S1);
System.out.println("Perimeter of triangle is : " + P + " cm ");
System.out.println("Area of triangle is : " + S + " cm^2 ");
}
}
The mistake is in this line:
double bc = (2 * (Math.pow(AB, 2) + Math.pow(AC, 2) - ((AB * AC))) * CosOfAngle);
which should be:
double bc = Math.pow(AB, 2) + Math.pow(AC, 2) - 2 * AB * AC * CosOfAngle;
You were multiplying the whole formula by 2, whereas only the cosine part needs to be multiplied by two. There were too many confusing parenthesis. Removing them made it a lot clearer.
This seems simple to me:
// https://www.mathsisfun.com/algebra/trig-cosine-law.html
public double lawOfCosines(double a, double b, double angleInRadians) {
return Math.sqrt(a*a + b*b - 2.0*a*b*Math.cos(angleInRadians));
}
I am trying to solve a system of trigonometric equations in Java, but I don't know where to start. I've used commons-math3 before to solve simple linear sets of equations, but this is above my head. Equations I am trying to solve:
a - e + bcosθ1 + csinθ1 + d*sin(θ2+θ1)= z
( bsinθ1 + ccosθ1 + d*cos(θ2-θ1) * sinθ0 = x
( bsinθ1 + ccosθ1 + d*cos(θ2-θ1) * sinθ0 = y
, where a,b,c,d and e are constants. In practical terms, given x, y, and z, I need to solve for θ0, θ1, θ2.
You need to use the root-finding algorithm.
It is usually studied in calculus as the Newton's method or Newton Raphson method.
You will have to use a multi-dimensional secant method or Muller's method. Numerical recipes has something on it.
You can use the least-squares-in-java project for this. Here’s the code that will solve your problem:
import org.junit.Assert;
import org.junit.Test;
import org.orangepalantir.leastsquares.Function;
public class NonLinearTrigonometricSolver {
// Solves the following non-linear set of equations:
// a - e + bcosθ1 + csinθ1 + d * sin(θ1 + θ2) ) = z
// ( bsinθ1 + ccosθ1 + d * cos(θ1 + θ2) ) * sinθ0 = x
// ( bsinθ1 + ccosθ1 + d * cos(θ1 + θ2) ) * cosθ0 = y
// given x, y, z, solve for θ0, θ1, θ2
static final double a = 125;
static final double b = 143;
static final double c = 50;
static final double d = 142;
static final double e = 96;
static final double x = 0;
static final double y = 192;
static final double z = 172;
#Test
public void testNonLinearTrigonometricSolver() {
double[][] xs = { { -1 }, { 0 }, { 1 } };
double[] zs = { z, x, y };
double r = Math.sqrt(x * x + y * y);
final double sinTheta0 = x / r;
final double cosTheta0 = y / r;
Function f = new Function() {
#Override
public double evaluate(double[] values, double[] parameters) {
double t1 = parameters[0];
double t2 = parameters[1];
if (values[0] == -1) {
return a - e + b * Math.sin(t1) + c * Math.cos(t1) + d * Math.cos(t2 + t1);
} else if (values[0] == 0) {
return (b * Math.sin(t1) + c * Math.cos(t1) + d * Math.cos(t2 + t1)) * sinTheta0;
} else {
return (b * Math.sin(t1) + c * Math.cos(t1) + d * Math.cos(t2 + t1)) * cosTheta0;
}
}
#Override
public int getNParameters() {
return 2;
}
#Override
public int getNInputs() {
return 1;
}
};
NonLinearSolver fit = new NonLinearSolver(f);
fit.setData(xs, zs);
double[] params = { 0, 0 };
fit.setParameters(params);
fit.fitData();
// improving results.
fit.setMinChange(1e-32);
fit.setMinError(1e-32);
fit.setStepSize(0.5);
fit.fitData();
double t1 = fit.getParameters()[0];
double t2 = fit.getParameters()[1];
double arg = y / (b * Math.sin(t1) + c * Math.cos(t1) + d * Math.cos(t2 + t1));
// System.out.println(" " + arg);
double theta0 = Math.acos(arg) * Math.signum(x);
System.out.println(Math.toDegrees(theta0));
System.out.println(Math.toDegrees(fit.getParameters()[0]));
System.out.println(Math.toDegrees(fit.getParameters()[1]));
Assert.assertEquals(0, Math.toDegrees(theta0), 1e-16);
Assert.assertEquals(0, Math.toDegrees(fit.getParameters()[0]), 1e-16);
Assert.assertEquals(0, Math.toDegrees(fit.getParameters()[1]), 1e-16);
}
}
I'm having an issue with my function call. I'm trying to find the solution to the two-point boundary value problem x' = f(t,x) = x + 0.09 x 2 + cos(10 t) with boundary condition x(0) + x(1) - 3.0 = 0 using the secant and third-order Runge-Kutta methods and for whatever reason, my equation method gives me four errors on a single line, those being that it's not a statement, is missing two semicolons, and is missing an end parenthesis.
public class BoundaryValueProblem
{
public static double f(double t, double x)
{
return x + 0.09x^2 + Math.cos(10t);
}
public static void findZero
{
double x4;
double x5 = .7;
double x6 = 1.0;
int n = 1;
double fx;
double f1;
double f2;
double Error;
BoundaryValueProblem FZ = new BoundaryValueProblem();
f1 = FZ.f(1.0, 1.0);
f2 = FZ.f(1.0, 1.0);
System.out.println("Secant Method");
System.out.println("n: \t\t x1: \t\t x2: \t\t Error:");
while(abs(x5 + x6 - 3.0) < 1e-5)
{
x4 = x6 - f2 * ((x6 - x5)/(f2 - f1));
fx = FZ.f(1.0, 1.0);
x5 = x6;
x6 = x4;
f1 = f2;
f2 = fx;
Error = x5 + x6 - 3.0;
System.out.println(n + "\t\t" + x5 + "\t\t" + x6 + "\t\t" + Error);
n++;
}
System.out.println();
}
public void rkm(double x0, double t0, double h)
{
double x1, x2, x3;
int i=0;
double a1 = 0.5;
double a2 = 0.25;
double c0 = 2.0/3.0;
double c1 = 5.0/3.0;
double c2 = -4.0/3.0;
double b21 = -.25;
double b10 = .5;
double b20 = .5;
double stepsize = .025;
System.out.println("Runge-Kutta Method:");
System.out.println("i: \t\t h: \t\t t0: \t\t x0:");
System.out.println(i + "\t\t " + h + "\t\t " + t0 + "\t\t " + x0 );
for(i = 0; i < 40; i++)
{
x1 = x0 + h * b10 * f(t0, x0);
x2 = x0 + h * (b20 * f(t0, x0) + b21 * f(t0 + a1 * h, x1));
x3 = x0 + h * (c0 * f(t0, x0) + c1 * f(t0 + a1 * h, x1) + c2 * f(t0 + a2 * h, x2));
t0 = t0 + stepsize;
x0 = x3;
System.out.println(i + "\t\t " + h + "\t\t " + t0 + "\t\t " + x0 );
}
System.out.println();
}
public static void main(String[] args)
{
BoundaryValueProblem FZ1 = new BoundaryValueProblem();
FZ1.findZero();
BoundaryValueProblem RKM1 = new BoundaryValueProblem();
RKM1.rkm(1.0, 0.0, 0.0);
}
}
I've had it work on simpler equations but this one is not working for me. I have the rest of the code mostly correct (I believe), but I don't think it's the cause of the error since I commented it out and the errors persisted, thus I'm not focused on that. Any advice or help would be greatly appreciated.
Below is fixed code. Please remember that java unlike Octave or Matlab requires multiplication operator (*) and doesn't support pow operator (^) - you would need to use Math.pow() instead.
public class BoundaryValueProblem {
public static double f(double t, double x) {
return x + 0.09 * x * x + Math.cos(10 * t);
}
public static void findZero() {
double x4;
double x5 = .7;
double x6 = 1.0;
int n = 1;
double fx;
double f1;
double f2;
double Error;
f1 = f(1.0, 1.0);
f2 = f(1.0, 1.0);
System.out.println("Secant Method");
System.out.println("n: \t\t x1: \t\t x2: \t\t Error:");
while (Math.abs(x5 + x6 - 3.0) < 1e-5) {
x4 = x6 - f2 * ((x6 - x5) / (f2 - f1));
fx = f(1.0, 1.0);
x5 = x6;
x6 = x4;
f1 = f2;
f2 = fx;
Error = x5 + x6 - 3.0;
System.out.println(n + "\t\t" + x5 + "\t\t" + x6 + "\t\t" + Error);
n++;
}
System.out.println();
}
public void rkm(double x0, double t0, double h) {
double x1, x2, x3;
int i = 0;
double a1 = 0.5;
double a2 = 0.25;
double c0 = 2.0 / 3.0;
double c1 = 5.0 / 3.0;
double c2 = -4.0 / 3.0;
double b21 = -.25;
double b10 = .5;
double b20 = .5;
double stepsize = .025;
System.out.println("Runge-Kutta Method:");
System.out.println("i: \t\t h: \t\t t0: \t\t x0:");
System.out.println(i + "\t\t " + h + "\t\t " + t0 + "\t\t " + x0);
for (i = 0; i < 40; i++) {
x1 = x0 + h * b10 * f(t0, x0);
x2 = x0 + h * (b20 * f(t0, x0) + b21 * f(t0 + a1 * h, x1));
x3 = x0 + h * (c0 * f(t0, x0) + c1 * f(t0 + a1 * h, x1) + c2 * f(t0 + a2 * h, x2));
t0 = t0 + stepsize;
x0 = x3;
System.out.println(i + "\t\t " + h + "\t\t " + t0 + "\t\t " + x0);
}
System.out.println();
}
/**
* #param args
*/
public static void main(String[] args) {
BoundaryValueProblem FZ1 = new BoundaryValueProblem();
FZ1.findZero();
BoundaryValueProblem RKM1 = new BoundaryValueProblem();
RKM1.rkm(1.0, 0.0, 0.0);
}
}
public static void findZero// correct this. Where are parenthesis () for this method
{
double x4;
double x5 = .7;
double x6 = 1.0;
int n = 1;
double fx;
double f1;
double f2;
double Error;
BoundaryValueProblem FZ = new BoundaryValueProblem();
f1 = FZ.f(1.0, 1.0);
f2 = FZ.f(1.0, 1.0);
System.out.println("Secant Method");
System.out.println("n: \t\t x1: \t\t x2: \t\t Error:");
while(abs(x5 + x6 - 3.0) < 1e-5)
{
x4 = x6 - f2 * ((x6 - x5)/(f2 - f1));
fx = FZ.f(1.0, 1.0);
x5 = x6;
x6 = x4;
f1 = f2;
f2 = fx;
Error = x5 + x6 - 3.0;
System.out.println(n + "\t\t" + x5 + "\t\t" + x6 + "\t\t" + Error);
n++;
}
System.out.println();
}
There is a method without parentheses: public static void findZero
It should be public static void findZero()
Function findZero should have parenthesis at the end like this:
public static void findZero()
return x + 0.09x^2 + Math.cos(10t);
In Java you have to put math operator between operands so instead of 0.09x you have to write 0.09*x and instead of 10t you have to write 10*t
^ sign is XOR operator not power operator so you have to use Math.pow function (I'm guessing that's what you wanted to do)
In the end this line should look like this:
return x + Math.pow(0.09*x, 2) + Math.cos(10*t);
I'm also getting error with abs function. I don't know if you wrote that function yourself but if you didn't you should use Math.abs function
so i have a math equation that i need to use in java but for some reason my code is giving me small errors :(
the math equation is describe on this web page in the section extra credit
my current code outpouts 4000 and the answere is 4005 what am i duing wrong ?
my test class lookes like this
public class MainActivity {
public static void main(String[] args) throws Exception{
double baseMaterial =556;
int me =5;
int ml = 10;
int extraMaterial = 3444;
System.out.println(""+calculateMiniralTotal(baseMaterial,me,ml,extraMaterial));
}
public static double calculateMiniralTotal(double perfekt,int me,int ml,int extraMaterial) {
double s = (perfekt + (perfekt * (10 / (ml + 1)) / 100));
s = Math.round(s);
double r = s + (perfekt * (0.25 - (0.05 * me)));
r = Math.round(r);
double q = extraMaterial + (extraMaterial * (0.25 - (0.05 * me)));
q = Math.round(q);
//double r=q;
r = r + q;
return Math.round(r);
}
}
You are performing integer division with (10 / (ml + 1)) / 100, which in Java must result in another int. Your ml is 10, and in Java, 10 / 11 is 0, not 0.909..., and nothing is added to s.
Use a double literal or cast to double to force floating-point computations.
double s = (perfekt + (perfekt * (10.0 / (ml + 1)) / 100));
or
double s = (perfekt + (perfekt * ( (double) 10 / (ml + 1)) / 100));
Making either change makes the output:
4005.0
When you multiply a double by an int you get an int back.
public class Main
{
public static void main(String[] args)
throws Exception
{
double baseMaterial = 556;
int me = 5;
int ml = 10;
int extraMaterial = 3444;
System.out.println("" + calculateMiniralTotal(baseMaterial, me, ml, extraMaterial));
}
public static double calculateMiniralTotal(double perfekt, int me, int ml, int extraMaterial)
{
double s = (perfekt + (perfekt * (10.0 / (ml + 1)) / 100.0)); // <-- changed from 10 to 10.0 and 100 to 100.0. This way they are doubles too
s = Math.round(s);
double r = s + (perfekt * (0.25 - (0.05 * me)));
r = Math.round(r);
double q = extraMaterial + (extraMaterial * (0.25 - (0.05 * me)));
q = Math.round(q);
// double r=q;
r = r + q;
return Math.round(r);
}
}
public static ArrayList<IntPoint> getCircleLineIntersectionPoint(IntPoint pointA, IntPoint pointB, IntPoint center, int radius) {
// returns a list of intersection points between a line which passes through given points,
// pointA and pointB, and a circle described by given radius and center coordinate
double disc, A, B, C, slope, c;
double x1, x2, y1, y2;
IntPoint point1, point2;
ArrayList<IntPoint> intersections = new ArrayList<IntPoint>();
try{
slope = Util.calculateSlope(pointA, pointB);
}catch (UndefinedSlopeException e){
C = Math.pow(center.y, 2) + Math.pow(pointB.x, 2) - 2 * pointB.x * center.x + Math.pow(center.x, 2) - Math.pow(radius, 2);
B = -2 * center.y;
A = 1;
disc = Math.pow(B, 2) - 4 * 1 * C;
if (disc < 0){
return intersections;
}
else{
y1 = (-B + Math.sqrt(disc)) / (2 * A);
y2 = (-B - Math.sqrt(disc)) / (2 * A);
x1 = pointB.x;
x2 = pointB.x;
}
point1 = new IntPoint((int)x1, (int)y1);
point2 = new IntPoint((int)x2, (int)y2);
if (Util.euclideanDistance(pointA, point2) > Util.euclideanDistance(pointA, point1)){
intersections.add(point1);
}
else{
intersections.add(point2);
}
return intersections;
}
if (slope == 0){
C = Math.pow(center.x, 2) + Math.pow(center.y, 2) + Math.pow(pointB.y, 2) - 2 * pointB.y * center.y - Math.pow(radius, 2);
B = -2 * center.x;
A = 1;
disc = Math.pow(B, 2) - 4 * 1 * C;
if (disc < 0){
return intersections;
}
else{
x1 = (-B + Math.sqrt(disc)) / (2*A);
x2 = (-B - Math.sqrt(disc)) / (2*A);
y1 = pointB.y;
y2 = pointB.y;
}
}
else{
c = slope * pointA.x + pointA.y;
B = (2 * center.x + 2 * center.y * slope + 2 * c * slope);
A = 1 + Math.pow(slope, 2);
C = (Math.pow(center.x, 2) + Math.pow(c, 2) + 2 * center.y * c + Math.pow(center.y, 2) - Math.pow(radius, 2));
disc = Math.pow(B, 2) - (4 * A * C);
if (disc < 0){
return intersections;
}
else{
x1 = (-B + Math.sqrt(disc)) / (2 * A);
x2 = (-B - Math.sqrt(disc)) / (2 * A);
y1 = slope * x1 - c;
y2 = slope * x2 - c;
}
}
point1 = new IntPoint((int)x1, (int)y1);
point2 = new IntPoint((int)x2, (int)y2);
if (Util.euclideanDistance(pointA, point2) > Util.euclideanDistance(pointA, point1)){
//if (Util.angleBetween(pointA, pointB, point1) < Math.PI/2){
intersections.add(point1);
//}
}
else{
//if (Util.angleBetween(pointA, pointB, point1) < Math.PI/2){
intersections.add(point2);
//}
}
return intersections;
}
I am using the above algorithm to test for intersection between a circle and a line. It works fine sometimes but at other times it fails. The code represents the equation which is derived from solving for x simultaneously from circle and line equations (x-a)^+(y-b)^2=r^2 and y = mx - mx1 + y1. Has anyone got an idea where I am going wrong either in my maths or elsewhere?
Your calculations seem quite long, and I do not see the use of the different cases you test.
Anyway, since I found the problem interesting I attempted to solve it myself and came up with the following. Feel free to replace double radius by int radius and use IntPoints, but be aware that every time you cast, as discussed in the comments, results that are not exact integer intersection points will become wrong.
The background of the calculations performed is this: From point A, a scaled version of vector AB points to a point on the circle. That point has distance radius from center. Hence, |AC + scalingFactor * AB|=r.
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class CircleLine {
public static List<Point> getCircleLineIntersectionPoint(Point pointA,
Point pointB, Point center, double radius) {
double baX = pointB.x - pointA.x;
double baY = pointB.y - pointA.y;
double caX = center.x - pointA.x;
double caY = center.y - pointA.y;
double a = baX * baX + baY * baY;
double bBy2 = baX * caX + baY * caY;
double c = caX * caX + caY * caY - radius * radius;
double pBy2 = bBy2 / a;
double q = c / a;
double disc = pBy2 * pBy2 - q;
if (disc < 0) {
return Collections.emptyList();
}
// if disc == 0 ... dealt with later
double tmpSqrt = Math.sqrt(disc);
double abScalingFactor1 = -pBy2 + tmpSqrt;
double abScalingFactor2 = -pBy2 - tmpSqrt;
Point p1 = new Point(pointA.x - baX * abScalingFactor1, pointA.y
- baY * abScalingFactor1);
if (disc == 0) { // abScalingFactor1 == abScalingFactor2
return Collections.singletonList(p1);
}
Point p2 = new Point(pointA.x - baX * abScalingFactor2, pointA.y
- baY * abScalingFactor2);
return Arrays.asList(p1, p2);
}
static class Point {
double x, y;
public Point(double x, double y) { this.x = x; this.y = y; }
#Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
public static void main(String[] args) {
System.out.println(getCircleLineIntersectionPoint(new Point(-3, -3),
new Point(-3, 3), new Point(0, 0), 5));
System.out.println(getCircleLineIntersectionPoint(new Point(0, -2),
new Point(1, -2), new Point(1, 1), 5));
System.out.println(getCircleLineIntersectionPoint(new Point(1, -1),
new Point(-1, 0), new Point(-1, 1), 5));
System.out.println(getCircleLineIntersectionPoint(new Point(-3, -3),
new Point(-2, -2), new Point(0, 0), Math.sqrt(2)));
}
Here a solution with import javax.vecmath.Vector2d;
static Vector2d[] circleLineIntersection1(Vector2d a, Vector2d b, Vector2d o, double radius) {
Vector2d p1 = new Vector2d(a);
Vector2d p2 = new Vector2d(b);
p1.sub(o);
p2.sub(o);
Vector2d d = new Vector2d();
d.sub(p2, p1);
double det = p1.x * p2.y - p2.x * p1.y;
double dSq = d.lengthSquared();
double discrimant = radius * radius * dSq - det * det;
if (discrimant < 0) {
return new Vector2d[0];
}
if (discrimant == 0) {
Vector2d[] t = new Vector2d[1];
t[0] = new Vector2d(det * d.y / dSq + o.x, -det * d.x / dSq + o.y);
return t;
}
double discSqrt = Math.sqrt(discrimant);
double sgn = 1;
if (d.y < 0) {
sgn = -1;
}
Vector2d[] t = new Vector2d[2];
t[0] = new Vector2d((det * d.y + sgn * d.x * discSqrt) / dSq + o.x, (-det * d.x + Math.abs(d.y) * discSqrt) / dSq + o.y);
t[1] = new Vector2d((det * d.y - sgn * d.x * discSqrt) / dSq + o.x, (-det * d.x - Math.abs(d.y) * discSqrt) / dSq + o.y);
return t;
}