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

edu.mines.jtk.sgl.TensorsPanel Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
/****************************************************************************
Copyright 2009, Colorado School of Mines and others.
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.
****************************************************************************/
package edu.mines.jtk.sgl;

import java.awt.Color;

import edu.mines.jtk.dsp.*;
import static edu.mines.jtk.util.ArrayMath.*;

/**
 * An axis-aligned panel that displays a slice of a 3D metric tensor field.
 * The tensors correspond to symmetric positive-definite 3x3 matrices, and
 * are rendered as ellipsoids.
 * @author Chris Engelsma and Dave Hale, Colorado School of Mines.
 * @version 2009.08.29
 */
public class TensorsPanel extends AxisAlignedPanel {

  /**
   * Constructs a tensors panel for the specified tensor field.
   * Assumes default unit samplings.
   * @param et the eigentensors; by reference, not by copy.
   */
  public TensorsPanel(EigenTensors3 et) {
    this(new Sampling(et.getN1()),
         new Sampling(et.getN2()),
         new Sampling(et.getN3()),
         et);
  }

  /**
   * Constructs a tensors panel for the specified tensor field.
   * @param s1 sampling of 1st dimension (Z axis).
   * @param s2 sampling of 2nd dimension (Y axis).
   * @param s3 sampling of 3rd dimension (X axis).
   * @param et the eigentensors; by reference, not by copy.
   */
  public TensorsPanel(
    Sampling s1, Sampling s2, Sampling s3, EigenTensors3 et)
  {
    _sx = s3;
    _sy = s2;
    _sz = s1;
    _et = et;
    _emax = findMaxEigenvalue();
    setStates(StateSet.forTwoSidedShinySurface(Color.CYAN));
  }

  /**
   * Updates the panel. 
   * This method should be called when the tensor field
   * referenced by this tensors panel has been modified.
   */
  public void update() {
    dirtyDraw();
  }

  /**
   * Sets the maximum size of the ellipsoids.
   * As this size is increased, the number of ellipsoids decreases.
   * @param size the maximum ellipsoid size, in samples.
   */
  public void setEllipsoidSize(int size) {
    _ellipsoidSize = size;
    dirtyDraw();
  }

  /////////////////////////////////////////////////////////////////////////////
  // protected

  protected void draw(DrawContext dc) {
    AxisAlignedFrame aaf = this.getFrame();
    if (aaf==null)
      return;
    Axis axis = aaf.getAxis();
    drawEllipsoids(axis);
  }

  /////////////////////////////////////////////////////////////////////////////
  // private

  private Sampling _sx,_sy,_sz;
  private EigenTensors3 _et;
  private float _emax;
  private int _ellipsoidSize = 10;
  private EllipsoidGlyph _eg = new EllipsoidGlyph();

  /**
   * Draws the tensors as ellipsoids.
   */
  private void drawEllipsoids(Axis axis) {

    // Tensor sampling.
    int nx = _sx.getCount();
    int ny = _sy.getCount();
    int nz = _sz.getCount();
    double dx = _sx.getDelta();
    double dy = _sy.getDelta();
    double dz = _sz.getDelta();
    double fx = _sx.getFirst();
    double fy = _sy.getFirst();
    double fz = _sz.getFirst();

    // Min/max (x,y,z) coordinates.
    double xmin = _sx.getFirst();
    double xmax = _sx.getLast();
    double ymin = _sy.getFirst();
    double ymax = _sy.getLast();
    double zmin = _sz.getFirst();
    double zmax = _sz.getLast();

    // Maximum length of eigenvectors u, v and w.
    float dmax = 0.5f*_ellipsoidSize;
    float dxmax = (float)dx*dmax;
    float dymax = (float)dy*dmax;
    float dzmax = (float)dz*dmax;

    // Distance between ellipsoid centers (in samples).
    int kec = (int)(2.0*dmax);

    // Scaling factor for the eigenvectors.
    float scale = dmax/sqrt(_emax);

    // Smallest eigenvalue permitted.
    float etiny = 0.0001f*_emax;

    // Current frame.
    AxisAlignedFrame aaf = this.getFrame();

    if (axis==Axis.X) {

      // Y-Axis.
      int nyc = (int)((ymax-ymin)/(2.0f*dymax));
      double dyc = kec*dy;
      double fyc = 0.5f*((ymax-ymin)-(nyc-1)*dyc);
      int jyc = (int)(fyc/dy);

      // Z-Axis.
      int nzc = (int)((zmax-zmin)/(2.0f*dzmax));
      double dzc = kec*dz;
      double fzc = 0.5f*((zmax-zmin)-(nzc-1)*dzc);
      int jzc = (int)(fzc/dz);

      xmin = aaf.getCornerMin().x;
      xmax = aaf.getCornerMax().x;
      ymin = aaf.getCornerMin().y;
      ymax = aaf.getCornerMax().y;
      zmin = aaf.getCornerMin().z;
      zmax = aaf.getCornerMax().z;

      // X-Axis.
      float xc = 0.5f*(float)(xmax+xmin);
      int ix = _sx.indexOfNearest(xc);

      for (int iy=jyc; iy




© 2015 - 2024 Weber Informatics LLC | Privacy Policy