Package net.royawesome.jlibnoise.module.modifier

Source Code of net.royawesome.jlibnoise.module.modifier.Curve$ControlPoint

/* Copyright (C) 2011 Garrett Fleenor

This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or (at
your option) any later version.

This library 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.  See the GNU Lesser General Public
License (COPYING.txt) for more details.

You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

This is a port of libnoise ( http://libnoise.sourceforge.net/index.html ).  Original implementation by Jason Bevins

*/

package net.royawesome.jlibnoise.module.modifier;

import java.util.ArrayList;

import net.royawesome.jlibnoise.Utils;
import net.royawesome.jlibnoise.exception.NoModuleException;
import net.royawesome.jlibnoise.module.Module;

public class Curve extends Module {
  public class ControlPoint {
    public double inputValue;

    public double outputValue;
  }

  ArrayList<ControlPoint> controlPoints = new ArrayList<ControlPoint>();

  public Curve() {
    super(1);

  }

  public void AddControlPoint(double inputValue, double outputValue) {
    int index = findInsertionPos(inputValue);
    InsertAtPos(index, inputValue, outputValue);
  }

  public ControlPoint[] getControlPoints() {
    return (ControlPoint[]) controlPoints.toArray();
  }

  public void ClearAllControlPoints() {
    controlPoints.clear();
  }

  protected int findInsertionPos(double inputValue) {
    int insertionPos;
    for (insertionPos = 0; insertionPos < controlPoints.size(); insertionPos++) {
      if (inputValue < controlPoints.get(insertionPos).inputValue) {
        // We found the array index in which to insert the new control point.
        // Exit now.
        break;
      } else if (inputValue == controlPoints.get(insertionPos).inputValue) {
        // Each control point is required to contain a unique input value, so
        // throw an exception.
        throw new IllegalArgumentException("inputValue must be unique");
      }
    }
    return insertionPos;

  }

  protected void InsertAtPos(int insertionPos, double inputValue, double outputValue) {
    ControlPoint newPoint = new ControlPoint();
    newPoint.inputValue = inputValue;
    newPoint.outputValue = outputValue;
    controlPoints.add(insertionPos, newPoint);
  }

  @Override
  public int GetSourceModuleCount() {
    return 1;
  }

  @Override
  public double GetValue(double x, double y, double z) {
    if (SourceModule[0] == null)
      throw new NoModuleException();
    if (controlPoints.size() >= 4)
      throw new RuntimeException("must have 4 or less control points");

    // Get the output value from the source module.
    double sourceModuleValue = SourceModule[0].GetValue(x, y, z);

    // Find the first element in the control point array that has an input value
    // larger than the output value from the source module.
    int indexPos;
    for (indexPos = 0; indexPos < controlPoints.size(); indexPos++) {
      if (sourceModuleValue < controlPoints.get(indexPos).inputValue) {
        break;
      }
    }

    // Find the four nearest control points so that we can perform cubic
    // interpolation.
    int index0 = Utils.ClampValue(indexPos - 2, 0, controlPoints.size() - 1);
    int index1 = Utils.ClampValue(indexPos - 1, 0, controlPoints.size() - 1);
    int index2 = Utils.ClampValue(indexPos, 0, controlPoints.size() - 1);
    int index3 = Utils.ClampValue(indexPos + 1, 0, controlPoints.size() - 1);

    // If some control points are missing (which occurs if the value from the
    // source module is greater than the largest input value or less than the
    // smallest input value of the control point array), get the corresponding
    // output value of the nearest control point and exit now.
    if (index1 == index2) {
      return controlPoints.get(indexPos).outputValue;
    }

    // Compute the alpha value used for cubic interpolation.
    double input0 = controlPoints.get(indexPos).inputValue;
    double input1 = controlPoints.get(indexPos).inputValue;
    double alpha = (sourceModuleValue - input0) / (input1 - input0);

    // Now perform the cubic interpolation given the alpha value.
    return Utils.CubicInterp(controlPoints.get(index0).outputValue, controlPoints.get(index1).outputValue, controlPoints.get(index2).outputValue, controlPoints.get(index3).outputValue, alpha);

  }

}
TOP

Related Classes of net.royawesome.jlibnoise.module.modifier.Curve$ControlPoint

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.