123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248 |
- 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. <p>
- *
- * 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.
- * <p>
- * Available options:
- * <ul>
- * <li> <strong>PLOT_DOTSNOLIGHT</strong>: if used, no lightning options are applied (fastest)</li>
- * <li> <strong>PLOT_DOTS</strong>: draws dots</li>
- * <li> <strong>PLOT_LINES</strong>: draws lines</li>
- * <li> <strong>PLOT_MESH</strong>: draws a mesh</li>
- * <li> <strong>PLOT_FILLED</strong>: fills the 3d object completely (slowest)</li>
- * </ul>
- *
- * @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.
- * <p>
- * <ul>
- * <li> <strong>ORIGINAL</strong></li>
- * <li> <strong>GRAY</strong></li>
- * <li> <strong>SPECTRUM</strong></li>
- * <li> <strong>FIRE</strong></li>
- * <li> <strong>THERMAL</strong></li>
- * <li> <strong>ORANGE</strong></li>
- * <li> <strong>BLUE</strong></li>
- * <li> <strong>BLACK</strong></li>
- *</ul>
- *
- * @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 .
- * <p>
- * <ul>
- * <li>0: no light</li>
- * <li>1: strong light</li>
- * </ul>
- *
- * @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();
- }
- }
- }
|