All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tinfour.common.Thresholds Maven / Gradle / Ivy

/*
 * Copyright 2014 Gary W. Lucas.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * -----------------------------------------------------------------------
 *
 * Revision History:
 * Date    Name       Description
 * ------  ---------  -------------------------------------------------
 * 05/2014 G. Lucas   Created
 *
 * Notes: This class collects fragments of code from the various methods/classes
 * in the TIN family into a single unified (and hopefully consistent)
 * class.
 *
 * -----------------------------------------------------------------------
 */
package org.tinfour.common;

/**
 * Provides a standard calculation of threshold values appropriate for use in an
 * incremental TIN implementation based on nominal point spacing.
 * With the exception of vertex tolerance, all thresholds are computed using
 * a small multiplier times the Unit of Least Precision (ULP) computed
 * from the nominal point spacing.  The vertex tolerance is a fixed fraction
 * of the nominal point spacing.
 */
public class Thresholds {

  /** Factor for computing precision threshold. */
  public static final double PRECISION_THRESHOLD_FACTOR = 256;
  /** Factor for computing the half-plane threshold. */
  public static final double HALF_PLANE_THRESHOLD_FACTOR = 256.0;
  /** Factor for computing the delaunay threshold. */
  public static final double DELAUNAY_THRESHOLD_FACTOR = 256.0;
  /** Factor for computing the in-circle threshold. */
  public static final double IN_CIRCLE_THRESHOLD_FACTOR = 1024 * 1024;
  /** Factor for computing the vertex tolerance. */
  public static final double VERTEX_TOLERANCE_FACTOR_DEFAULT = 1.0e+5;

  /**
   * The nominal point spacing value specified in the constructor.
   * In general, this value is a rough estimate of the
   * mean distance between neighboring points (or vertices).
   */
  private final double nominalPointSpacing;
  /**
   * A threshold value giving guidelines for the smallest absolute value
   * that can be used in geometric calculations without excessive loss
   * of precision. This value is based on general assumptions about the
   * what constitutes a significant distance given the nominal point
   * spacing of the vertices in the TIN.
   */
  private final double precisionThreshold;
  /**
   * A threshold value giving guidelines for the smallest absolute value
   * result that can be trusted in geometric calculations for determining
   * on which side of a point a plane lies (the "half-plane calculation").
   * If the absolute value of the result is smaller than this threshold,
   * extended-precision arithmetic is advised.
   */
  private final double halfPlaneThreshold;

  /**
   * The computed value for the threshold that indicates
   * when an ordinary precision calculation for the in-circle criterion
   * may be inaccurate and an extended precision calculation should be used.
   */
  private final double inCircleThreshold;

  /**
   * The computed value for evaluating whether a triangle pair is
   * within sufficient tolerance when testing to see if they approximately
   * meet the Delaunay criterion using the in-circle calculation.
   * A positive (non-zero) in-circle value indicates that the pair
   * violates the criterion, but for case where floating-point limitations
   * may result in conflicts, a very small positive value may be acceptable
   * for approximation purposes.
   */
  private final double delaunayThreshold;

  /**
   * A threshold value indicating the distance at which a pair
   * of (x,y) coordinates will be treated as effectively a match for
   * a vertex.
   */
  private final double vertexTolerance;
  /**
   * The square of the vertex tolerance value.
   */
  private final double vertexTolerance2; // square of vertexTolerance;

  /**
   * Constructs thresholds for a nominal point spacing of 1.
   */
  public Thresholds() {
    nominalPointSpacing = 1.0;
    double ulp = Math.ulp(nominalPointSpacing);
    precisionThreshold = PRECISION_THRESHOLD_FACTOR * ulp;
    halfPlaneThreshold = HALF_PLANE_THRESHOLD_FACTOR * precisionThreshold;
    inCircleThreshold = IN_CIRCLE_THRESHOLD_FACTOR * precisionThreshold;
    delaunayThreshold = DELAUNAY_THRESHOLD_FACTOR * precisionThreshold;
    vertexTolerance = nominalPointSpacing / VERTEX_TOLERANCE_FACTOR_DEFAULT;
    vertexTolerance2 = vertexTolerance * vertexTolerance;
  }

