Java examples for java.lang:Math Geometry Line
Interpolates between two end points.
/**//from w ww. j a va2 s . co m * Java Modular Image Synthesis Toolkit (JMIST) * Copyright (C) 2008-2013 Bradley W. Kimmel * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ //package com.java2s; import java.util.Arrays; import java.util.Collections; import java.util.List; public class Main { /** * Interpolates between two end points. * @param a The end point at <code>t = 0</code>. * @param b The end point at <code>t = 1</code>. * @param t The value at which to interpolate. * @return The value that is the fraction <code>t</code> of the way from * <code>a</code> to <code>b</code>: <code>(1-t)a + tb</code>. */ public static double interpolate(double a, double b, double t) { return a + t * (b - a); } /** * Interpolates between two points on a line. * @param x0 The x-coordinate of the first point. * @param y0 The y-coordinate of the first point. * @param x1 The x-coordinate of the second point. * @param y1 The y-coordinate of the second point. * @param x The x-coordinate at which to interpolate. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolate(double x0, double y0, double x1, double y1, double x) { double t = (x - x0) / (x1 - x0); return interpolate(y0, y1, t); } /** * Interpolates a piecewise linear curve. * @param xs An array of x-coordinates (this must be sorted in ascending * order). * @param ys An array of the y-coordinates (must be of the same length as * <code>xs</code>, or one less if <code>wrap == true</code>). * @param x The x-coordinate at which to interpolate. * @param wrap A value indicating whether the curve is periodic. * @return The y-coordinate corresponding to <code>x0</code>. */ public static double interpolate(double[] xs, double[] ys, double x, boolean wrap) { if (wrap) { return interpolateWrapped(xs, ys, x); } else { return interpolate(xs, ys, x); } } /** * Interpolates a piecewise linear curve. * @param xs An array of x-coordinates (this must be sorted in ascending * order). * @param ys An array of the y-coordinates (must be of the same length as * <code>xs</code>). * @param x The x-coordinate at which to interpolate. * @return The y-coordinate corresponding to <code>x0</code>. */ public static double interpolate(double[] xs, double[] ys, double x) { if (x <= xs[0]) { return ys[0]; } if (x >= xs[xs.length - 1]) { return ys[xs.length - 1]; } int index = Arrays.binarySearch(xs, x); if (index < 0) { index = -(index + 1); } while (index < xs.length - 1 && !(x < xs[index + 1])) { index++; } assert (index < xs.length - 1); return interpolate(xs[index - 1], ys[index - 1], xs[index], ys[index], x); } /** * Interpolates a piecewise linear curve. * @param xs An array of x-coordinates (this must be sorted in ascending * order). * @param ys An array of the y-coordinates (must be of the same length as * <code>xs</code>, or one less if <code>wrap == true</code>). * @param x The x-coordinate at which to interpolate. * @param wrap A value indicating whether the curve is periodic. * @return The y-coordinate corresponding to <code>x0</code>. */ public static double interpolate(List<Double> xs, List<Double> ys, double x, boolean wrap) { if (wrap) { return interpolateWrapped(xs, ys, x); } else { return interpolate(xs, ys, x); } } /** * Interpolates a piecewise linear curve. * @param xs An array of x-coordinates (this must be sorted in ascending * order). * @param ys An array of the y-coordinates (must of length of * <code>xs.size() - 1</code>). * @param x The x-coordinate at which to interpolate. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolate(List<Double> xs, List<Double> ys, double x) { if (x <= xs.get(0)) { return ys.get(0); } int n = xs.size(); if (x >= xs.get(n - 1)) { return ys.get(n - 1); } int index = Collections.binarySearch(xs, x); if (index < 0) { index = -(index + 1); } while (index < n - 1 && !(x < xs.get(index + 1))) { index++; } assert (index < n - 1); return interpolate(xs.get(index - 1), ys.get(index - 1), xs.get(index), ys.get(index), x); } /** * Interpolates a piecewise linear curve. * @param x0 The minimum value in the domain. * @param x1 The maximum value in the domain (must not be less than * <code>x0</code>). * @param y An array of the y-coordinates (must have at least two elements). * @param x The x-coordinate at which to interpolate. * @param wrap A value indicating whether the curve is periodic. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolate(double x0, double x1, double[] y, double x, boolean wrap) { if (wrap) { return interpolateWrapped(x0, x1, y, x); } else { return interpolate(x0, x1, y, x); } } /** * Interpolates a piecewise linear curve. * @param x0 The minimum value in the domain. * @param x1 The maximum value in the domain (must not be less than * <code>x0</code>). * @param y An array of the y-coordinates (must have at least two elements). * @param x The x-coordinate at which to interpolate. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolate(double x0, double x1, double[] y, double x) { if (x <= x0) { return y[0]; } if (x >= x1) { return y[y.length - 1]; } double t = (y.length - 1) * ((x - x0) / (x1 - x0)); int i = (int) Math.floor(t); return interpolate(y[i], y[i + 1], t - i); } /** * Interpolates a piecewise linear curve. * @param x0 The minimum value in the domain. * @param x1 The maximum value in the domain (must not be less than * <code>x0</code>). * @param y An array of the y-coordinates (must have at least two elements * if <code>wrap == false</code>). * @param x The x-coordinate at which to interpolate. * @param wrap A value indicating whether the curve is periodic. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolate(double x0, double x1, List<Double> y, double x, boolean wrap) { if (wrap) { return interpolateWrapped(x0, x1, y, x); } else { return interpolate(x0, x1, y, x); } } /** * Interpolates a piecewise linear curve. * @param x0 The minimum value in the domain. * @param x1 The maximum value in the domain (must not be less than * <code>x0</code>). * @param y An array of the y-coordinates (must have at least two elements). * @param x The x-coordinate at which to interpolate. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolate(double x0, double x1, List<Double> y, double x) { if (x <= x0) { return y.get(0); } if (x > x1) { return y.get(y.size() - 1); } double t = (y.size() - 1) * ((x - x0) / (x1 - x0)); int i = (int) Math.floor(t); return interpolate(y.get(i), y.get(i + 1), t - i); } /** * Interpolates a periodic piecewise linear curve. * @param xs An array of x-coordinates (this must be sorted in ascending * order). * @param ys An array of the y-coordinates (must have length * <code>xs.length - 1</code>). * @param x The x-coordinate at which to interpolate. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolateWrapped(double[] xs, double[] ys, double x) { int n = xs.length; double x0 = xs[0]; double x1 = xs[n - 1]; x -= (x1 - x0) * Math.floor((x - x0) / (x1 - x0)); assert (inRangeCO(x, x0, x1)); int index = Arrays.binarySearch(xs, x); if (index < 0) { index = -(index + 1); } while (index < n - 1 && !(x < xs[index + 1])) { index++; } assert (index < n - 1); int i = index - 1; int j = index; if (j == n - 1) { j = 0; } return interpolate(xs[i], ys[i], xs[index], ys[j], x); } /** * Interpolates a piecewise linear curve. * @param xs An array of x-coordinates (this must be sorted in ascending * order). * @param ys An array of the y-coordinates (must be of the same length as * <code>xs</code>, or one less if <code>wrap == true</code>). * @param x The x-coordinate at which to interpolate. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolateWrapped(List<Double> xs, List<Double> ys, double x) { int n = xs.size(); double x0 = xs.get(0); double x1 = xs.get(n - 1); x -= (x1 - x0) * Math.floor((x - x0) / (x1 - x0)); assert (inRangeCO(x, x0, x1)); int index = Collections.binarySearch(xs, x); if (index < 0) { index = -(index + 1); } while (index < n - 1 && !(x < xs.get(index + 1))) { index++; } assert (index < n - 1); int i = index - 1; int j = index; if (j == n - 1) { j = 0; } return interpolate(xs.get(i), ys.get(i), xs.get(index), ys.get(j), x); } /** * Interpolates a periodic piecewise linear curve. * @param x0 The minimum value in the domain. * @param x1 The maximum value in the domain (must not be less than * <code>x0</code>). * @param y An array of the y-coordinates. * @param x The x-coordinate at which to interpolate. * @param wrap A value indicating whether the curve is periodic. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolateWrapped(double x0, double x1, double[] y, double x) { double t = (x - x0) / (x1 - x0); t -= Math.floor(t); t *= y.length; int i = (int) Math.floor(t); int j = i + 1; if (j == y.length) { j = 0; } assert (0 <= i && i < y.length); return interpolate(y[i], y[j], t - i); } /** * Interpolates a periodic piecewise linear curve. * @param x0 The minimum value in the domain. * @param x1 The maximum value in the domain (must not be less than * <code>x0</code>). * @param y An array of the y-coordinates. * @param x The x-coordinate at which to interpolate. * @return The y-coordinate corresponding to <code>x</code>. */ public static double interpolateWrapped(double x0, double x1, List<Double> y, double x) { double t = (x - x0) / (x1 - x0); t -= Math.floor(t); t *= y.size(); int i = (int) Math.floor(t); int j = i + 1; if (j == y.size()) { j = 0; } assert (0 <= i && i < y.size()); return interpolate(y.get(i), y.get(j), t - i); } /** * Determines whether {@code x} falls within the interval * {@code [minimum, maximum)}. * @param x The value to check. * @param minimum The lower bound of the interval to check against. * @param maximum The upper bound of the interval to check against. * @return A value indicating whether {@code x} is contained in the * interval {@code [minimum, maximum)}. */ public static boolean inRangeCO(double x, double minimum, double maximum) { return minimum <= x && x < maximum; } }