//
// ScreenAnnotatorUtils.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.

You should have received a copy of the GNU Library 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
*/

package visad.bom.annotations;

import visad.PlotText;
import visad.TextControl;
import visad.VisADException;
import visad.VisADGeometryArray;
import visad.java3d.VisADCanvasJ3D;
import visad.java3d.DisplayImplJ3D;
import visad.java3d.DisplayRendererJ3D;

import visad.util.HersheyFont;

import java.awt.Font;
import java.awt.Image;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;

import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.Font3D;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.LineArray;
import javax.media.j3d.LineAttributes;
import javax.media.j3d.PointArray;
import javax.media.j3d.PointAttributes;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.QuadArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Text3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TransparencyAttributes;
import javax.media.j3d.TriangleArray;
import javax.media.j3d.View;

import javax.vecmath.Point2d;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3d;

/**
 *  This is a collection of static methods to help with the construction
 *  of java3D objects used for annotating a VisAD display. The objects are
 *  intended to be drawn directly to the screen using screen pixel
 *  locations. See {@link ScreenAnnotator}.
 *
 *  This is meant to contain as much of the Java3D dependencies as posible.
 */
public class ScreenAnnotatorUtils
{

  /**
   *  Construct a {@link BranchGroup} object from a routine
   *  description of a Label using {@link Text3D}. A label is a Text
   *  string with attributes used for drawing it.
   *
   *  @param display  the VisAD display for this Label.
   *  @param text  the string.
   *  @param x  x screen coordinate of the text.
   *  @param y  y screen coordinate of the text.
   *  @param colour  red green blue triple; each value in [0.0, 1.0].
   *  @param font  {@link java.awt.Font} to use.
   *  @param zValue  Virtual world value; larger z is in front.
   *  @param fontSizeInPixels  height of text.
   *  @param align  one of: 
   *  @param path  one of: 
   *  @return the {@link BranchGroup}, suitably scaled, representing the 
   *          label.
   */
  public static BranchGroup makeJLabelShape3D(DisplayImplJ3D display,
    String text, int x, int y, float[] colour, Font font,
    double zValue, double fontSizeInPixels, int align, int path)
  {
    DisplayRendererJ3D renderer =
      (DisplayRendererJ3D)display.getDisplayRenderer();
    VisADCanvasJ3D canvas = renderer.getCanvas();

    // get the start point  and one pixel up in vworld coordinates
    int[][] screenXY = { {x, x},
                         {y, y-1}  // just one pixel up
    };
    Point3d[] points = screenToVworld(screenXY, canvas);

    //adjust z
    ditherPoints(canvas, 0.4, points);
    adjustZ(display, canvas, zValue, points);

    // scale by distance in vworld representing one pixel
    double scale = fontSizeInPixels*
      (points[1].y - points[0].y)/font.getSize2D();
 
    // make the Text3D geometry object
    Font3D font3D = new Font3D(font, null); // no extrusion
    // create at Origin - scale and move later
    Text3D text3D = new Text3D(font3D, text,
      new Point3f((float)0, (float)0, (float)0), align, path);

    // make some colours
    ColoringAttributes textColor = new ColoringAttributes();
    textColor.setColor(colour[0], colour[1], colour[2]);

    Appearance textAppearance = new Appearance();
    textAppearance.setColoringAttributes(textColor);

    Shape3D textShape = new Shape3D(text3D, textAppearance);

    // Build a Transformation 
    // create at Origin, Scale and move to point
    Transform3D tMove = new Transform3D();
    tMove.set(new Vector3d(points[0].x, points[0].y, points[0].z));
    Transform3D tScale = new Transform3D();
    tScale.set(scale);
    tMove.mul(tScale);

    TransformGroup tg = new TransformGroup();
    Transform3D t3D = new Transform3D();
    tg.setTransform(tMove);

    tg.addChild(textShape);

    BranchGroup bg = new BranchGroup();
    bg.addChild(tg);

    return bg;
  } // makeJLabelShape3D

