org.shredzone.commons.suncalc.util.QuadraticInterpolation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of commons-suncalc Show documentation
Show all versions of commons-suncalc Show documentation
Compute sun and moon phases
/*
* Shredzone Commons - suncalc
*
* Copyright (C) 2017 Richard "Shred" Körber
* http://commons.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
package org.shredzone.commons.suncalc.util;
import static java.lang.Math.abs;
import static java.lang.Math.sqrt;
/**
* Calculates the roots and extremum of a quadratic equation.
*/
public class QuadraticInterpolation {
private final double xe;
private final double ye;
private final double root1;
private final double root2;
private final int nRoot;
private final boolean maximum;
/**
* Creates a new quadratic equation.
*
* @param yMinus
* y at x == -1
* @param y0
* y at x == 0
* @param yPlus
* y at x == 1
*/
public QuadraticInterpolation(double yMinus, double y0, double yPlus) {
double a = 0.5 * (yPlus + yMinus) - y0;
double b = 0.5 * (yPlus - yMinus);
double c = y0;
xe = -b / (2.0 * a);
ye = (a * xe + b) * xe + c;
maximum = a < 0.0;
double dis = b * b - 4.0 * a * c;
int rootCount = 0;
if (dis >= 0.0) {
double dx = 0.5 * sqrt(dis) / abs(a);
root1 = xe - dx;
root2 = xe + dx;
if (abs(root1) <= 1.0) {
rootCount++;
}
if (abs(root2) <= 1.0) {
rootCount++;
}
} else {
root1 = Double.NaN;
root2 = Double.NaN;
}
nRoot = rootCount;
}
/**
* Returns X of extremum. Can be outside [-1 .. 1].
*
* @return X
*/
public double getXe() {
return xe;
}
/**
* Returns the Y value at the extremum.
*
* @return Y
*/
public double getYe() {
return ye;
}
/**
* Returns the first root that was found.
*
* @return X of first root
*/
public double getRoot1() {
return root1 < -1.0 ? root2 : root1;
}
/**
* Returns the second root that was found.
*
* @return X of second root
*/
public double getRoot2() {
return root2;
}
/**
* Returns the number of roots found in [-1 .. 1].
*
* @return Number of roots
*/
public int getNumberOfRoots() {
return nRoot;
}
/**
* Returns whether the extremum is a minimum or a maximum.
*
* @return {@code true}: Extremum at xe is a maximum. {@code false}: Extremum at xe is
* a minimum.
*/
public boolean isMaximum() {
return maximum;
}
}