Package net.royawesome.jlibnoise.module.modifier

Source Code of net.royawesome.jlibnoise.module.modifier.Terrace

/* 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 net.royawesome.jlibnoise.Utils;
import net.royawesome.jlibnoise.exception.NoModuleException;
import net.royawesome.jlibnoise.module.Module;

public class Terrace extends Module {
  /// Number of control points stored in this noise module.
  int controlPointCount = 0;

  /// Determines if the terrace-forming curve between all control points
  /// is inverted.
  boolean invertTerraces = false;

  /// Array that stores the control points.
  double[] ControlPoints = new double[0];

  public Terrace() {
    super(1);
  }

  public boolean isInvertTerraces() {
    return invertTerraces;
  }

  public void setInvertTerraces(boolean invertTerraces) {
    this.invertTerraces = invertTerraces;
  }

  public int getControlPointCount() {
    return controlPointCount;
  }

  public double[] getControlPoints() {
    return ControlPoints;
  }

  public void AddControlPoint(double value) {
    int insertionPos = FindInsertionPos(value);
    InsertAtPos(insertionPos, value);
  }

  public void ClearAllControlPoints() {
    ControlPoints = null;
    controlPointCount = 0;

  }

  public void MakeControlPoints(int controlPointCount) {
    if (controlPointCount < 2) {
      throw new IllegalArgumentException("Must have more than 2 control points");
    }

    ClearAllControlPoints();

    double terraceStep = 2.0 / (controlPointCount - 1.0);
    double curValue = -1.0;
    for (int i = 0; i < controlPointCount; i++) {
      AddControlPoint(curValue);
      curValue += terraceStep;
    }

  }

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

  }

  protected void InsertAtPos(int insertionPos, double value) {
    // Make room for the new control point at the specified position within
    // the control point array.  The position is determined by the value of
    // the control point; the control points must be sorted by value within
    // that array.
    double[] newControlPoints = new double[controlPointCount + 1];
    for (int i = 0; i < controlPointCount; i++) {
      if (i < insertionPos) {
        newControlPoints[i] = ControlPoints[i];
      } else {
        newControlPoints[i + 1] = ControlPoints[i];
      }
    }

    ControlPoints = newControlPoints;
    ++controlPointCount;

    // Now that we've made room for the new control point within the array,
    // add the new control point.
    ControlPoints[insertionPos] = value;

  }

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

  @Override
  public double GetValue(double x, double y, double z) {
    if (SourceModule[0] == null)
      throw new NoModuleException();

    // 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 a value
    // larger than the output value from the source module.
    int indexPos;
    for (indexPos = 0; indexPos < controlPointCount; indexPos++) {
      if (sourceModuleValue < ControlPoints[indexPos]) {
        break;
      }
    }

    // Find the two nearest control points so that we can map their values
    // onto a quadratic curve.
    int index0 = Utils.ClampValue(indexPos - 1, 0, controlPointCount - 1);
    int index1 = Utils.ClampValue(indexPos, 0, controlPointCount - 1);

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

    // Compute the alpha value used for linear interpolation.
    double value0 = ControlPoints[index0];
    double value1 = ControlPoints[index1];
    double alpha = (sourceModuleValue - value0) / (value1 - value0);
    if (invertTerraces) {
      alpha = 1.0 - alpha;
      double temp = value0;
      value0 = value1;
      value1 = temp;
    }

    // Squaring the alpha produces the terrace effect.
    alpha *= alpha;

    // Now perform the linear interpolation given the alpha value.
    return Utils.LinearInterp(value0, value1, alpha);

  }

}
TOP

Related Classes of net.royawesome.jlibnoise.module.modifier.Terrace

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.