using System; using System.Collections; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; namespace PaintDotNet.Data.SurfacePlot { unsafe class JRenderer3D { SolidBrush brush = new SolidBrush(Color.Blue); SolidBrush brush1 = new SolidBrush(Color.White); Pen pen = new Pen(Color.Blue); Pen pen1 = new Pen(Color.Red); IntPtr ptr; BitmapData bmpData; int bytes; byte[] rgbValues; Rectangle rect; private Bitmap bufferedImage = null; private Graphics g2D = null; private int[] bufferPixels = null; // render buffer private double[] zbufferPixels = null; // Z-buffer private int bufferWidth = 512; // size of the buffers private int bufferHeight = 512; // Global rendering parameters private Color backgroundColor = Color.Gray; private Color legendTextColor = Color.White; // transform parameters private Transform transform = null; // the actual transformation private double tr_rotationX = 1.34; private double tr_rotationY = 0; private double tr_rotationZ = 1; private double tr_perspective = 0; private double tr_maxDistance = 256; private int zOrientation = -1; private double scale = 1; private double zAspectRatio = 1; private double xCenter = 0; // the x, y, and z - coordinates of the rotation center private double yCenter = 0; private double zCenter = 0; // objects to be drawn private ArrayList lines3D = null; private ArrayList cubeLines3D = null; private ArrayList text3D = null; // 3D points private PointsPlot pointsPlot = null; /** * Draws a point as a sphere (slowest). */ public static int POINT_SPHERE = Point3D.SPHERE; /** * Draws a point as a (2D) circle. */ public static int POINT_CIRCLE = Point3D.CIRCLE; /** * Draws a point as a dot. Size information has no effect. */ public static int POINT_DOT = Point3D.DOT; // surfacePlot constants & parameters private static int SURFACEGRID_DEFAULTWIDTH = 256; private static int SURFACEGRID_DEFAULTHEIGHT = 256; /** * Draws a surface plot using only dots, no illumination is used (fastest mode). */ public static int SURFACEPLOT_DOTSNOLIGHT = 10; /** * Draws a surface plot using only dots, illumination is active. */ public static int SURFACEPLOT_DOTS = 11; /** * Draws a surface plot using lines. Number of lines can be adjusted. */ public static int SURFACEPLOT_LINES = 12; /** * Draws a surface plot using a mesh. Mesh size can be adapted. */ public static int SURFACEPLOT_MESH = 13; /** * Draws a filled surface plot . */ public static int SURFACEPLOT_FILLED = 14; /** * Draws a filled surface plot (Slowest mode). */ public static int SURFACEPLOT_ISOLINES = 15; private SurfacePlot surfacePlot = null; private int surfacePlot_gridWidth = SURFACEGRID_DEFAULTWIDTH; private int surfacePlot_gridHeight = SURFACEGRID_DEFAULTHEIGHT; private Bitmap surfacePlot_imagePlusData = null; // image used for the surface plot private Bitmap surfacePlot_imagePlusTexture = null; // texture image private int surfacePlot_plotMode = SURFACEPLOT_LINES; private int surfacePlot_lutNr = LUT_ORIGINAL; private double surfacePlot_light = 0; /** * Draws a volume using only dots (fastest mode). */ public static int VOLUME_DOTS = 20; /** * Draws a volume using nearest neighbor interpolation. */ public static int VOLUME_SLICE_NEAREST_NEIGHBOR = 21; /** * Draws a volume using trilinear interpolation. */ public static int VOLUME_SLICE_TRILINEAR = 22; // public final static int VOLUME_SLICE_AND_BORDERS = 23; // public final static int VOLUME_SLICE_AND_VOLUME_DOTS = 24; /** * Draws a volume using trilinear interpolation projection from the front */ public static int VOLUME_PROJECTION_TRILINEAR_FRONT = 25; /** * Draws a volume using trilinear interpolation projection from the back */ // public static final int VOLUME_PROJECTION_TRILINEAR_BACK = 26; private Volume volume = null; private int volume_drawMode = VOLUME_DOTS; //private int volume_threshold = 0; //private int volume_cutDist = 0; // clips the view sceen private int volume_lutNr = LUT_ORIGINAL; // LUT type //private int volume_dotsDeltaX = 1; // subsampling factor in x direction (used by dots drawing) //private int volume_dotsDeltaY = 1; // subsampling factor in x direction (used by dots drawing) //private int volume_dotsDeltaZ = 1; // subsampling factor in x direction (used by dots drawing) private int surfacePlot_min = 0; // minimum value for the luminance transform private int surfacePlot_max = 255; // maximum value for the luminance transform private Bitmap image; private bool axes = true; private bool lines = true; private bool text = true; private bool legend = true; private double minZ; private double maxZ; // LUT constants /** * 3D represenations of objects are drawn with their original colors. */ public static int LUT_ORIGINAL = 50; /** * 3D representations of objects are drawn with grayscale colors. */ public static int LUT_GRAY = 51; /** * 3D representations of objects are drawn with spectrum colors. */ public static int LUT_SPECTRUM = 52; /** * 3D representations of objects are drawn with fire colors. */ public static int LUT_FIRE = 53; /** * 3D representations of objects are drawn with thermal colors. */ public static int LUT_THERMAL = 54; /** * 3D representations of objects are drawn in orange. */ public static int LUT_ORANGE = 55; /** * 3D representations of objects are drawn in blue. */ public static int LUT_BLUE = 56; /** * 3D representations of objects are drawn in black. */ public static int LUT_BLACK = 57; /** * 3D representations of objects are cored according to their gradient. */ public static int LUT_GRADIENT = 58; public static int LUT_GRADIENT2 = 59; /** * Creates a new JRenderer3D object. * * This has always to be the first step to generate a 3D scene. * * The center is assumed at (0,0,0) * */ public JRenderer3D() { //initBuffer(); } /** * Creates a new JRenderer3D object.

* * This has always to be the first step to generate a 3D scene. * * @param xCenter The x-coordinate of the rotation / plot center. * @param yCenter The y-coordinate of the rotation / plot center. * @param zCenter The z-coordinate of the rotation / plot center. */ public JRenderer3D(double xCenter, double yCenter, double zCenter) { this.xCenter = xCenter; this.yCenter = yCenter; this.zCenter = zCenter; //initBuffer(); } private void initBuffer() { image = new Bitmap(bufferWidth, bufferHeight); bytes = image.Width * image.Height; rgbValues = new byte[bytes * 3]; rect = new Rectangle(0, 0, image.Width, image.Height); bufferPixels = new int[bufferWidth * bufferHeight]; zbufferPixels = new double[bufferWidth * bufferHeight]; if (transform != null) { tr_rotationX = transform.getRotationX(); tr_rotationY = transform.getRotationY(); tr_rotationZ = transform.getRotationZ(); scale = transform.getScale(); zAspectRatio = transform.getZAspectRatio(); tr_perspective = transform.getPerspective(); tr_maxDistance = transform.getMaxDistance(); } transform = new Transform(bufferWidth, bufferHeight); // restore values from previous transformation transform.setZOrientation(zOrientation); transform.setRotationXYZ(tr_rotationX, tr_rotationY, tr_rotationZ); transform.setScale(scale); transform.setZAspectRatio(zAspectRatio); transform.setPerspective(tr_perspective); transform.setMaxDistance(tr_maxDistance); // if the surfacePlot exists, then update the references to the buffers if (surfacePlot != null) { surfacePlot.setBuffers(bufferPixels, zbufferPixels, bufferWidth, bufferHeight); surfacePlot.setTransform(transform); } /** if (volume != null) { volume.setBuffers(bufferPixels, zbufferPixels, bufferWidth, bufferHeight); volume.setTransform(transform); }**/ } private void lines1() { Point3D p0 = new Point3D(); Point3D p1 = new Point3D(); for (int i = 0; i < lines3D.Count; i++) { if (lines3D[i] != null && lines3D[i] is Line3D) { Line3D line = (Line3D)lines3D[i]; int color = line.color; setPoints(line, p0, p1); transform.transform(p0); double x0 = transform.X, y0 = transform.Y, z0 = transform.Z + 2; transform.transform(p1); double x1 = transform.X, y1 = transform.Y, z1 = transform.Z + 2; if (line.isPair) { i++; Line3D line2 = (Line3D)lines3D[i]; int color2 = line2.color; setPoints(line2, p0, p1); transform.transform(p0); double x0_2 = transform.X, y0_2 = transform.Y, z0_2 = transform.Z + 2; transform.transform(p1); double x1_2 = transform.X, y1_2 = transform.Y, z1_2 = transform.Z + 2; if (z0_2 + z1_2 > z0 + z1) { x0 = x0_2; y0 = y0_2; z0 = z0_2; x1 = x1_2; y1 = y1_2; z1 = z1_2; color = color2; } } double dx1 = x1 - x0, dy1 = y1 - y0, dz1 = z1 - z0; int numSteps = (int)Math.Max(Math.Abs(dx1), Math.Abs(dy1)); double step = (numSteps > 0) ? 1 / (double)numSteps : 1; for (int s = 0; s < numSteps; s++) { double f = s * step; int x = (int)(x0 + f * dx1); int y = (int)(y0 + f * dy1); if (x >= 0 && y >= 0 && x < bufferWidth && y < bufferHeight) { int pos = y * bufferWidth + x; double z = z0 + f * dz1; int v_ = (int)((z * 20) + 128); v_ = Math.Min(Math.Max(0, v_), 255); v_ = (int)(0xFF000000 | (v_ << 8)); if (z <= zbufferPixels[pos]) { zbufferPixels[pos] = z; bufferPixels[pos] = color; // v_; } } } } } } public void cubeLines() { Point3D p0 = new Point3D(); Point3D p1 = new Point3D(); for (int i = 0; i < cubeLines3D.Count; i++) { if (cubeLines3D[i] != null && cubeLines3D[i] is Line3D) { Line3D line = (Line3D)cubeLines3D[i]; int color = line.color; setPoints(line, p0, p1); transform.transform(p0); double x0 = transform.X, y0 = transform.Y, z0 = transform.Z; transform.transform(p1); double x1 = transform.X, y1 = transform.Y, z1 = transform.Z; double dx1 = x1 - x0, dy1 = y1 - y0, dz1 = z1 - z0; int numSteps = (int)Math.Max(Math.Abs(dx1), Math.Abs(dy1)); double step = (numSteps > 0) ? 1 / (double)numSteps : 1; for (int s = 0; s < numSteps; s++) { double f = s * step; int x = (int)(x0 + f * dx1); int y = (int)(y0 + f * dy1); if (x >= 0 && y >= 0 && x < bufferWidth && y < bufferHeight) { int pos = y * bufferWidth + x; double z = z0 + f * dz1; if (z <= zbufferPixels[pos]) { zbufferPixels[pos] = z; bufferPixels[pos] = color; } } } } } //第一个版本 /** if (image != null) { bmpData = image.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); ptr = bmpData.Scan0; Color color; for (int i = 0; i < bufferPixels.Length; i++) { color = Color.FromArgb(bufferPixels[i]); rgbValues[i * 3 + 2] = color.R; rgbValues[i * 3 + 1] = color.G; rgbValues[i * 3] = color.B; } System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes * 3); image.UnlockBits(bmpData); }**/ //第二个版本 if (image != null) { //bmpData = new BitmapData(); bmpData = image.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);//.Format24bppRgb ptr = bmpData.Scan0; for (int i = 0; i < bufferPixels.Length; i++) { int c0 = bufferPixels[i]; rgbValues[i * 3 + 2] = (byte)((c0 >> 16) & 0xff); rgbValues[i * 3 + 1] = (byte)((c0 >> 8) & 0xff); rgbValues[i * 3] = (byte)((c0) & 0xff); } System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes * 3); image.UnlockBits(bmpData); } //第三个版本 /** if (image != null) { bmpData = image.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);//.Format24bppRgb byte* ptr = (byte*)(bmpData.Scan0); for (int i = 0; i < bmpData.Width; i++) { for (int j = 0; j < bmpData.Height; j++) { int c0 = bufferPixels[i*j]; ptr[0] = (byte)((c0) & 0xff); ptr[1] = (byte)((c0 >> 8) & 0xff); ptr[2] = (byte)((c0 >> 16) & 0xff); } ptr += bmpData.Stride - bmpData.Width * 3; } //System.Runtime.InteropServices.Marshal.Copy(bufferPixels, 0, ptr, bytes); image.UnlockBits(bmpData); }**/ } private void setPoints(Line3D l0, Point3D p0, Point3D p1) { p0.x = l0.x1; p0.y = l0.y1; p0.z = l0.z1; p1.x = l0.x2; p1.y = l0.y2; p1.z = l0.z2; } private void finishAndDrawText() { if (bufferedImage == null || bufferedImage.Height != bufferHeight || bufferedImage.Width != bufferWidth) { bufferedImage = new Bitmap(bufferWidth, bufferHeight); g2D = Graphics.FromImage(bufferedImage); } g2D.FillRectangle(brush, 0, 0, bufferWidth, bufferHeight); g2D.DrawImage(image, 0, 0); Font font; if (text) { if (text3D != null) { double scale = transform.getScale(); for (int i = 0; i < text3D.Count; i++) { if (text3D[i] != null && text3D[i] is Text3D) { Text3D ti = (Text3D)text3D[i]; transform.transform(ti); double x = transform.X; double y = transform.Y; double z = transform.Z; double x2 = 0; double y2 = 0; double z2 = 0; if (ti.number == 2) { i++; Text3D ti2 = (Text3D)text3D[i]; transform.transform(ti2); x2 = transform.X; y2 = transform.Y; z2 = transform.Z; if (z2 < z) { x = x2; y = y2; z = z2; } } if (ti.number == 4) { i++; Text3D ti2 = (Text3D)text3D[i]; transform.transform(ti2); x2 = transform.X; y2 = transform.Y; z2 = transform.Z; i++; ti = (Text3D)text3D[i]; transform.transform(ti); double x3 = transform.X; double y3 = transform.Y; double z3 = transform.Z; i++; ti = (Text3D)text3D[i]; transform.transform(ti); double x4 = transform.X; double y4 = transform.Y; double z4 = transform.Z; if (x2 < x) { x = x2; y = y2; z = z3; } if (x3 < x) { x = x3; y = y3; z = z3; } if (x4 < x) { x = x4; y = y4; z = z4; } } if (z >= 0) { //g2D.setColor(ti.color); int strHeight = (int)(scale * ti.size); font = new Font("Sans", strHeight); //g2D.setFont(font); //FontMetrics metrics = g2D.getFontMetrics(); //int strWidth = metrics.stringWidth(ti.text); SizeF size = g2D.MeasureString(ti.text, font); g2D.DrawString(ti.text, font, brush1, (int)x - size.Width/ 2, (int)y + strHeight / 2); } } } } } if (text) { if (text3D != null) { double scale = transform.getScale(); for (int i = 0; i < text3D.Count; i++) { if (text3D[i] != null && text3D[i] is Text3D) { Text3D ti = (Text3D)text3D[i]; transform.transform(ti); double x = transform.X; double y = transform.Y; double z = transform.Z; double x2 = 0; double y2 = 0; double z2 = 0; if (ti.number == 2) { i++; Text3D ti2 = (Text3D)text3D[i]; transform.transform(ti2); x2 = transform.X; y2 = transform.Y; z2 = transform.Z; if (z2 < z) { x = x2; y = y2; z = z2; } } if (ti.number == 4) { i++; Text3D ti2 = (Text3D)text3D[i]; transform.transform(ti2); x2 = transform.X; y2 = transform.Y; z2 = transform.Z; i++; ti = (Text3D)text3D[i]; transform.transform(ti); double x3 = transform.X; double y3 = transform.Y; double z3 = transform.Z; i++; ti = (Text3D)text3D[i]; transform.transform(ti); double x4 = transform.X; double y4 = transform.Y; double z4 = transform.Z; if (x2 < x) { x = x2; y = y2; z = z3; } if (x3 < x) { x = x3; y = y3; z = z3; } if (x4 < x) { x = x4; y = y4; z = z4; } } //System.out.println("2 x:" + x + " y: " + y + " z: " + z + " " + ti.text); if (z < 0) { //g2D.setColor(ti.color); int strHeight = (int)(scale * ti.size); font = new Font("Sans", strHeight); //g2D.setFont(font); //FontMetrics metrics = g2D.getFontMetrics(); SizeF size = g2D.MeasureString(ti.text, font); g2D.DrawString(ti.text, font, brush1, (int)x - size.Width / 2, (int)y + strHeight / 2); } } } } } // show lut if (legend && surfacePlot != null) { int lutNr = surfacePlot.getSurfacePlotLut(); if ((lutNr > LUT_ORIGINAL && lutNr <= LUT_THERMAL) || (lutNr == LUT_ORIGINAL && surfacePlot.hasOtherLut)) { int hLut = 256; int wLut = 20; int xs = bufferWidth - 30; int xe = xs + wLut; int ys = (bufferHeight - hLut) / 2; bool isInverse = (surfacePlot.getInversefactor() == -1); //g2D.setColor(legendTextColor); g2D.DrawRectangle(pen1, new Rectangle(xs - 1, ys - 1, wLut + 2, hLut + 1)); for (int j = 0; j < 256; j++) { //g2D.setColor(new Color(surfacePlot.lut.colors[255 - j])); g2D.DrawLine(pen1, xs, ys + j, xe, ys + j); } double d = maxZ - minZ; double stepValue = calcStepSize(d, 11); double minStart = Math.Floor(minZ / stepValue) * stepValue; double delta = minStart - minZ; //g2D.setColor(legendTextColor); font = new Font("Sans", 12); //g2D.setFont(font); //FontMetrics metrics = g2D.getFontMetrics(); int stringHeight = 5; for (double value = 0; value + delta <= d; value += stepValue) { String s; if (Math.Floor(minStart + value) - (minStart + value) == 0) s = "" + (int)(minStart + value); else s = "" + (int)Math.Round((minStart + value) * 1000) / 1000; double pos = ((value + delta) * 256 / d); int y; if (pos >= 0) { y = (int)(-pos + 255 + ys); if (isInverse) y = (int)(pos + ys); //int strWidth = metrics.stringWidth(s); g2D.DrawString(s, font, brush1, xs - 5, y + stringHeight); g2D.DrawLine(pen1, xs - 3, y, xs - 1, y); } } } } } public void showRotation() { Font font = new Font("Sans", 13); //g2D.setFont(font); String str = "Rotation x = " + (int)((180 / Math.PI) * transform.getRotationX()) + "\u00b0" + ", Rotation z =" + (int)((180 / Math.PI) * transform.getRotationZ()) + "\u00b0"; g2D.DrawString(str, font, brush1, 10, 20); } public void setLegendTextColor(Color legendTextColor) { this.legendTextColor = legendTextColor; } double calcStepSize(double range, double targetSteps) { // Calculate an initial guess at step size double tempStep = range / targetSteps; // Get the magnitude of the step size double mag = Math.Floor(Math.Log(tempStep) / Math.Log(10)); double magPow = Math.Pow((double)10.0, mag); // Calculate most significant digit of the new step size double magMsd = ((int)(tempStep / magPow + .5)); // promote the MSD to either 1, 2, 4, or 5 if (magMsd > 6) // 5 magMsd = 10.0; else if (magMsd > 3) magMsd = 5.0; else if (magMsd > 2) magMsd = 4.0; else if (magMsd > 1) magMsd = 2.0; return magMsd * magPow; } private void clearBuffers() { for (int i = bufferPixels.Length - 1; i >= 0; i--) { bufferPixels[i] = 0; zbufferPixels[i] = 1000000; } } private Line3D setLinePoints(Line3D lineItem, double[] p1, double[] p2, int color) { lineItem.x1 = p1[0]; lineItem.y1 = p1[1]; lineItem.z1 = p1[2]; lineItem.x2 = p2[0]; lineItem.y2 = p2[1]; lineItem.z2 = p2[2]; lineItem.color = color; return lineItem; } private void addCubeLinesList(Line3D[] lines3D) { if (cubeLines3D == null) cubeLines3D = new ArrayList(); for (int i = 0; i < lines3D.Length; i++) { this.cubeLines3D.Add(lines3D[i]); } } private void clearCubeLines3D() { if (cubeLines3D != null) this.cubeLines3D.Clear(); } /** * This methods does the rendering and creates the 3D output. * It has to be redone after all setting changes (scale, angle, surface modes, lightning modes, color modes etc.) * Draws all given input data (lines, text, points, cubes, surfaces). */ public void doRendering() { clearBuffers(); if (volume != null) { transform.setOffsets(xCenter, yCenter, zCenter); volume.draw(); transform.setOffsets(0, 0, 0); } if (surfacePlot != null) { surfacePlot.draw(); } if (pointsPlot != null) { pointsPlot.draw(); } if (lines && lines3D != null) { //lines1(); } if (axes && cubeLines3D != null) { cubeLines(); } finishAndDrawText(); if (getSurfacePlotMode() == JRenderer3D.SURFACEPLOT_DOTSNOLIGHT) showRotation(); } /** * Creates the surface plot. * * @param imp The images to be drawn in 3D. */ public void setSurfacePlot(Bitmap imp) { //Cv2.ImShow("d111dd", OpenCvSharp.Extensions.BitmapConverter.ToMat(imp)); //在这里把图片resize下看看 //surfacePlot_imagePlusData = KiResizeImage(imp, surfacePlot_gridWidth, surfacePlot_gridHeight); surfacePlot_imagePlusData = imp; surfacePlot = new SurfacePlot(); surfacePlot.setSurfacePlotCenter(xCenter, yCenter, zCenter); surfacePlot.setSurfaceGridSize(surfacePlot_gridWidth, surfacePlot_gridHeight); surfacePlot.setSurfacePlotImage(surfacePlot_imagePlusData); if (surfacePlot_imagePlusTexture != null) { surfacePlot.setSurfacePlotTextureImage(surfacePlot_imagePlusTexture); } surfacePlot.resample(); surfacePlot.setSurfacePlotMode(surfacePlot_plotMode); surfacePlot.setSurfacePLotSetLight(surfacePlot_light); surfacePlot.setBuffers(bufferPixels, zbufferPixels, bufferWidth, bufferHeight); surfacePlot.setTransform(transform); } public void setSurfacePlotTexture(Bitmap impTexture) { surfacePlot_imagePlusTexture = impTexture; if (surfacePlot != null) { surfacePlot.setSurfacePlotTextureImage(impTexture); surfacePlot.resample(); } } /** * Sets the surface plot mode. *

* Available options: *

* * @param surfacePlot_plotMode the surface plot mode */ public void setSurfacePlotMode(int surfacePlot_plotMode) { this.surfacePlot_plotMode = surfacePlot_plotMode; if (surfacePlot != null) surfacePlot.setSurfacePlotMode(surfacePlot_plotMode); } public int getSurfacePlotMode() { return surfacePlot_plotMode; } /** * Sets the surface grid size (sampling rate). * Should be set to an integer fraction of the image of which the surface plot has to be generated. * * @param width the width of surface grid * @param height the height of surface grid */ public void setSurfacePlotGridSize(int width, int height) { this.surfacePlot_gridWidth = width; this.surfacePlot_gridHeight = height; if (surfacePlot != null) { surfacePlot.setSurfaceGridSize(surfacePlot_gridWidth, surfacePlot_gridHeight); surfacePlot.resample(); } } /** * Sets scale of the redered 3D scene. * * @param scale scales the scene */ public void setTransformScale(double scale) { transform.setScale(scale); } /** * Sets the rotation on x-, y- and z-axis. * * @param ax rotation angle of x-axis in degree * @param ay rotation angle of y-axis in degree * @param az rotation angle of z-axis in degree */ public void setTransformRotationXYZ(double ax, double ay, double az) { transform.setRotationXYZ(ax / 180 * Math.PI, ay / 180 * Math.PI, az / 180 * Math.PI); } /** * Changes the rotation of x- and z-axis by the values of changeX and changeY. * * @param changeX change of rotation angle of x-axis in degree * @param changeZ change of rotation angle of z-axis in degree */ public void changeTransformRotationXZ(double changeX, double changeZ) { transform.changeRotationXZ(changeX / 180 * Math.PI, changeZ / 180 * Math.PI); } /** * Sets the background color of the rendered 3D presenation * * @param rgb the background color (argb int) */ public void setBackgroundColor(int rgb) { this.backgroundColor = Color.FromArgb(rgb); } /** * Sets the background color of the rendered 3D presentation * * @param color Color */ public void setBackgroundColor(Color color) { this.backgroundColor = color; } /** * Adds a single 3D line to the 3D scene. * * @param line3D the 3D line to add */ public void addLine3D(Line3D line3D) { if (this.lines3D == null) this.lines3D = new ArrayList(); line3D.x1 -= xCenter; line3D.y1 -= yCenter; line3D.z1 -= zCenter; line3D.x2 -= xCenter; line3D.y2 -= yCenter; line3D.z2 -= zCenter; this.lines3D.Add(line3D); } public void clearLines() { if (this.lines3D != null) this.lines3D.Clear(); } /** * Adds a single 3D text to the 3D scene. * * @param text3D the 3D text to add */ public void addText3D(Text3D text3D) { if (this.text3D == null) this.text3D = new ArrayList(); text3D.x -= xCenter; text3D.y -= yCenter; text3D.z -= zCenter; this.text3D.Add(text3D); } public void addTextPair3D(Text3D text1_3D, Text3D text2_3D) { if (this.text3D == null) this.text3D = new ArrayList(); text1_3D.x -= xCenter; text1_3D.y -= yCenter; text1_3D.z -= zCenter; text2_3D.x -= xCenter; text2_3D.y -= yCenter; text2_3D.z -= zCenter; this.text3D.Add(text1_3D); this.text3D.Add(text2_3D); } public void clearText() { if (this.text3D != null) this.text3D.Clear(); } /** * Sets the buffer size. (The size of the rendered 2D image) * * @param width The width to be set. * @param height The height to be set. */ public void setBufferSize(int width, int height) { this.bufferWidth = width; this.bufferHeight = height; initBuffer(); } /** * Adds a cube (drawn with 12 lines) to the 3D scene. * * @param xMin minimum value x * @param yMin minimum value y * @param zMin minimum value z * @param xMax maximum value x * @param yMax maximum value y * @param zMax maximum value z * @param color Color of cube lines (argb) */ public void add3DCube(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, Color color) { int colorInt = color.ToArgb(); add3DCube(xMin, yMin, zMin, xMax, yMax, zMax, colorInt); } /** * Adds a cube (drawn with 12 lines) to the 3D scene. * * @param xMin minimum value x * @param yMin minimum value y * @param zMin minimum value z * @param xMax maximum value x * @param yMax maximum value y * @param zMax maximum value z * @param rgb Color of cube lines (argb) */ public void add3DCube(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int rgb) { double[][] cube = new double[8][]{ new double[]{ xMin-xCenter, yMin-yCenter, zMin-zCenter }, // left front down [0] new double[]{ xMax-xCenter, yMin-yCenter, zMin-zCenter }, // right front down [1] new double[]{ xMin-xCenter, yMin-yCenter, zMax-zCenter }, // left front up [2] new double[]{ xMax-xCenter, yMin-yCenter, zMax-zCenter }, // right front up [3] new double[]{ xMin-xCenter, yMax-yCenter, zMin-zCenter }, // left back down [4] new double[]{ xMax-xCenter, yMax-yCenter, zMin-zCenter }, // right back down [5] new double[]{ xMin-xCenter, yMax-yCenter, zMax-zCenter }, // left back up [6] new double[]{ xMax-xCenter, yMax-yCenter, zMax-zCenter } // right back up [7] }; // set up new 3D lines list Line3D[] lines3D = new Line3D[12]; lines3D[0] = setLinePoints(new Line3D(), cube[0], cube[1], rgb); lines3D[1] = setLinePoints(new Line3D(), cube[0], cube[2], rgb); lines3D[2] = setLinePoints(new Line3D(), cube[0], cube[4], rgb); lines3D[3] = setLinePoints(new Line3D(), cube[2], cube[6], rgb); lines3D[4] = setLinePoints(new Line3D(), cube[4], cube[6], rgb); lines3D[5] = setLinePoints(new Line3D(), cube[6], cube[7], rgb); lines3D[6] = setLinePoints(new Line3D(), cube[3], cube[7], rgb); lines3D[7] = setLinePoints(new Line3D(), cube[2], cube[3], rgb); lines3D[8] = setLinePoints(new Line3D(), cube[1], cube[3], rgb); lines3D[9] = setLinePoints(new Line3D(), cube[1], cube[5], rgb); lines3D[10] = setLinePoints(new Line3D(), cube[4], cube[5], rgb); lines3D[11] = setLinePoints(new Line3D(), cube[5], cube[7], rgb); addCubeLinesList(lines3D); } public void clearCubes() { this.clearCubeLines3D(); } /** * Sets the color lut for the surface plot. *

*

* * @param surfacePlot_lutNr color of look-up-table */ public void setSurfacePlotLut(int surfacePlot_lutNr) { this.surfacePlot_lutNr = surfacePlot_lutNr; if (surfacePlot != null) surfacePlot.setSurfacePlotLut(surfacePlot_lutNr); } /** * Sets the lightning for the surface plot illumination . *

*

* * @param surfacePlot_light intensity value between 0 and 1 (default is 0) * */ public void setSurfacePlotLight(double surfacePlot_light) { this.surfacePlot_light = surfacePlot_light; if (surfacePlot != null) surfacePlot.setSurfacePLotSetLight(surfacePlot_light); } public void setSurfacePlotMinMax(int surfacePlot_min, int surfacePlot_max) { //IJ.log("Min: " + surfacePlot_min + " Max: " + surfacePlot_max); this.surfacePlot_min = surfacePlot_min; this.surfacePlot_max = surfacePlot_max; if (surfacePlot != null) { surfacePlot.setMinMax(surfacePlot_min, surfacePlot_max); surfacePlot.applyMinMax(); } } /** * Aplies a smoothing to the surface plot data * * @param smoothRadius the radius of the smoothing kernel * */ public void setSurfaceSmoothingFactor(double smoothRadius) { surfacePlot.applySmoothingFilter(smoothRadius); } /** * Sets the z-aspect ratio (the relative z-height of a voxel). * When setting a volume, the z-aspect ratio is reset to ratio read from the stack. * If the z-aspect ratio needs to set this has to be done after calling the setVolume method. * * @param zAspectRatio z-aspect ratio (the relative z-ratio of a voxel) to be set. */ public void setTransformZAspectRatio(double zAspectRatio) { this.zAspectRatio = zAspectRatio; transform.setZAspectRatio(zAspectRatio); } /** * Returns the buffer width of the image. * * @return buffer width */ public int getWidth() { return bufferWidth; } /** * Returns the buffer height of the image. * * @return buffer height */ public int getHeight() { return bufferHeight; } /** * Returns actual rendered image. * * @return image */ public Bitmap getImage() { return bufferedImage; } public void setTransformPerspective(double perspective) { transform.setPerspective(perspective); } public void setTransformMaxDistance(double maxDistance) { transform.setMaxDistance(maxDistance); } public void setAxes(bool axes) { this.axes = axes; } public void setLines(bool lines) { this.lines = lines; } public void setText(bool text) { this.text = text; } public void setLegend(bool legend) { this.legend = legend; } public void surfacePlotSetInverse(bool b) { if (surfacePlot != null) surfacePlot.setInverse(b); } public void setMinZValue(double minZ) { this.minZ = minZ; } public void setMaxZValue(double maxZ) { this.maxZ = maxZ; } public double getTransformRotationX() { return (180 / Math.PI) * transform.getRotationX(); } public double getTransformRotationY() { return (180 / Math.PI) * transform.getRotationY(); } public double getTransformRotationZ() { return (180 / Math.PI) * transform.getRotationZ(); } } }