| 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();        }    }}
 |