  /**
   *  Construct a {@link Shape3D} object from a routine description
   *  of a Label using 2D fonts. A label is a Text string with
   *  attributes used drawing it.
   *
   *  @param display  the VisAD display for this Label.
   *  @param text  the string.
   *  @param x  x screen coordinate of the text.
   *  @param y  y screen coordinate of the text.
   *  @param colour  red green blue triple; each value in [0.0, 1.0].
   *  @param font  {@link java.awt.Font} to use.
   *  @param hfont  Hershey font to use; if both fonts are null
   *         then use the default VisAD line font.
   *  @param zValue  Virtual world value; larger z is in front.
   *  @param scaleFactor  scale the font by this factor; by default
   *                       characters are 1 pixel in size.
   *  @param filled  if true the font is rendered as filled,
   *         if false just the triangles are drawn.
   *  @param thickness  line width to use if just drawing triangles;
   *          usually 1.0 is the most useful.
   *  @param orientation  angle of rotation of the text anticlockwise
   *         from the horizontal.
   *  @param horizontal  one of:
   *  @param vertical  one of:
   *  @param charRotation  rotate each character
   *         charRotation degrees clockwise from base line.
   *
   *  @return the Label description as a {@link Shape3D}.
   *
   *  @throws VisADException  VisAD couldn't make the geometry array.
   */
  public static Shape3D makeLabelShape3D(DisplayImplJ3D display,
    String text, int x, int y, float[] colour,
    Font font, HersheyFont hfont, double zValue,
    double scaleFactor, boolean filled, double thickness,
    double orientation,
    TextControl.Justification horizontal,
    TextControl.Justification vertical,
    double charRotation)
    throws VisADException
  {
    Shape3D shape = null;
    DisplayRendererJ3D renderer =
      (DisplayRendererJ3D)display.getDisplayRenderer();
    VisADCanvasJ3D canvas = renderer.getCanvas();

    // set up some stuff in the Virtual World
    Point3d position1 = new Point3d();
    Point3d position2 = new Point3d();
    Point3d position3 = new Point3d();
    canvas.getPixelLocationInImagePlate(x, y, position1);
    // possible different scale in x and y direction?
    // use default of 1 pixel for font height
    canvas.getPixelLocationInImagePlate(x+1, y, position2);
    double pixelInImagePlate = position2.x - position1.x;
    position2.x = position1.x + pixelInImagePlate*
      Math.cos(Math.toRadians(orientation));
    position2.y = position1.y + pixelInImagePlate*
      Math.sin(Math.toRadians(orientation));
    position2.z = position1.z;
    position3.x = position1.x - pixelInImagePlate*
      Math.sin(Math.toRadians(orientation));
    position3.y = position1.y + pixelInImagePlate*
      Math.cos(Math.toRadians(orientation));
    position3.z = position1.z;

    Transform3D t = new Transform3D();
    canvas.getImagePlateToVworld(t);
    t.transform(position1);
    t.transform(position2);
    t.transform(position3);

    // adjust z
    Point3d[] textStart = {position1, position2, position3};
    ditherPoints(canvas, 0.4, textStart);
    adjustZ(display, canvas, zValue, textStart);

    position1 = textStart[0];
    position2 = textStart[1];
    position3 = textStart[2];
    double[] start = {(double) position1.x,
                      (double) position1.y,
                      (double) position1.z};
    double[] base =  {(double) (position2.x - position1.x),
                      (double) (position2.y - position1.y),
                      (double) (position2.z - position1.z)};
    double[] up =    {(double) (position3.x - position1.x),
                      (double) (position3.y - position1.y),
                      (double) (position3.z - position1.z)};

    // scale is now in visad PlotText.java but do here
    // and put scale = 1 in call to PlotText
    for (int i=0; i<3; i++) {
      up[i] = scaleFactor*up[i];
      base[i] = scaleFactor*base[i];
    }

    // always use offset of zero. Just change x y if offset wanted
    double[] offset = {0.0, 0.0, 0.0};
    VisADGeometryArray array = null;
    if (font != null) {
      // to be compatable with versions of VisAD with old
      // PlotText call the old interface if charRotation
      // is zero
      if (charRotation == 0.0) {
        array = PlotText.render_font(text, font, start,
          base, up, horizontal, vertical);
      } else {
        array = PlotText.render_font(text, font, start,
          base, up, horizontal, vertical, charRotation, 1.0, offset);
      }
    } else if (hfont != null) {
      if (charRotation == 0.0) {
        array = PlotText.render_font(text, hfont, start,
          base, up, horizontal, vertical);
      } else {
        array = PlotText.render_font(text, hfont, start,
          base, up, horizontal, vertical, charRotation, 1.0, offset);
      }
    } else { // font && hfont are null
      if (charRotation == 0.0) {
        array = PlotText.render_label(text, start, base,
          up, horizontal, vertical);
      } else {
        array = PlotText.render_label(text, start, base,
          up, horizontal, vertical, charRotation, 1.0, offset);
      }
    }

    GeometryArray geom = display.makeGeometry(array);

    Appearance appearance = new Appearance();

    ColoringAttributes coloringAttributes =
      new ColoringAttributes();
    coloringAttributes.setColor(colour[0], colour[1], colour[2]);
    appearance.setColoringAttributes(coloringAttributes);

    LineAttributes lineAttributes = new LineAttributes();
    lineAttributes.setLineWidth((float)thickness);
    appearance.setLineAttributes(lineAttributes);

    PolygonAttributes polygonAttributes = new PolygonAttributes();
    polygonAttributes.setCullFace(PolygonAttributes.CULL_NONE);
    // should be this by default but didn't render the font
    if (filled) {
      polygonAttributes.setPolygonMode(PolygonAttributes.POLYGON_FILL);
    } else {
      polygonAttributes.setPolygonMode(PolygonAttributes.POLYGON_LINE);
    }
    appearance.setPolygonAttributes(polygonAttributes);

    // change this to return a branch group

    return new Shape3D(geom, appearance);
  }
  
