Add Spectrum class with an implementation
This commit is contained in:
parent
8b512a5604
commit
70f01a69c4
|
@ -2,13 +2,13 @@
|
||||||
<library name="google.guava" type="repository">
|
<library name="google.guava" type="repository">
|
||||||
<properties maven-id="com.google.guava:guava:RELEASE" />
|
<properties maven-id="com.google.guava:guava:RELEASE" />
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$PROJECT_DIR$/lib/guava-31.1-jre.jar!/" />
|
<root url="jar://$PROJECT_DIR$/lib/guava-32.1.2-jre.jar!/" />
|
||||||
<root url="jar://$PROJECT_DIR$/lib/failureaccess-1.0.1.jar!/" />
|
<root url="jar://$PROJECT_DIR$/lib/failureaccess-1.0.1.jar!/" />
|
||||||
<root url="jar://$PROJECT_DIR$/lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar!/" />
|
<root url="jar://$PROJECT_DIR$/lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar!/" />
|
||||||
<root url="jar://$PROJECT_DIR$/lib/jsr305-3.0.2.jar!/" />
|
<root url="jar://$PROJECT_DIR$/lib/jsr305-3.0.2.jar!/" />
|
||||||
<root url="jar://$PROJECT_DIR$/lib/checker-qual-3.12.0.jar!/" />
|
<root url="jar://$PROJECT_DIR$/lib/checker-qual-3.33.0.jar!/" />
|
||||||
<root url="jar://$PROJECT_DIR$/lib/error_prone_annotations-2.11.0.jar!/" />
|
<root url="jar://$PROJECT_DIR$/lib/error_prone_annotations-2.18.0.jar!/" />
|
||||||
<root url="jar://$PROJECT_DIR$/lib/j2objc-annotations-1.3.jar!/" />
|
<root url="jar://$PROJECT_DIR$/lib/j2objc-annotations-2.8.jar!/" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES />
|
<SOURCES />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_19" default="true" project-jdk-name="liberica-19" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_20" default="true" project-jdk-name="liberica-20" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
93
src/xyz/marsavic/gfxlab/Spectrum.java
Normal file
93
src/xyz/marsavic/gfxlab/Spectrum.java
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
package xyz.marsavic.gfxlab;
|
||||||
|
|
||||||
|
import javafx.util.Pair;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Spectrum {
|
||||||
|
static final double minWavelength = 380;
|
||||||
|
static final double maxWavelength = 750;
|
||||||
|
public double at(double wavelength);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DoublePairKeyComparator implements Comparator<Pair<Double, Double>> {
|
||||||
|
@Override
|
||||||
|
public int compare(Pair<Double, Double> o1, Pair<Double, Double> o2) {
|
||||||
|
double k1 = o1.getKey(), k2 = o2.getKey();
|
||||||
|
if (k1 > k2)
|
||||||
|
return 1;
|
||||||
|
else if (k1 < k2) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SplineSpectrum implements Spectrum {
|
||||||
|
Pair<Double, Double>[] samples;
|
||||||
|
double[] m;
|
||||||
|
|
||||||
|
public SplineSpectrum(Pair<Double, Double>[] samples) {
|
||||||
|
if (samples == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
this.samples = samples;
|
||||||
|
int n = samples.length;
|
||||||
|
|
||||||
|
double[] d = new double[n - 1];
|
||||||
|
m = new double[n];
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 1; i < samples.length; i++) {
|
||||||
|
double h = samples[i].getKey() - samples[i - 1].getKey();
|
||||||
|
if (h <= 0.0)
|
||||||
|
throw new IllegalArgumentException("Samples must have strictly increasing x coordinates.");
|
||||||
|
d[i] = (samples[i].getValue() - samples[i - 1].getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
m[0] = d[0];
|
||||||
|
for (int i = 1; i < n - 1; i++) {
|
||||||
|
if (d[i] == 0.0) {
|
||||||
|
m[i] = 0.0;
|
||||||
|
m[i + 1] = 0.0;
|
||||||
|
} else {
|
||||||
|
double a = m[i] / d[i];
|
||||||
|
double b = m[i + 1] / d[i];
|
||||||
|
double h = a*a+b*b;
|
||||||
|
if (h > 9.0) {
|
||||||
|
double t = 3.0 / h;
|
||||||
|
m[i] = t * a * d[i];
|
||||||
|
m[i + 1] = t * b * d[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double at(double wavelength) {
|
||||||
|
final int n = samples.length;
|
||||||
|
|
||||||
|
if (wavelength <= samples[0].getKey()) {
|
||||||
|
return samples[0].getValue();
|
||||||
|
}
|
||||||
|
if (wavelength >= samples[n-1].getKey()) {
|
||||||
|
return samples[n-1].getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
Double.valueOf(wavelength);
|
||||||
|
int i = Arrays.binarySearch(samples,
|
||||||
|
new Pair<Double, Double>(Double.valueOf(wavelength), null),
|
||||||
|
new DoublePairKeyComparator());
|
||||||
|
if (i >= 0) {
|
||||||
|
return samples[i].getValue();
|
||||||
|
}
|
||||||
|
i = -(i+1);
|
||||||
|
double h = samples[i+1].getKey() - samples[i].getKey();
|
||||||
|
double t = (wavelength - samples[i].getKey()) / h;
|
||||||
|
return (samples[i].getValue() * (1 + 2*t) + h*m[i]*t) * (1 - t) * (1 - t)
|
||||||
|
+ (samples[i+1].getValue() * (3 - 2*t) + h * m[i+1] * (t - 1)) * t * t;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue