Package ca.eandb.jmist.framework.geometry.primitive

Source Code of ca.eandb.jmist.framework.geometry.primitive.TorusGeometry

/**
* 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 ca.eandb.jmist.framework.geometry.primitive;

import java.util.Arrays;

import ca.eandb.jmist.framework.IntersectionRecorder;
import ca.eandb.jmist.framework.geometry.PrimitiveGeometry;
import ca.eandb.jmist.math.Basis3;
import ca.eandb.jmist.math.Box3;
import ca.eandb.jmist.math.Point2;
import ca.eandb.jmist.math.Point3;
import ca.eandb.jmist.math.Polynomial;
import ca.eandb.jmist.math.Ray3;
import ca.eandb.jmist.math.Sphere;
import ca.eandb.jmist.math.Vector3;

/**
* A torus primitive <code>SceneElement</code>.
* @author Brad Kimmel
*/
public final class TorusGeometry extends PrimitiveGeometry {

  /** Serialization version ID. */
  private static final long serialVersionUID = 8573316243171501395L;

  /**
   * Creates a new <code>TorusGeometry</code>.
   * @param major The major radius of the torus (i.e., the distance from the
   *     center of the torus to a point in the center of the tube.
   * @param minor The minor radius of the torus (i.e., the radius of the
   *     tube).
   */
  public TorusGeometry(double major, double minor) {
    this.major = major;
    this.minor = minor;
  }

  /* (non-Javadoc)
   * @see ca.eandb.jmist.framework.geometry.PrimitiveGeometry#intersect(ca.eandb.jmist.math.Ray3, ca.eandb.jmist.framework.IntersectionRecorder)
   */
  public void intersect(Ray3 ray, IntersectionRecorder recorder) {

    Vector3    orig      = ray.origin().vectorFromOrigin();
    Vector3    dir        = ray.direction().unit();
    double    sqRadius1    = major * major;
    double    sqRadius2    = minor * minor;
    double    s2NormOfDir    = dir.squaredLength();
    double    s2NormOfOrig  = orig.squaredLength();
    double    dirDotOrig    = dir.dot(orig);
    double    K        = s2NormOfOrig - (sqRadius1 + sqRadius2);

    Polynomial  f = new Polynomial(
              K * K - 4.0 * sqRadius1 * (sqRadius2 - orig.y() * orig.y()),
              4.0 * dirDotOrig * (s2NormOfOrig - (sqRadius1 + sqRadius2)) + 8.0 * sqRadius1 * dir.y() * orig.y(),
              2.0 * s2NormOfDir * (s2NormOfOrig - (sqRadius1 + sqRadius2)) + 4.0 * ((dirDotOrig * dirDotOrig) + sqRadius1 * dir.y() * dir.y()),
              4.0 * dirDotOrig * s2NormOfDir,
              s2NormOfDir * s2NormOfDir
          );

    double[]  x = f.roots();

    if (x.length > 1)
    {
      Arrays.sort(x);
      for (int i = 0; i < x.length; i++)
        recorder.record(super.newIntersection(ray, x[i], i % 2 == 0));
    }

  }

  /* (non-Javadoc)
   * @see ca.eandb.jmist.framework.AbstractGeometry#getNormal(ca.eandb.jmist.framework.AbstractGeometry.GeometryIntersection)
   */
  @Override
  protected Vector3 getNormal(GeometryIntersection x) {

    Point3  p = x.getPosition();
    Vector3  rel = new Vector3(p.x(), 0.0, p.z());

    double  length = rel.length();

    if (length > 0.0)
    {
      rel = rel.times(major / length);
      return p.vectorFrom(Point3.ORIGIN.plus(rel));
    }
    else
      return Vector3.K;

  }

  /* (non-Javadoc)
   * @see ca.eandb.jmist.framework.AbstractGeometry#getBasis(ca.eandb.jmist.framework.AbstractGeometry.GeometryIntersection)
   */
  @Override
  protected Basis3 getBasis(GeometryIntersection x) {

    Point3  p  = x.getPosition();
    Vector3  u  = new Vector3(-p.z(), 0.0, p.x()).unit();

    return Basis3.fromWU(x.getNormal(), u, Basis3.Orientation.RIGHT_HANDED);

  }

  /* (non-Javadoc)
   * @see ca.eandb.jmist.framework.AbstractGeometry#getTextureCoordinates(ca.eandb.jmist.framework.AbstractGeometry.GeometryIntersection)
   */
  @Override
  protected Point2 getTextureCoordinates(GeometryIntersection x) {

    Vector3  cp  = x.getPosition().vectorFromOrigin();
    Vector3  R  = Vector3.unit(cp.x(), 0.0, cp.z());
    Vector3  r  = cp.minus(R.times(major)).unit();

    return new Point2(
      (Math.PI + Math.atan2(-cp.z(), cp.x())) / (2.0 * Math.PI),
      (Math.PI + Math.atan2(cp.y(), R.dot(r))) / (2.0 * Math.PI)
    );

  }

  /* (non-Javadoc)
   * @see ca.eandb.jmist.framework.Bounded3#boundingBox()
   */
  public Box3 boundingBox() {
    return new Box3(
        -(major + minor), -minor, -(major + minor),
          major + minor ,  minor,   major + minor
    );
  }

  /* (non-Javadoc)
   * @see ca.eandb.jmist.framework.Bounded3#boundingSphere()
   */
  public Sphere boundingSphere() {
    return new Sphere(Point3.ORIGIN, major + minor);
  }

  /**
   * The major radius of the torus (i.e., the distance from the center of the
   * torus to a point in the center of the tube.
   */
  private final double major;

  /**
   * The minor radius of the torus (i.e., the radius of the tube).
   */
  private final double minor;

}
TOP

Related Classes of ca.eandb.jmist.framework.geometry.primitive.TorusGeometry

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.