  /**
   * This adjusts a set of points so that the drawn object has the
   * same appearance even though the Z value is adjusted to a user
   * given setting. Important for Perspective view.
   *
   * @param display  the VisAD display.
   * @param canvas  Java3D canvas being drawn on
   * @param z  Virtual world value; larger z is in front.
   * @param points  array of values to have their z value adjusted.
   */
  public static void adjustZ(DisplayImplJ3D display, Canvas3D canvas,
    double z, Point3d[] points)
  {
    if (display.getGraphicsModeControl().getProjectionPolicy()
      == View.PERSPECTIVE_PROJECTION)
    {
      Point3d leftEye = new Point3d();
      Point3d rightEye = new Point3d();
      canvas.getLeftEyeInImagePlate(leftEye);
      canvas.getRightEyeInImagePlate(rightEye);
      double xLoc = (leftEye.x + rightEye.x)/2.0;
      double yLoc = (leftEye.y + rightEye.y)/2.0;
      double zLoc = (leftEye.z + rightEye.z)/2.0;
      Point3d eye = new Point3d(xLoc, yLoc, zLoc);
      Transform3D t = new Transform3D();
      canvas.getImagePlateToVworld(t);
      t.transform(eye);

      double a;
      for (int i=0; i
   *                 
  • QuadrilateralJ3D.FILL *
  • QuadrilateralJ3D.LINE *
  • QuadrilateralJ3D.POINT * @param x1 x screen coordinate of the first point. * @param y1 y screen coordinate of the first point. * @param x2 x screen coordinate of the second point. * @param y2 y screen coordinate of the second point. * @param x3 x screen coordinate of the third point. * @param y3 y screen coordinate of the third point. * @param x4 x screen coordinate of the fourth point. * @param y4 y screen coordinate of the fourth point. * @param colour red green blue triple; each value in [0.0, 1.0]. * @param z Virtual world value; larger z is in front. * @param thickness used for LINE and POINT node. * * @return the QuadrilateralJ3D description as a {@link Shape3D}. */ public static Shape3D makeQuadrilateralShape3D(DisplayImplJ3D display, int style, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, float[] colour, double z, double thickness) { DisplayRendererJ3D renderer = (DisplayRendererJ3D)display.getDisplayRenderer(); VisADCanvasJ3D canvas = renderer.getCanvas(); int[][] screenXY = { {x1, x2, x3, x4}, {y1, y2, y3, y4} }; Point3d[] points = screenToVworld(screenXY, canvas); //adjust z ditherPoints(canvas, 0.4, points); adjustZ(display, canvas, z, points); QuadArray quadArray = new QuadArray(points.length, GeometryArray.COORDINATES); quadArray.setCoordinates(0, points); // Make an appearance for outline PointAttributes pointAttributes = new PointAttributes(); pointAttributes.setPointSize((float)thickness); LineAttributes lineAttributes = new LineAttributes(); lineAttributes.setLineWidth((float)thickness); PolygonAttributes pointPolygon = new PolygonAttributes(); pointPolygon.setCullFace(PolygonAttributes.CULL_NONE); if (style == QuadrilateralJ3D.POINT) { pointPolygon.setPolygonMode(PolygonAttributes.POLYGON_POINT); } else if (style == QuadrilateralJ3D.LINE) { pointPolygon.setPolygonMode(PolygonAttributes.POLYGON_LINE); } else { pointPolygon.setPolygonMode(PolygonAttributes.POLYGON_FILL); } // make some colours ColoringAttributes pointColor = new ColoringAttributes(); pointColor.setColor(colour[0], colour[1], colour[2]); Appearance pointAppearance = new Appearance(); pointAppearance.setPointAttributes(pointAttributes); pointAppearance.setLineAttributes(lineAttributes); pointAppearance.setPolygonAttributes(pointPolygon); pointAppearance.setColoringAttributes(pointColor); return new Shape3D(quadArray, pointAppearance); } // makeQuadrilateralShape3D /** * Construct a {@link Shape3D} object from a routine description * of a Triangle. * * @param display the VisAD display for this Point. * @param style one of
      *
    • TriangleJ3D.FILL,
    • *
    • TriangleJ3D.LINE,
    • *
    • TriangleJ3D.POINT
    * @param x1 x screen coordinate of the first point. * @param y1 y screen coordinate of the first point. * @param x2 x screen coordinate of the second point. * @param y2 y screen coordinate of the second point. * @param x3 x screen coordinate of the third point. * @param y3 y screen coordinate of the third point. * @param colour red green blue triple; each value in [0.0, 1.0]. * @param z Virtual world value; larger z is in front. * @param thickness used for LINE and POINT node. * * @return the Triangle description as a {@link Shape3D}. */ public static Shape3D makeTriangleShape3D(DisplayImplJ3D display, int style, int x1, int y1, int x2, int y2, int x3, int y3, float[] colour, double z, double thickness) { DisplayRendererJ3D renderer = (DisplayRendererJ3D)display.getDisplayRenderer(); VisADCanvasJ3D canvas = renderer.getCanvas(); // this becomes a call to screenToVworld() int[][] screenXY = { {x1, x2, x3}, {y1, y2, y3} }; Point3d[] points = screenToVworld(screenXY, canvas); //adjust z ditherPoints(canvas, 0.4, points); adjustZ(display, canvas, z, points); TriangleArray triangleArray = new TriangleArray( points.length, GeometryArray.COORDINATES); triangleArray.setCoordinates(0, points); // Make an appearance for outline PointAttributes pointAttributes = new PointAttributes(); pointAttributes.setPointSize((float)thickness); LineAttributes lineAttributes = new LineAttributes(); lineAttributes.setLineWidth((float)thickness); PolygonAttributes pointPolygon = new PolygonAttributes(); pointPolygon.setCullFace(PolygonAttributes.CULL_NONE); if (style == TriangleJ3D.POINT) { pointPolygon.setPolygonMode(PolygonAttributes.POLYGON_POINT); } else if (style == TriangleJ3D.LINE) { pointPolygon.setPolygonMode(PolygonAttributes.POLYGON_LINE); } else { pointPolygon.setPolygonMode(PolygonAttributes.POLYGON_FILL); } // make some colours ColoringAttributes pointColor = new ColoringAttributes(); pointColor.setColor(colour[0], colour[1], colour[2]); Appearance pointAppearance = new Appearance(); pointAppearance.setPointAttributes(pointAttributes); pointAppearance.setLineAttributes(lineAttributes); pointAppearance.setPolygonAttributes(pointPolygon); pointAppearance.setColoringAttributes(pointColor); return new Shape3D(triangleArray, pointAppearance); } // makeTriangleShape3D /** * Construct a {@link Shape3D} object from a routine description * of a Line. * * @param display the VisAD display for this Point. * @param style one of:
      *
    • LineJ3D.SOLID *
    • LineJ3D.DASH *
    • LineJ3D.DOT *
    • LineJ3D.DASH_DOT
    * @param x1 x screen coordinate of the first point. * @param y1 y screen coordinate of the first point. * @param x2 x screen coordinate of the second point. * @param y2 y screen coordinate of the second point. * @param colour red green blue triple; each value in [0.0, 1.0]. * @param z Virtual world value; larger z is in front. * @param thickness for the line. * * @return the LineJ3D description as a {@link Shape3D}. */ public static Shape3D makeLineShape3D(DisplayImplJ3D display, int style, int x1, int y1, int x2, int y2, float[] colour, double z, double thickness) { DisplayRendererJ3D renderer = (DisplayRendererJ3D)display.getDisplayRenderer(); VisADCanvasJ3D canvas = renderer.getCanvas(); int[][] screenXY = { {x1, x2}, {y1, y2} }; Point3d[] points = screenToVworld(screenXY, canvas); //adjust z ditherPoints(canvas, 0.4, points); adjustZ(display, canvas, z, points); LineArray lineArray = new LineArray( points.length, GeometryArray.COORDINATES); lineArray.setCoordinates(0, points); // Make an appearance for outline PointAttributes pointAttributes = new PointAttributes(); pointAttributes.setPointSize((float)thickness); LineAttributes lineAttributes = new LineAttributes(); lineAttributes.setLineWidth((float)thickness); if (style == LineJ3D.SOLID) { lineAttributes.setLinePattern(LineAttributes.PATTERN_SOLID); } else if (style == LineJ3D.DASH) { lineAttributes.setLinePattern(LineAttributes.PATTERN_DASH); } else if (style == LineJ3D.DOT) { lineAttributes.setLinePattern(LineAttributes.PATTERN_DOT); } else if (style == LineJ3D.DASH_DOT) { lineAttributes.setLinePattern(LineAttributes.PATTERN_DASH_DOT); } // make some colours ColoringAttributes pointColor = new ColoringAttributes(); pointColor.setColor(colour[0], colour[1], colour[2]); Appearance pointAppearance = new Appearance(); pointAppearance.setPointAttributes(pointAttributes); pointAppearance.setLineAttributes(lineAttributes); pointAppearance.setColoringAttributes(pointColor); return new Shape3D(lineArray, pointAppearance); } // makeLineShape3D /** * Construct a {@link Shape3D} object from a routine description * of a Point. * * @param display the VisAD display for this Point. * @param x1 x screen coordinate of the point. * @param y1 y screen coordinate of the point. * @param colour red green blue triple; each value in [0.0, 1.0]. * @param z Virtual world value; larger z is in front. * @param thickness gives the size of the Point. * * @return the Point description as a {@link Shape3D}. */ public static Shape3D makePointShape3D(DisplayImplJ3D display, int x1, int y1, float[] colour, double z, double thickness) { DisplayRendererJ3D renderer = (DisplayRendererJ3D)display.getDisplayRenderer(); VisADCanvasJ3D canvas = renderer.getCanvas(); int[][] screenXY = { {x1}, {y1} }; Point3d[] points = screenToVworld(screenXY, canvas); //adjust z ditherPoints(canvas, 0.4, points); adjustZ(display, canvas, z, points); PointArray pointArray = new PointArray( points.length, GeometryArray.COORDINATES); pointArray.setCoordinates(0, points); // Make an appearance for outline PointAttributes pointAttributes = new PointAttributes(); pointAttributes.setPointSize((float)thickness); // make some colours ColoringAttributes pointColor = new ColoringAttributes(); pointColor.setColor(colour[0], colour[1], colour[2]); Appearance pointAppearance = new Appearance(); pointAppearance.setPointAttributes(pointAttributes); pointAppearance.setColoringAttributes(pointColor); return new Shape3D(pointArray, pointAppearance); } // makePointShape3D /** * Convert an array of Pixel points to Point3d array in the * Virtual World. * * @param canvas for the virtual world of interest. * @param screenXY the screen points in x, y pairs. * * @return - array of {@link Point3d} values representing the * Virtual World values for the Screen points. */ public static Point3d[] screenToVworld(int[][] screenXY, Canvas3D canvas) { int numPoints = screenXY[0].length; Point3d[] points = new Point3d[numPoints]; Transform3D t = new Transform3D(); canvas.getImagePlateToVworld(t); for (int i=0; i< numPoints; i++) { points[i] = new Point3d(); canvas.getPixelLocationInImagePlate(screenXY[0][i], screenXY[1][i], points[i]); t.transform(points[i]); } return points; } // screenToVWorld /** * Convert an array of Vworld points to int[][] array in * Screen coordinates. * * @param canvas for the virtual world of interest. * @param points array of {@link Point3d} of Vworld coordinates. * * @return - int[2][] array of values representing the Screen points. */ public static int[][] vworldToScreen(Point3d[] points, Canvas3D canvas) { int numPoints = points.length; Point2d point2d = new Point2d(); Point3d point3d = new Point3d(); int[][] screenXY = new int[2][numPoints]; Transform3D t = new Transform3D(); canvas.getVworldToImagePlate(t); for (int j=0; j 0.9) { frac = 0.9; } // get interpixel spacing in Vworld corrdinates Point3d p1 = new Point3d(); Point3d p2 = new Point3d(); Point3d p3 = new Point3d(); canvas.getPixelLocationInImagePlate(1, 1, p1); canvas.getPixelLocationInImagePlate(2, 1, p2); canvas.getPixelLocationInImagePlate(1, 2, p3); Transform3D t = new Transform3D(); canvas.getImagePlateToVworld(t); t.transform(p1); t.transform(p2); t.transform(p3); deltaX = p2.x - p1.x; deltaY = p1.y - p3.y; // use this to get the dithered points for (int i=0; i *
  • Image.TOP_LEFT (default) *
  • Image.TOP_RIGHT *
  • Image.BOTTOM_RIGHT *
  • Image.BOTTOM_LEFT *
  • Image.CENTER * @param x x screen coordinate to place the image. * @param y y screen coordinate to place the image. * @param width of image in pixels. * @param height of image in pixels. * @param zValue Virtual world value; larger z is in front. * @param scale scale factor for image magnification; greater * than 0.0. * * @return the Image description as a {@link Shape3D}. * * @throws VisADException if the image can't be accessed * for some reason. */ public static Shape3D makeImageShape3D(DisplayImplJ3D display, Image image, int position, int x, int y, int width, int height, double zValue, double scale) throws VisADException { int index = 0; int ind = 0; int scaledWidth; int scaledHeight; DisplayRendererJ3D renderer = (DisplayRendererJ3D)display.getDisplayRenderer(); VisADCanvasJ3D canvas = renderer.getCanvas(); // Adjust for scaling factor scaledWidth = Math.round((float)(width*scale)); scaledHeight = Math.round((float)(height*scale)); double scaleW = (double)scaledWidth/(double)width; double scaleH = (double)scaledHeight/(double)height; // Adjust x, y according to position // do nothing for TOP_LEFT if (position == ImageJ3D.TOP_RIGHT) { // adjust x x = x - (scaledWidth-1); } else if (position == ImageJ3D.BOTTOM_RIGHT) { // adjust x & y x = x - (scaledWidth-1); y = y - (scaledHeight-1); } else if (position == ImageJ3D.BOTTOM_LEFT) { // adjust y y = y - (scaledHeight-1); } else if (position == ImageJ3D.CENTER) { // adjust x & y x = x - (scaledWidth-1)/2; y = y - (scaledHeight-1)/2; } // now calculate the VWorld coordinates for each pixel Transform3D t = new Transform3D(); canvas.getImagePlateToVworld(t); index = 0; Point3d[] points = new Point3d[scaledWidth*scaledHeight]; for (int i=0; i
  • Ads help maintain this website.