Interpolates between two end points. - Java java.lang

Java examples for java.lang:Math Geometry Line

Description

Interpolates between two end points.

Demo Code

/**//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;
    }
}

Related Tutorials