  /**
   * Constructs threshold values for the specified nominalPointSpacing.
   * In general, the nominal point spacing is a rough estimate of the
   * mean distance between neighboring points (or vertices). It is used
   * for estimating threshold values for logic used by the IncrementalTin
   * and related classes. A perfect value is not necessary. An estimate
   * within a couple orders of magnitude of the actual value is sufficient.
   *
   * @param nominalPointSpacing a positive, non-zero value
   */
  public Thresholds(final double nominalPointSpacing) {
    if (nominalPointSpacing <= 0) {
      throw new IllegalArgumentException(
        "Nominal point spacing specification "
        + nominalPointSpacing
        + " is not greater than zero");
    }
    this.nominalPointSpacing = nominalPointSpacing;
    double ulp = Math.ulp(nominalPointSpacing);
    precisionThreshold = PRECISION_THRESHOLD_FACTOR * ulp;
    halfPlaneThreshold = HALF_PLANE_THRESHOLD_FACTOR * precisionThreshold;
    inCircleThreshold = IN_CIRCLE_THRESHOLD_FACTOR * precisionThreshold;
    delaunayThreshold = DELAUNAY_THRESHOLD_FACTOR * precisionThreshold;

    vertexTolerance = nominalPointSpacing / VERTEX_TOLERANCE_FACTOR_DEFAULT;
    vertexTolerance2 = vertexTolerance * vertexTolerance;
  }

  /**
   * Gets the threshold value indicating when an extended-precision
   * calculation must be used for the in-circle determination.
   *
   * @return a positive value scaled according to the nominal
   * point spacing of the TIN.
   */
  public double getInCircleThreshold() {
    return inCircleThreshold;
  }

  /**
   * Gets a threshold value indicating the distance at which a pair
   * of (x,y) coordinates will be treated as effectively a match for
   * a vertex.
   *
   * @return a distance in the system of units consistent with the TIN.
   */
  public double getVertexTolerance() {
    return vertexTolerance;
  }

  /**
   * Gets a threshold value indicating the square of the distance at which a
   * pair of (x,y) coordinates will be treated as effectively a match for
   * a vertex.
   *
   * @return a distance squared in the system of units consistent with the
   * TIN.
   */
  public double getVertexTolerance2() {
    return vertexTolerance2;
  }

  /**
   * Get a threshold value giving guidelines for the smallest absolute value
   * result from a geometric calculations that can be accepted without
   * concern for an excessive loss of precision. This value is based on
   * general assumptions about the what constitutes a significant distance
   * given the nominal point spacing of the vertices in the TIN.
   *
   * @return a small, positive value.
   */
  public double getPrecisionThreshold() {
    return precisionThreshold;
  }

  /**
   * Gets the nominal point spacing value specified in the constructor.
   * In general, this value is a rough estimate of the
   * mean distance between neighboring points (or vertices).
   *
   * @return a positive, non-zero value.
   */
  public double getNominalPointSpacing() {
    return nominalPointSpacing;
  }

  /**
   * Gets the computed value for evaluating whether a triangle pair is
   * within sufficient tolerance when testing to see if they approximately
   * meet the Delaunay criterion using the in-circle calculation.
   * A positive (non-zero) in-circle value indicates that the pair
   * violates the criterion, but for case where floating-point limitations
   * may result in conflicts, a very small positive value may be acceptable
   * for approximation purposes.
   * 

* This value is primarily used in test procedures that evaluate * the correctness of a TIN constructed by the IncrementalTin class. * * @return A positive value much smaller than the nominal point spacing. */ public double getDelaunayThreshold() { return delaunayThreshold; } /** * Gets a threshold value giving guidelines for the smallest absolute value * result that can be trusted in geometric calculations for determining * on which side of a point a plane lies (the "half-plane calculation"). * If the absolute value of the result is smaller than this threshold, * extended-precision arithmetic is advised. * @return a positive, non-zero value much smaller than the nominal * point spacing. */ public double getHalfPlaneThreshold() { return halfPlaneThreshold; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy