private static IEnumerable <Point3D> Wireframe2(Point3D[,] points)
        {
            var width            = points.GetLength(0);
            var heigth           = points.GetLength(1);
            var currentPoint     = new Point(0, heigth - 1);
            var finishPoint      = new Point(width - 1, 0);
            var currentDirection = new Vector(1, 0);
            var wireframe        = new List <Point3D>();

            while (true)
            {
                wireframe.Add(points[(int)currentPoint.X, (int)currentPoint.Y]);
                currentPoint.Offset(currentDirection.X, currentDirection.Y);
                wireframe.Add(points[(int)currentPoint.X, (int)currentPoint.Y]);
                if (currentPoint.X == 0 || currentPoint.X == width - 1)
                {
                    currentPoint.Offset(0, -1);
                    currentDirection.X = currentPoint.X == 0 ? 1 : -1;
                    if (currentPoint == finishPoint)
                    {
                        break;
                    }
                }
            }
            return(wireframe);
        }
Exemple #2
0
            public Point3D[] AddItem(Point3D[] item)
            {
                //數量少於陣列總長度則往後加入
                if (_count < _pointsStack.GetLength(0))
                {
                    _count++;

                    ExtensionMethods.Point3DExtensions.AddPoint3D(ref _totalValue, ref item);

                    ExtensionMethods.Point3DExtensions.DividePoint3D(ref _totalValue, _count, ref OutputPoint);
                }
                else
                {
                    Point3D[] temp = new Point3D[3]
                    {
                        _pointsStack[_currentIndex, 0], _pointsStack[_currentIndex, 1], _pointsStack[_currentIndex, 2]
                    };
                    ExtensionMethods.Point3DExtensions.SubtractPoint3D(ref _totalValue, ref temp);

                    ExtensionMethods.Point3DExtensions.AddPoint3D(ref _totalValue, ref item);

                    ExtensionMethods.Point3DExtensions.DividePoint3D(ref _totalValue, _count, ref OutputPoint);
                }

                _pointsStack[_currentIndex, 0] = item[0];
                _pointsStack[_currentIndex, 1] = item[1];
                _pointsStack[_currentIndex, 2] = item[2];

                _currentIndex++;
                _currentIndex = _currentIndex % _pointsStack.GetLength(0);



                return(OutputPoint);
            }
Exemple #3
0
        public MyColor GetPixelColor(int x, int y)
        {
            var objectColor = !_useImage ? _objectColor : _imageBitmap.GetPixel(x, y);

            Point3D vector;

            if (!_useMap || x >= _vectorMap.GetLength(0) || y >= _vectorMap.GetLength(1))
            {
                vector = new Point3D(0, 0, 1);
            }
            else
            {
                vector = _vectorMap[x, y];
            }

            var lightVector = _lightMoves ? GetLightVector(x, y) : ConstVector;

            double cos   = Cosinus(vector, lightVector);
            var    distR = (byte)(objectColor.R * _lightColor.X * cos * _distributedCoed);
            var    distG = (byte)(objectColor.G * _lightColor.Y * cos * _distributedCoed);
            var    distB = (byte)(objectColor.B * _lightColor.Z * cos * _distributedCoed);

            var R = GetRVector(vector, lightVector);

            var coef    = Math.Pow(Cosinus(R, ConstVector), _cosExp) * 256 * _mirrorCoef;
            var mirrorR = _lightColor.X * coef;
            var mirrorG = _lightColor.Y * coef;
            var mirrorB = _lightColor.Z * coef;

            var r = distR + mirrorR > 255 ? (byte)255 : (byte)(distR + mirrorR);
            var g = distG + mirrorG > 255 ? (byte)255 : (byte)(distG + mirrorG);
            var b = distB + mirrorB > 255 ? (byte)255 : (byte)(distG + mirrorB);

            return(new MyColor(r, g, b));
        }
        private void AddXYColor(ChartStyle2D cs2d, DataSeriesSurface ds)
        {
            Point3D[,] pts = ds.PointArray;
            double zmin = ds.ZDataMin();
            double zmax = ds.ZDataMax();

            // Draw surface on the XY plane:
            if (!IsInterp)
            {
                for (int i = 0; i < pts.GetLength(0) - 1; i++)
                {
                    for (int j = 0; j < pts.GetLength(1) - 1; j++)
                    {
                        plg                 = new Polygon();
                        plg.Stroke          = ds.LineColor;
                        plg.StrokeThickness = ds.LineThickness;
                        plg.Fill            = GetBrush(pts[i, j].Z, zmin, zmax);
                        if (IsLineColorMatch)
                        {
                            plg.Stroke = GetBrush(pts[i, j].Z, zmin, zmax);
                        }
                        plg.Points.Add(cs2d.NormalizePoint(new Point(pts[i, j].X, pts[i, j].Y)));
                        plg.Points.Add(cs2d.NormalizePoint(new Point(pts[i, j + 1].X, pts[i, j + 1].Y)));
                        plg.Points.Add(cs2d.NormalizePoint(new Point(pts[i + 1, j + 1].X, pts[i + 1, j + 1].Y)));
                        plg.Points.Add(cs2d.NormalizePoint(new Point(pts[i + 1, j].X, pts[i + 1, j].Y)));
                        cs2d.Chart2dCanvas.Children.Add(plg);
                    }
                }
            }
            else if (IsInterp)
            {
                for (int i = 0; i < pts.GetLength(0) - 1; i++)
                {
                    for (int j = 0; j < pts.GetLength(1) - 1; j++)
                    {
                        Point3D[] points = new Point3D[4];
                        points[0] = pts[i, j];
                        points[1] = pts[i, j + 1];
                        points[2] = pts[i + 1, j + 1];
                        points[3] = pts[i + 1, j];

                        Interp2D(cs2d, points, zmin, zmax);
                        plg        = new Polygon();
                        plg.Stroke = ds.LineColor;
                        if (IsLineColorMatch)
                        {
                            plg.Stroke = GetBrush(pts[i, j].Z, zmin, zmax);
                        }
                        plg.StrokeThickness = ds.LineThickness;
                        plg.Fill            = Brushes.Transparent;
                        plg.Points.Add(cs2d.NormalizePoint(new Point(pts[i, j].X, pts[i, j].Y)));
                        plg.Points.Add(cs2d.NormalizePoint(new Point(pts[i, j + 1].X, pts[i, j + 1].Y)));
                        plg.Points.Add(cs2d.NormalizePoint(new Point(pts[i + 1, j + 1].X, pts[i + 1, j + 1].Y)));
                        plg.Points.Add(cs2d.NormalizePoint(new Point(pts[i + 1, j].X, pts[i + 1, j].Y)));
                        cs2d.Chart2dCanvas.Children.Add(plg);
                    }
                }
            }
        }
Exemple #5
0
 private static Point3D[,] RemoveNoizes(Point3D[,] points)
 {
     for (var y = 0; y < points.GetLength(1); y++)
     {
         for (var x = 0; x < points.GetLength(0); x++)
         {
             var z = points[x, y].Z;
             points[x, y] = new Point3D(x, y, (z > 1200 || z < 700) ? 1200 : z);
         }
     }
     return(points);
 }
Exemple #6
0
 public static Point3d[,] ToPoint3d(this Point3D[,] pts)
 {
     if (!(pts == null))
     {
         var myPts = new Point3d[pts.GetLength(0), pts.GetLength(1)];
         for (int i = 0; i < pts.GetLength(0); i++)
         {
             for (int j = 0; j < pts.GetLength(1); j++)
             {
                 myPts[i, j] = pts[i, j].ToPoint3d();
             }
         }
         return(myPts);
     }
     return(null);
 }
Exemple #7
0
 private void AddAdjacentNeighbours(Point3D[,] edgesPoints, List <AdjacentPoints>[] adjacentPoints)
 {
     for (int i = 0; i < edgesPoints.GetLength(0); ++i)
     {
         AddEdgeNeighbours(edgesPoints, i, adjacentPoints[i]);
     }
 }
Exemple #8
0
        private void ParseEdge(string edgeStr, int edgeNumber, Point3D[,] pointsList)
        {
            var pointsAndAdjacentVertexStr = edgeStr.Split('|').ToArray();

            for (int i = 0; i < pointsAndAdjacentVertexStr.Length; ++i)
            {
                pointsList[edgeNumber, i] = ParsePoint(pointsAndAdjacentVertexStr[i]);
                if (i > 0)
                {
                    pointsList[edgeNumber, i].AddNeighbour(pointsList[edgeNumber, i - 1]);
                    pointsList[edgeNumber, i - 1].AddNeighbour(pointsList[edgeNumber, i]);
                }
            }
            pointsList[edgeNumber, 0].AddNeighbour(pointsList[edgeNumber, pointsList.GetLength(1) - 1]);
            pointsList[edgeNumber, pointsList.GetLength(1) - 1].AddNeighbour(pointsList[edgeNumber, 0]);
        }
Exemple #9
0
        ///<summary>贝塞尔平滑插点计算,Z方向</summary>
        private Point3D[,] insertZPoint(Point3D[,] allpoint, int insertcount) //z方向插点
        {
            // bezier平滑插值
            Point[] ap, cp1, cp2;
            Point   calpoint;

            Point3D[,] resultpoint = new Point3D[allpoint.GetLength(0), (allpoint.GetLength(1) - 1) * (insertcount + 1) + 1];
            Point[] cp = new Point[4];
            for (int i = 0; i < allpoint.GetLength(0); i++)
            {
                ap = new Point[allpoint.GetLength(1)];
                for (int j = 0; j < allpoint.GetLength(1); j++)
                {
                    ap[j].X = allpoint[i, j].Z;
                    ap[j].Y = allpoint[i, j].Y;
                }
                MyGeometryHelper.GetCurveControlPoints(ap, out cp1, out cp2);
                for (int j = 0; j < allpoint.GetLength(1) - 1; j++)
                {
                    resultpoint[i, j *(insertcount + 1)] = allpoint[i, j];  //原有的点
                    cp[0] = ap[j]; cp[1] = cp1[j]; cp[2] = cp2[j]; cp[3] = ap[j + 1];
                    for (int k = 0; k < insertcount; k++)
                    {
                        calpoint = MyGeometryHelper.PointOnBezier(cp, 1.0 / (insertcount + 1) * (k + 1));
                        resultpoint[i, j *(insertcount + 1) + 1 + k] = new Point3D(allpoint[i, j].X, calpoint.Y, calpoint.X);  //插入的点
                    }
                }
                resultpoint[i, (allpoint.GetLength(1) - 1) * (insertcount + 1)] = allpoint[i, allpoint.GetLength(1) - 1]; //原有的终点
            }
            return(resultpoint);
        }
Exemple #10
0
 private static Point3D[,] PreprocessPoints(Point3D[,] points)
 {
     for (int y = 0; y < points.GetLength(1); y++)
     {
         for (int x = 0; x < points.GetLength(0); x++)
         {
             if (y > 1 && (points[x, y] - points[x, y - 1]).Z < double.Epsilon)
             {
                 points[x, y - 1].Z = (points[x, y].Z + points[x, y - 2].Z) / 2;
             }
             if (x > 1 && (points[x, y] - points[x - 1, y]).Z < double.Epsilon)
             {
                 points[x - 1, y].Z = (points[x, y].Z + points[x - 2, y].Z) / 2;
             }
         }
     }
     return(points);
 }
Exemple #11
0
        private void AddWirefreamPoints(Point3D[,] pts)
        {
            Point3DCollection points = new Point3DCollection(pts.Length);
            int xLength = pts.GetLength(0);
            int yLength = pts.GetLength(1);

            for (int x = 0; x < xLength - 1; x++)
            {
                if (!double.IsNaN(pts[x, 0].Z))
                {
                    if (double.IsNaN(pts[x + 1, 0].Z))
                    {
                        for (int y = 0; y < yLength - 1; y++)
                        {
                            points.Add(pts[x, y]);
                            points.Add(pts[x, y + 1]);
                        }
                    }
                    else
                    {
                        for (int y = 0; y < yLength - 1; y++)
                        {
                            points.Add(pts[x, y]);
                            points.Add(pts[x, y + 1]);
                            points.Add(pts[x, y]);
                            points.Add(pts[x + 1, y]);
                        }
                        points.Add(pts[x, yLength - 1]);
                        points.Add(pts[x + 1, yLength - 1]);
                    }
                }
            }
            if (!double.IsNaN(pts[xLength - 1, 0].Z))
            {
                for (int y = 0; y < yLength - 1; y++)
                {
                    points.Add(pts[xLength - 1, y]);
                    points.Add(pts[xLength - 1, y + 1]);
                }
            }
            points.Freeze();
            base.Points = points;
        }
        private Material CreateVisibleSpectrumMaterial(Point3D[,] points)
        {
            int xWidth = points.GetLength(0);
            int yWidth = points.GetLength(1);

            colorCount = xWidth * yWidth;

            WriteableBitmap writeableBitmap = new WriteableBitmap(colorCount, 1, 96, 96, PixelFormats.Bgr24, null);

            writeableBitmap.Lock();

            unsafe
            {
                // Get a pointer to the back buffer.
                byte *pStart = (byte *)(void *)writeableBitmap.BackBuffer;
                int   nL     = writeableBitmap.BackBufferStride;

                for (int ix = 0; ix < colorCount; ix += 1)
                {
                    Color color = ColorHelper.GetGradientColor(Colors.Blue, Colors.Red, (double)ix / colorCount);

                    *(pStart + ix * 3 + 0) = (byte)(color.B);
                    *(pStart + ix * 3 + 1) = (byte)(color.G);
                    *(pStart + ix * 3 + 2) = (byte)(color.R);
                }
            }

            writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, colorCount, 1));

            // Release the back buffer and make it available for display.
            writeableBitmap.Unlock();

            ImageBrush imageBrush = new ImageBrush(writeableBitmap);

            imageBrush.ViewportUnits = BrushMappingMode.Absolute;

            SpecularMaterial material = new SpecularMaterial();

            material.Brush = imageBrush;

            bitMap = writeableBitmap;
            return(material);
        }
Exemple #13
0
 public static Point3D[,] ReadPoints(string fileName)
 {
     using (var fstream = File.OpenRead(fileName))
     {
         var array = new byte[fstream.Length];
         fstream.Read(array, 0, array.Length);
         var textFromFile = System.Text.Encoding.Default.GetString(array);
         var rows         = textFromFile.Split("\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
         var firstRow     = rows[0].Split('\t');
         Points = new Point3D[firstRow.Length - (int)CropSize.Width * 2, rows.Length - (int)CropSize.Height * 2];
         for (var y = 0; y < Points.GetLength(1); y++)
         {
             var values = rows[y].Split('\t');
             for (var x = 0; x < Points.GetLength(0); x++)
             {
                 Points[x, y] = new Point3D(x, y, int.Parse(values[x + (int)CropSize.Width]));
             }
         }
         return(Points);
     }
 }
        private void AddXYColor3D(ChartStyle cs, DataSeriesSurface ds)
        {
            Point3D[,] pts  = ds.PointArray;
            Point3D[,] pts1 = new Point3D[pts.GetLength(0), pts.GetLength(1)];
            Matrix3D m   = Utility.AzimuthElevation(cs.Elevation, cs.Azimuth);
            Polygon  plg = new Polygon();

            // Find the minumum and maximum z values:
            double zmin = ds.ZDataMin();
            double zmax = ds.ZDataMax();

            // Perform transformation on points:
            for (int i = 0; i < pts.GetLength(0); i++)
            {
                for (int j = 0; j < pts.GetLength(1); j++)
                {
                    // Make a deep copy the points array:
                    pts1[i, j] = new Point3D(pts[i, j].X, pts[i, j].Y, cs.Zmin);
                    pts1[i, j] = cs.Normalize3D(m, pts1[i, j]);
                }
            }

            // Draw surface on the XY plane:
            for (int i = 0; i < pts.GetLength(0) - 1; i++)
            {
                for (int j = 0; j < pts.GetLength(1) - 1; j++)
                {
                    plg = new Polygon();
                    plg.Points.Add(new Point(pts1[i, j].X, pts1[i, j].Y));
                    plg.Points.Add(new Point(pts1[i, j + 1].X, pts1[i, j + 1].Y));
                    plg.Points.Add(new Point(pts1[i + 1, j + 1].X, pts1[i + 1, j + 1].Y));
                    plg.Points.Add(new Point(pts1[i + 1, j].X, pts1[i + 1, j].Y));
                    plg.StrokeThickness = ds.LineThickness;
                    plg.Fill            = GetBrush(pts[i, j].Z, zmin, zmax);
                    plg.Stroke          = GetBrush(pts[i, j].Z, zmin, zmax);
                    cs.ChartCanvas.Children.Add(plg);
                }
            }
        }
Exemple #15
0
        static public bool mesh2Tri(Point3D[,] dbArray, double dbThreshold, out ushort[,] nFacesIndex, out double[,] dbVertices, TriType type)
        {
            nFacesIndex = null;
            dbVertices  = null;

            if (dbArray == null)
            {
                return(false);
            }

            int nRows = dbArray.GetLength(0);
            int nCols = dbArray.GetLength(1);


            #region 判断产生的模型点是否在坑径范围内
            bool[,] bFlags = new bool[nRows, nCols];
            dbVertices     = new double[nRows * nCols, 3];

            for (int i = 0; i < nRows; i++)
            {
                for (int j = 0; j < nCols; j++)
                {
                    double dbX = dbArray[i, j].X;
                    double dbY = dbArray[i, j].Y;
                    double dbZ = dbArray[i, j].Z;

                    dbVertices[i * nCols + j, 0] = dbX;
                    dbVertices[i * nCols + j, 1] = dbY;
                    dbVertices[i * nCols + j, 2] = dbZ;

                    if (Math.Sqrt(dbX * dbX + dbY * dbY) <= dbThreshold)
                    {
                        bFlags[i, j] = true;
                    }
                    else
                    {
                        bFlags[i, j] = false;
                    }
                }
            }
            #endregion

            #region 构面
            //分别记录坑径范围内的点构成面的各节点的索引
            List <Point3D> listFaces = new List <Point3D>();
            switch (type)
            {
            case TriType.TriForward:
                for (int i = 0; i < nRows - 1; i++)
                {
                    for (int j = 0; j < nCols - 1; j++)
                    {
                        if (bFlags[i, j] && bFlags[i + 1, j] && bFlags[i, j + 1])
                        {
                            listFaces.Add(new Point3D(i * nCols + j, (i + 1) * nCols + j, i * nCols + j + 1));
                        }


                        if (bFlags[i + 1, j + 1] && bFlags[i, j + 1] && bFlags[i + 1, j])
                        {
                            listFaces.Add(new Point3D((i + 1) * nCols + j + 1, i * nCols + j + 1, (i + 1) * nCols + j));
                        }
                    }
                }
                break;

            case TriType.TriBackward:
                for (int i = 0; i < nRows - 1; i++)
                {
                    for (int j = 0; j < nCols - 1; j++)
                    {
                        if (bFlags[i, j] && bFlags[i + 1, j] && bFlags[i + 1, j + 1])
                        {
                            listFaces.Add(new Point3D(i * nCols + j, (i + 1) * nCols + j, (i + 1) * nCols + j + 1));
                        }

                        if (bFlags[i, j] && bFlags[i, j + 1] && bFlags[i + 1, j + 1])
                        {
                            listFaces.Add(new Point3D(i * nCols + j, i * nCols + j + 1, (i + 1) * nCols + j + 1));
                        }
                    }
                }
                break;

            default:
                break;
            }
            #endregion

            #region
            int nFaceCount = listFaces.Count;
            nFacesIndex = new ushort[nFaceCount, 3];
            for (int i = 0; i < nFaceCount; i++)
            {
                nFacesIndex[i, 0] = (ushort)listFaces[i].X;
                nFacesIndex[i, 1] = (ushort)listFaces[i].Y;
                nFacesIndex[i, 2] = (ushort)listFaces[i].Z;
            }
            #endregion

            return(true);
        }
Exemple #16
0
        ///<summary>生成3D模型</summary>
        public void genModel()
        {
            //数据初始化
            //定义参数
            double maxX3D = parent.para.Limit.X, maxY3D = parent.para.Limit.Y, maxZ3D = parent.para.Limit.Z;  // 3D场景最大坐标
            int    xcount = 12, zcount = 24, xcountData, zcountData = 25;

            // x y 方向数目,x为月数,z为小时数,其中,xcount表征月分,xcountData为数据的x方向个数
            //zcount为0-23点,但zcountData为0-24点,多一个数据,同理,xcount中,增加一个数,全年下为12.31日
            xcountData = samplePoints.GroupBy(p => p.zDate.Date).Count();

            MeshGeometry3D mesh = new MeshGeometry3D();

            double devx = maxX3D / (xcount), devy = maxY3D / parent.maxYValue, devz = maxZ3D / (zcount);

            allpoint = new Point3D[xcountData, zcountData];

            double tx, tz;
            int    di, dj;

            di = 0;
            DateTime olddate = samplePoints.OrderBy(p => p.zDate).First().zDate.Date;

            foreach (var e in samplePoints.OrderBy(p => p.zDate))
            {
                //di = e.zDate.Month - 1;
                if (e.zDate.Date != olddate)
                {
                    di++;
                    olddate = e.zDate.Date;
                }

                dj = e.zDate.Hour;

                allpoint[di, dj] = new Point3D((double)((e.zDate - parent.startDate).TotalDays - 1) / ((parent.endDate - parent.startDate).TotalDays - 1) * maxX3D, devy * (double)e.zValue, -devz * dj);
                if (dj == 0) //赋第24点,以本日0代替
                {
                    allpoint[di, zcountData - 1] = new Point3D((double)((e.zDate - parent.startDate).TotalDays - 1) / ((parent.endDate - parent.startDate).TotalDays - 1) * maxX3D, devy * (double)e.zValue, -devz * (zcountData - 1));
                }
            }


            allpoint = insertZPoint(allpoint, 2); //z插点
            allpoint = insertXPoint(allpoint, 2); //x插点



            for (int i = 0; i < allpoint.GetLength(0); i++)  //加positions
            {
                for (int j = 0; j < allpoint.GetLength(1); j++)
                {
                    mesh.Positions.Add(allpoint[i, j]);
                    tx = 1.0 * i / allpoint.GetLength(0);
                    tz = 1.0 * j / allpoint.GetLength(1);
                    mesh.TextureCoordinates.Add(new Point(tx, tz));
                }
            }

            for (int i = 0; i < allpoint.GetLength(0) - 1; i++) // 加三角索引
            {
                for (int j = 0; j < allpoint.GetLength(1) - 1; j++)
                {
                    mesh.TriangleIndices.Add(j + i * allpoint.GetLength(1));
                    mesh.TriangleIndices.Add(j + (i + 1) * allpoint.GetLength(1));
                    mesh.TriangleIndices.Add(j + 1 + i * allpoint.GetLength(1));
                    mesh.TriangleIndices.Add(j + 1 + i * allpoint.GetLength(1));
                    mesh.TriangleIndices.Add(j + (i + 1) * allpoint.GetLength(1));
                    mesh.TriangleIndices.Add(j + 1 + (i + 1) * allpoint.GetLength(1));
                }
            }


            //===============  曲面材质
            Canvas panelLine = new Canvas();

            panelLine.Width  = devx * (parent.endDate - parent.startDate).TotalDays;
            panelLine.Height = devz * 23 * 30;
            //色变化说明:最高255,0,0最低0,255,0;从低到高变化顺序1:R 0->255,2:G 255->0;

            double x, y, maxy = 10, miny = 0, maxh = panelLine.Height, maxw = panelLine.Width;
            double w = maxw / (allpoint.GetLength(0) - 1), h = maxh / (allpoint.GetLength(1) - 1);
            double v;
            Color  c1, c2;
            byte   cr, cg, cb = 0;

            maxy = 0; miny = 10000;
            for (int i = 0; i < allpoint.GetLength(0) - 1; i++)
            {
                for (int j = 0; j < allpoint.GetLength(1) - 1; j++)
                {
                    if (allpoint[i, j].Y > maxy)
                    {
                        maxy = allpoint[i, j].Y;
                    }
                    if (allpoint[i, j].Y < miny)
                    {
                        miny = allpoint[i, j].Y;
                    }
                }
            }

            Point3D lastpoint = allpoint[allpoint.GetLength(0) - 1, allpoint.GetLength(1) - 1];

            for (int i = 0; i < allpoint.GetLength(0) - 1; i++)
            {
                for (int j = 0; j < allpoint.GetLength(1) - 1; j++)
                {
                    x = allpoint[i, j].X / lastpoint.X * maxw;
                    y = allpoint[i, j].Z / lastpoint.Z * maxh;

                    w = (allpoint[i + 1, j].X - allpoint[i, j].X) / lastpoint.X * maxw;

                    double temp = 1;// .2;//新疆怪需求,人为加大最大值,以避免纯红
                    v  = (allpoint[i, j].Y - miny) / (maxy * temp - miny) * 511;
                    cr = v > 255 ? (byte)255 : (byte)v;
                    cg = v > 255 ? (byte)(255 - (v - 256)) : (byte)255;
                    c1 = Color.FromRgb(cr, cg, cb);
                    v  = (allpoint[i + 1, j + 1].Y - miny) / (maxy * temp - miny) * 511;
                    cr = v > 255 ? (byte)255 : (byte)v;
                    cg = v > 255 ? (byte)(255 - (v - 256)) : (byte)255;
                    c2 = Color.FromRgb(cr, cg, cb);

                    RectangleGeometry rect = new RectangleGeometry(new Rect(x, y, w, h));
                    rect.Freeze();
                    Path pr = new Path();
                    pr.Data = rect;
                    LinearGradientBrush cbrush = new LinearGradientBrush(c1, c2, new Point(0, 0), new Point(1, 1));
                    pr.Fill            = cbrush;
                    pr.StrokeThickness = 0;

                    panelLine.Children.Add(pr);
                }
            }
            panelLine.Measure(new System.Windows.Size(h, w));
            panelLine.Arrange(new Rect(0, 0, h, w));



            System.Windows.Media.Imaging.RenderTargetBitmap renderTarget = new System.Windows.Media.Imaging.RenderTargetBitmap((int)panelLine.Width, (int)panelLine.Height, 96, 96, PixelFormats.Pbgra32);
            renderTarget.Render(panelLine);
            renderTarget.Freeze();
            curveBrush = new ImageBrush(renderTarget);
            DiffuseMaterial mat = new DiffuseMaterial(curveBrush);

            mat.Freeze();

            model = new GeometryModel3D(mesh, mat);

            model.BackMaterial = mat;
        }
        private void AddWaterfall(ChartStyle cs, DataSeriesSurface ds)
        {
            Matrix3D m   = Utility.AzimuthElevation(cs.Elevation, cs.Azimuth);
            Polygon  plg = new Polygon();

            Point3D[,] pts = ds.PointArray;
            Point3D[] pt3     = new Point3D[pts.GetLength(0) + 2];
            double[]  zValues = new double[pts.Length];
            Point[]   pta     = new Point[pts.GetLength(0) + 2];
            double    zmin    = ds.ZDataMin();
            double    zmax    = ds.ZDataMax();

            for (int j = 0; j < pts.GetLength(1); j++)
            {
                int jj = j;
                if (cs.Elevation >= 0)
                {
                    if (cs.Azimuth >= -90 && cs.Azimuth < 90)
                    {
                        jj = pts.GetLength(1) - 1 - j;
                    }
                }
                else if (cs.Elevation < 0)
                {
                    jj = pts.GetLength(1) - 1 - j;
                    if (cs.Azimuth >= -90 && cs.Azimuth < 90)
                    {
                        jj = j;
                    }
                }
                for (int i = 0; i < pts.GetLength(0); i++)
                {
                    pt3[i + 1] = pts[i, jj];

                    if (i == 0)
                    {
                        pt3[0] = new Point3D(pt3[i + 1].X, pt3[i + 1].Y, cs.Zmin);
                    }
                    if (i == pts.GetLength(0) - 1)
                    {
                        pt3[pts.GetLength(0) + 1] = new Point3D(pt3[i + 1].X, pt3[i + 1].Y, cs.Zmin);
                    }
                }
                plg = new Polygon();
                for (int i = 0; i < pt3.Length; i++)
                {
                    zValues[i] = pt3[i].Z;
                    pt3[i]     = cs.Normalize3D(m, pt3[i]);
                    pta[i]     = new Point(pt3[i].X, pt3[i].Y);
                    plg.Points.Add(new Point(pt3[i].X, pt3[i].Y));
                }
                plg.Stroke          = Brushes.Transparent;
                plg.StrokeThickness = ds.LineThickness;
                plg.Fill            = Brushes.White;
                cs.ChartCanvas.Children.Add(plg);

                for (int i = 1; i < pt3.Length; i++)
                {
                    Line line = new Line();
                    line.Stroke          = Brushes.Black;
                    line.StrokeThickness = ds.LineThickness;
                    if (IsColormap)
                    {
                        if (i < pt3.Length - 1)
                        {
                            line.Stroke = GetBrush(zValues[i], zmin, zmax);
                        }
                        else
                        {
                            line.Stroke = GetBrush(zValues[i - 1], zmin, zmax);
                        }
                    }
                    line.X1 = pta[i - 1].X;
                    line.Y1 = pta[i - 1].Y;
                    line.X2 = pta[i].X;
                    line.Y2 = pta[i].Y;
                    cs.ChartCanvas.Children.Add(line);
                }
            }

            if (cs.IsColorBar && IsColormap)
            {
                AddColorBar(cs, ds, zmin, zmax);
            }
        }
        public void AddMesh(ChartStyle cs, DataSeriesSurface ds)
        {
            Matrix3D m   = Utility.AzimuthElevation(cs.Elevation, cs.Azimuth);
            Polygon  plg = new Polygon();

            Point3D[,] pts    = ds.PointArray;
            double[,] zValues = new double[pts.GetLength(0), pts.GetLength(1)];
            double zmin = ds.ZDataMin();
            double zmax = ds.ZDataMax();

            for (int i = 0; i < pts.GetLength(0); i++)
            {
                for (int j = 0; j < pts.GetLength(1); j++)
                {
                    zValues[i, j] = pts[i, j].Z;
                    pts[i, j]     = cs.Normalize3D(m, pts[i, j]);
                }
            }

            // Draw mesh chart:
            for (int i = 0; i < pts.GetLength(0) - 1; i++)
            {
                int ii = i;
                if (cs.Elevation >= 0)
                {
                    ii = i;
                    if (cs.Azimuth >= -180 && cs.Azimuth < 0)
                    {
                        ii = pts.GetLength(0) - 2 - i;
                    }
                }
                else
                {
                    ii = pts.GetLength(0) - 2 - i;
                    if (cs.Azimuth >= -180 && cs.Azimuth < 0)
                    {
                        ii = i;
                    }
                }
                for (int j = 0; j < pts.GetLength(1) - 1; j++)
                {
                    int jj = j;
                    if (cs.Elevation < 0)
                    {
                        jj = pts.GetLength(1) - 2 - j;
                    }
                    plg = new Polygon();
                    plg.Points.Add(new Point(pts[ii, jj].X, pts[ii, jj].Y));
                    plg.Points.Add(new Point(pts[ii, jj + 1].X, pts[ii, jj + 1].Y));
                    plg.Points.Add(new Point(pts[ii + 1, jj + 1].X, pts[ii + 1, jj + 1].Y));
                    plg.Points.Add(new Point(pts[ii + 1, jj].X, pts[ii + 1, jj].Y));

                    plg.Stroke          = Brushes.Black;
                    plg.StrokeThickness = ds.LineThickness;
                    plg.Fill            = Brushes.White;
                    if (!IsHiddenLine)
                    {
                        plg.Fill = Brushes.Transparent;
                    }
                    if (IsColormap)
                    {
                        plg.Stroke = GetBrush(zValues[ii, jj], zmin, zmax);
                    }
                    cs.ChartCanvas.Children.Add(plg);
                }
            }
            if (cs.IsColorBar && IsColormap)
            {
                AddColorBar(cs, ds, zmin, zmax);
            }
        }
        private void AddContour(ChartStyle2D cs2d, DataSeriesSurface ds)
        {
            Point[]         pta   = new Point[2];
            SolidColorBrush brush = Brushes.Black;
            Line            line  = new Line();

            Point3D[,] pts = ds.PointArray;
            double zmin = ds.ZDataMin();
            double zmax = ds.ZDataMax();

            double[] zlevels = new double[NumberContours];

            for (int i = 0; i < NumberContours; i++)
            {
                zlevels[i] = zmin + i * (zmax - zmin) / (NumberContours - 1);
            }

            int    i0, i1, i2, j0, j1, j2;
            double zratio = 1;

            // Draw contour on the XY plane:
            for (int i = 0; i < pts.GetLength(0) - 1; i++)
            {
                for (int j = 0; j < pts.GetLength(1) - 1; j++)
                {
                    if (IsColormap && ChartType != ChartTypeEnum.FillContour)
                    {
                        brush = GetBrush(pts[i, j].Z, zmin, zmax);
                    }
                    for (int k = 0; k < NumberContours; k++)
                    {
                        // Left triangle:
                        i0 = i;
                        j0 = j;
                        i1 = i;
                        j1 = j + 1;
                        i2 = i + 1;
                        j2 = j + 1;
                        if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k] < pts[i1, j1].Z ||
                             zlevels[k] < pts[i0, j0].Z && zlevels[k] >= pts[i1, j1].Z) &&
                            (zlevels[k] >= pts[i1, j1].Z && zlevels[k] <
                             pts[i2, j2].Z || zlevels[k] < pts[i1, j1].Z && zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i1, j1].Z - pts[i0, j0].Z);
                            pta[0] = cs2d.NormalizePoint(new Point(pts[i0, j0].X, (1 - zratio) * pts[i0, j0].Y + zratio * pts[i1, j1].Y));
                            zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z);
                            pta[1] = cs2d.NormalizePoint(new Point((1 - zratio) * pts[i1, j1].X + zratio * pts[i2, j2].X, pts[i1, j1].Y));
                            DrawLine(cs2d, ds, brush, pta[0], pta[1]);
                        }
                        else if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k]
                                  < pts[i2, j2].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i2, j2].Z) &&
                                 (zlevels[k] >= pts[i1, j1].Z && zlevels[k] <
                                  pts[i2, j2].Z || zlevels[k] < pts[i1, j1].Z &&
                                  zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i2, j2].Z - pts[i0, j0].Z);
                            pta[0] = cs2d.NormalizePoint(new Point((1 - zratio) * pts[i0, j0].X + zratio * pts[i2, j2].X,
                                                                   (1 - zratio) * pts[i0, j0].Y + zratio * pts[i2, j2].Y));
                            zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z);
                            pta[1] = cs2d.NormalizePoint(new Point((1 - zratio) * pts[i1, j1].X + zratio * pts[i2, j2].X, pts[i1, j1].Y));
                            DrawLine(cs2d, ds, brush, pta[0], pta[1]);
                        }
                        else if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k]
                                  < pts[i1, j1].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i1, j1].Z) &&
                                 (zlevels[k] >= pts[i0, j0].Z && zlevels[k] <
                                  pts[i2, j2].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i1, j1].Z - pts[i0, j0].Z);
                            pta[0] = cs2d.NormalizePoint(new Point(pts[i0, j0].X, (1 - zratio) * pts[i0, j0].Y + zratio * pts[i1, j1].Y));
                            zratio = (zlevels[k] - pts[i0, j0].Z) / (pts[i2, j2].Z - pts[i0, j0].Z);
                            pta[1] = cs2d.NormalizePoint(new Point(pts[i0, j0].X * (1 - zratio) + pts[i2, j2].X * zratio,
                                                                   pts[i0, j0].Y * (1 - zratio) + pts[i2, j2].Y * zratio));
                            DrawLine(cs2d, ds, brush, pta[0], pta[1]);
                        }

                        // right triangle:
                        i0 = i;
                        j0 = j;
                        i1 = i + 1;
                        j1 = j;
                        i2 = i + 1;
                        j2 = j + 1;
                        if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k] <
                             pts[i1, j1].Z || zlevels[k] < pts[i0, j0].Z &&
                             zlevels[k] >= pts[i1, j1].Z) &&
                            (zlevels[k] >= pts[i1, j1].Z && zlevels[k]
                             < pts[i2, j2].Z || zlevels[k] < pts[i1, j1].Z &&
                             zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i1, j1].Z - pts[i0, j0].Z);
                            pta[0] = cs2d.NormalizePoint(new Point(pts[i0, j0].X * (1 - zratio) + pts[i1, j1].X * zratio, pts[i0, j0].Y));
                            zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z);
                            pta[1] = cs2d.NormalizePoint(new Point(pts[i1, j1].X, pts[i1, j1].Y * (1 - zratio) + pts[i2, j2].Y * zratio));
                            DrawLine(cs2d, ds, brush, pta[0], pta[1]);
                        }
                        else if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k]
                                  < pts[i2, j2].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i2, j2].Z) &&
                                 (zlevels[k] >= pts[i1, j1].Z && zlevels[k] <
                                  pts[i2, j2].Z || zlevels[k] < pts[i1, j1].Z &&
                                  zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i2, j2].Z - pts[i0, j0].Z);
                            pta[0] = cs2d.NormalizePoint(new Point(pts[i0, j0].X * (1 - zratio) +
                                                                   pts[i2, j2].X * zratio, pts[i0, j0].Y * (1 - zratio) + pts[i2, j2].Y * zratio));
                            zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z);
                            pta[1] = cs2d.NormalizePoint(new Point(pts[i1, j1].X, pts[i1, j1].Y * (1 - zratio) + pts[i2, j2].Y * zratio));
                            DrawLine(cs2d, ds, brush, pta[0], pta[1]);
                        }
                        else if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k]
                                  < pts[i1, j1].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i1, j1].Z) &&
                                 (zlevels[k] >= pts[i0, j0].Z && zlevels[k] <
                                  pts[i2, j2].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i1, j1].Z - pts[i0, j0].Z);
                            pta[0] = cs2d.NormalizePoint(new Point(pts[i0, j0].X * (1 - zratio) + pts[i1, j1].X * zratio, pts[i0, j0].Y));
                            zratio = (zlevels[k] - pts[i0, j0].Z) / (pts[i2, j2].Z - pts[i0, j0].Z);
                            pta[1] = cs2d.NormalizePoint(new Point(pts[i0, j0].X * (1 - zratio) + pts[i2, j2].X * zratio,
                                                                   pts[i0, j0].Y * (1 - zratio) + pts[i2, j2].Y * zratio));
                            DrawLine(cs2d, ds, brush, pta[0], pta[1]);
                        }
                    }
                }
            }
        }
Exemple #20
0
        internal Geometry getValueGeometry(double zvalue, double vWidth, double vHeight)
        {
            if (con == null)
            {
                int idx = 0;

                //用allpoint来插点
                double  devy      = parent.para.Limit.Y / parent.maxYValue;
                double  tmpy      = devy * zvalue;
                Point3D lastpoint = allpoint[allpoint.GetLength(0) - 1, allpoint.GetLength(1) - 1];
                for (int i = 0; i < allpoint.GetLength(0) - 1; i++)
                {
                    for (int j = 0; j < allpoint.GetLength(1) - 1; j++)
                    {
                        double tmpx = allpoint[i, j].X / lastpoint.X;
                        double tmpz = allpoint[i, j].Z / lastpoint.Z;
                        //allpoint[di, dj] = new Point3D((double)((e.zDate - parent.startDate).TotalDays - 1) / ((parent.endDate - parent.startDate).TotalDays - 1) * maxX3D, devy * (double)e.zValue, -devz * dj);

                        dots.Add(new ValueDot()
                        {
                            id       = idx.ToString(),
                            location = new Point(vWidth * tmpz, vHeight * tmpx),
                            value    = allpoint[i, j].Y >= tmpy ? 2 : 0
                        });
                        idx++;
                    }
                }

                //设置计算参数
                con             = new Contour();
                con.dots        = dots;
                con.opacityType = Contour.EOpacityType.正坡形;
                con.canvSize    = new Size(vWidth, vHeight);
                con.gridXCount  = 100;
                con.gridYCount  = 50;
                con.Span        = 2;
                con.maxvalue    = 2;
                con.minvalue    = 0;
                con.isDrawGrid  = false;
                con.isDrawLine  = false;
                con.isFillLine  = true;
                con.GenGeometry();
            }
            else
            {
                int idx = 0;

                double  devy      = parent.para.Limit.Y / parent.maxYValue;
                double  tmpy      = devy * zvalue;
                Point3D lastpoint = allpoint[allpoint.GetLength(0) - 1, allpoint.GetLength(1) - 1];
                for (int i = 0; i < allpoint.GetLength(0) - 1; i++)
                {
                    for (int j = 0; j < allpoint.GetLength(1) - 1; j++)
                    {
                        dots[idx].value = allpoint[i, j].Y >= tmpy ? 2 : 0;
                        idx++;
                    }
                }
                con.ReGenGeometry();
            }

            return(con.geometry);
        }
Exemple #21
0
        public static Point3D[,] BuildSurface(Point3D[,] points, int degree, Size size)
        {
            SurfacePoints = new Point3D[(int)size.Width, (int)size.Height];
            var knotsX     = BuildKnots(points.GetLength(0), degree);
            var knotsY     = BuildKnots(points.GetLength(1), degree);
            var knotsXList = knotsX.ToList();
            var knotsYList = knotsY.ToList();
            var incrementX = (points.GetLength(0) - degree + 2) / (size.Width - 1);
            var incrementY = (points.GetLength(1) - degree + 2) / (size.Height - 1);

            Parallel.For(0, SurfacePoints.GetLength(0), i =>
            {
                var intervalX = i * incrementX;
                Parallel.For(0, SurfacePoints.GetLength(1), j =>
                {
                    var intervalY = j * incrementY;
                    var kFlag     = false;
                    for (var k = 0; k < points.GetLength(0); k++)
                    {
                        var bi = SplineBlend(k, degree, knotsX, intervalX);
                        if (bi == 0)
                        {
                            if (kFlag)
                            {
                                break;
                            }
                            continue;
                        }
                        kFlag     = true;
                        var lFlag = false;
                        for (var l = 0; l < points.GetLength(1); l++)
                        {
                            var bj = SplineBlend(l, degree, knotsY, intervalY);
                            if (bj == 0)
                            {
                                if (lFlag)
                                {
                                    break;
                                }
                                continue;
                            }
                            lFlag = true;
                            SurfacePoints[i, j] = SurfacePoints[i, j].Add(points[k, l].Multiply(bi).Multiply(bj));
                        }
                    }
                    intervalY += incrementY;
                });
            });

            var intervalX2 = 0d;

            for (var i = 0; i < SurfacePoints.GetLength(0) - 1; i++)
            {
                for (var j = 0; j < points.GetLength(0); j++)
                {
                    SurfacePoints[i, SurfacePoints.GetLength(1) - 1] =
                        SurfacePoints[i, SurfacePoints.GetLength(1) - 1]
                        .Add(points[j, points.GetLength(1) - 1]
                             .Multiply(SplineBlend(j, degree, knotsX, intervalX2)));
                }
                intervalX2 += incrementX;
            }
            var intervalY2 = 0d;

            for (var i = 0; i < SurfacePoints.GetLength(1) - 1; i++)
            {
                for (var j = 0; j < points.GetLength(1); j++)
                {
                    SurfacePoints[SurfacePoints.GetLength(0) - 1, i] =
                        SurfacePoints[SurfacePoints.GetLength(0) - 1, i]
                        .Add(points[points.GetLength(0) - 1, j]
                             .Multiply(SplineBlend(j, degree, knotsY, intervalY2)));
                }
                intervalY2 += incrementY;
            }
            SurfacePoints[SurfacePoints.GetLength(0) - 1, SurfacePoints.GetLength(1) - 1] = points[points.GetLength(0) - 1, points.GetLength(1) - 1];
            return(SurfacePoints);
        }
        protected override void Triangulate(DependencyPropertyChangedEventArgs args,
                                            Point3DCollection vertices,
                                            Vector3DCollection normals,
                                            Int32Collection indices,
                                            PointCollection textures)
        {
            vertices.Clear();
            normals.Clear();
            indices.Clear();
            textures.Clear();

            Point3D[,] faces = Faces;
            PointCollection texturesBase  = TextureCoordinates;
            int             indexTextures = 0;

            for (int face = 0; face < faces.GetLength(0); face++)
            {
                Vector3D normal = Vector3D.CrossProduct(faces[face, 1] - faces[face, 0],
                                                        faces[face, 2] - faces[face, 0]);

                // For faces that are triangles.
                if (faces.GetLength(1) == 3)
                {
                    int indexBase = vertices.Count;

                    for (int i = 0; i < 3; i++)
                    {
                        vertices.Add(faces[face, i]);
                        normals.Add(normal);
                        indices.Add(indexBase + i);

                        if (texturesBase != null && texturesBase.Count > 0)
                        {
                            textures.Add(texturesBase[indexTextures]);
                            indexTextures = (indexTextures + 1) % texturesBase.Count;
                        }
                    }

                    if (Slices > 1)
                    {
                        TriangleSubdivide(vertices, normals, indices, textures);
                    }
                }

                // For faces that are not triangles.
                else
                {
                    for (int i = 0; i < faces.GetLength(1) - 1; i++)
                    {
                        int indexBase = vertices.Count;
                        int num       = faces.GetLength(1) - 1;

                        vertices.Add(faces[face, 0]);
                        vertices.Add(faces[face, i + 1]);
                        vertices.Add(faces[face, (i + 1) % num + 1]);

                        if (texturesBase != null && texturesBase.Count >= faces.GetLength(1))
                        {
                            textures.Add(texturesBase[indexTextures + 0]);
                            textures.Add(texturesBase[indexTextures + i + 1]);
                            textures.Add(texturesBase[indexTextures + (i + 1) % num + 1]);
                        }

                        normals.Add(normal);
                        normals.Add(normal);
                        normals.Add(normal);

                        indices.Add(indexBase + 0);
                        indices.Add(indexBase + 1);
                        indices.Add(indexBase + 2);

                        if (Slices > 1)
                        {
                            TriangleSubdivide(vertices, normals, indices, textures);
                        }
                    }
                    if (texturesBase != null && texturesBase.Count > 0)
                    {
                        indexTextures = (indexTextures + faces.GetLength(1)) % texturesBase.Count;
                    }
                }
            }
        }
        private void AddMeshZ(ChartStyle cs, DataSeriesSurface ds)
        {
            Matrix3D m   = Utility.AzimuthElevation(cs.Elevation, cs.Azimuth);
            Polygon  plg = new Polygon();

            Point3D[,] pts    = ds.PointArray;
            Point3D[,] pts1   = new Point3D[pts.GetLength(0), pts.GetLength(1)];
            double[,] zValues = new double[pts.GetLength(0), pts.GetLength(1)];
            double zmin = ds.ZDataMin();
            double zmax = ds.ZDataMax();

            for (int i = 0; i < pts.GetLength(0); i++)
            {
                for (int j = 0; j < pts.GetLength(1); j++)
                {
                    zValues[i, j] = pts[i, j].Z;
                    pts1[i, j]    = new Point3D(pts[i, j].X, pts[i, j].Y, pts[i, j].Z);
                    pts[i, j]     = cs.Normalize3D(m, pts[i, j]);
                }
            }

            // Draw mesh using the z-order method:
            for (int i = 0; i < pts.GetLength(0) - 1; i++)
            {
                int ii = i;
                if (cs.Elevation >= 0)
                {
                    ii = i;
                    if (cs.Azimuth >= -180 && cs.Azimuth < 0)
                    {
                        ii = pts.GetLength(0) - 2 - i;
                    }
                }
                else
                {
                    ii = pts.GetLength(0) - 2 - i;
                    if (cs.Azimuth >= -180 && cs.Azimuth < 0)
                    {
                        ii = i;
                    }
                }
                for (int j = 0; j < pts.GetLength(1) - 1; j++)
                {
                    int jj = j;
                    if (cs.Elevation < 0)
                    {
                        jj = pts.GetLength(1) - 2 - j;
                    }
                    plg = new Polygon();
                    plg.Points.Add(new Point(pts[ii, jj].X, pts[ii, jj].Y));
                    plg.Points.Add(new Point(pts[ii, jj + 1].X, pts[ii, jj + 1].Y));
                    plg.Points.Add(new Point(pts[ii + 1, jj + 1].X, pts[ii + 1, jj + 1].Y));
                    plg.Points.Add(new Point(pts[ii + 1, jj].X, pts[ii + 1, jj].Y));

                    plg.Stroke          = Brushes.Black;
                    plg.StrokeThickness = ds.LineThickness;
                    plg.Fill            = Brushes.White;
                    if (!IsHiddenLine)
                    {
                        plg.Fill = Brushes.Transparent;
                    }
                    if (IsColormap)
                    {
                        plg.Stroke = GetBrush(zValues[ii, jj], zmin, zmax);
                    }
                    cs.ChartCanvas.Children.Add(plg);
                }
            }

            //Draw curtain lines:
            Point3D[] pta = new Point3D[4];
            for (int i = 0; i < pts1.GetLength(0); i++)
            {
                int jj = pts1.GetLength(0) - 1;
                if (cs.Elevation >= 0)
                {
                    if (cs.Azimuth >= -90 && cs.Azimuth <= 90)
                    {
                        jj = 0;
                    }
                }
                else if (cs.Elevation < 0)
                {
                    jj = 0;
                    if (cs.Azimuth >= -90 && cs.Azimuth <= 90)
                    {
                        jj = pts1.GetLength(0) - 1;
                    }
                }

                if (i < pts1.GetLength(0) - 1)
                {
                    pta[0] = new Point3D(pts1[i, jj].X, pts1[i, jj].Y, pts1[i, jj].Z);
                    pta[1] = new Point3D(pts1[i + 1, jj].X, pts1[i + 1, jj].Y, pts1[i + 1, jj].Z);
                    pta[2] = new Point3D(pts1[i + 1, jj].X, pts1[i + 1, jj].Y, cs.Zmin);
                    pta[3] = new Point3D(pts1[i, jj].X, pts1[i, jj].Y, cs.Zmin);
                    for (int k = 0; k < 4; k++)
                    {
                        pta[k] = cs.Normalize3D(m, pta[k]);
                    }
                    plg                 = new Polygon();
                    plg.Stroke          = Brushes.Black;
                    plg.StrokeThickness = ds.LineThickness;
                    plg.Fill            = Brushes.White;
                    plg.Points.Add(new Point(pta[0].X, pta[0].Y));
                    plg.Points.Add(new Point(pta[1].X, pta[1].Y));
                    plg.Points.Add(new Point(pta[2].X, pta[2].Y));
                    plg.Points.Add(new Point(pta[3].X, pta[3].Y));
                    if (!IsHiddenLine)
                    {
                        plg.Fill = Brushes.Transparent;
                    }
                    if (IsColormap)
                    {
                        plg.Stroke = GetBrush(pts1[i, jj].Z, zmin, zmax);
                    }
                    cs.ChartCanvas.Children.Add(plg);
                }
            }

            for (int j = 0; j < pts1.GetLength(1); j++)
            {
                int ii = 0;
                if (cs.Elevation >= 0)
                {
                    if (cs.Azimuth >= 0 && cs.Azimuth <= 180)
                    {
                        ii = pts1.GetLength(1) - 1;
                    }
                }
                else if (cs.Elevation < 0)
                {
                    if (cs.Azimuth >= -180 && cs.Azimuth <= 0)
                    {
                        ii = pts1.GetLength(1) - 1;
                    }
                }
                if (j < pts1.GetLength(1) - 1)
                {
                    pta[0] = new Point3D(pts1[ii, j].X, pts1[ii, j].Y, pts1[ii, j].Z);
                    pta[1] = new Point3D(pts1[ii, j + 1].X, pts1[ii, j + 1].Y, pts1[ii, j + 1].Z);
                    pta[2] = new Point3D(pts1[ii, j + 1].X, pts1[ii, j + 1].Y, cs.Zmin);
                    pta[3] = new Point3D(pts1[ii, j].X, pts1[ii, j].Y, cs.Zmin);
                    for (int k = 0; k < 4; k++)
                    {
                        pta[k] = cs.Normalize3D(m, pta[k]);
                    }
                    plg                 = new Polygon();
                    plg.Stroke          = Brushes.Black;
                    plg.StrokeThickness = ds.LineThickness;
                    plg.Fill            = Brushes.White;
                    plg.Points.Add(new Point(pta[0].X, pta[0].Y));
                    plg.Points.Add(new Point(pta[1].X, pta[1].Y));
                    plg.Points.Add(new Point(pta[2].X, pta[2].Y));
                    plg.Points.Add(new Point(pta[3].X, pta[3].Y));
                    if (!IsHiddenLine)
                    {
                        plg.Fill = Brushes.Transparent;
                    }
                    if (IsColormap)
                    {
                        plg.Stroke = GetBrush(pts1[ii, j].Z, zmin, zmax);
                    }
                    cs.ChartCanvas.Children.Add(plg);
                }
            }

            if (cs.IsColorBar && IsColormap)
            {
                AddColorBar(cs, ds, zmin, zmax);
            }
        }
        private void AddContour3D(ChartStyle cs, DataSeriesSurface ds)
        {
            Point3D[] pta = new Point3D[2];
            Point3D[,] pts = ds.PointArray;
            Matrix3D        m     = Utility.AzimuthElevation(cs.Elevation, cs.Azimuth);
            SolidColorBrush brush = Brushes.Black;

            // Find the minumum and maximum z values:
            double zmin = ds.ZDataMin();
            double zmax = ds.ZDataMax();

            double[] zlevels = new Double[NumberContours];
            for (int i = 0; i < NumberContours; i++)
            {
                zlevels[i] = zmin + i * (zmax - zmin) / (NumberContours - 1);
            }

            int    i0, i1, i2, j0, j1, j2;
            double zratio = 1;

            // Draw contour on the XY plane:
            for (int i = 0; i < pts.GetLength(0) - 1; i++)
            {
                for (int j = 0; j < pts.GetLength(1) - 1; j++)
                {
                    if (IsColormap && ChartType != ChartTypeEnum.FillContour)
                    {
                        brush = GetBrush(pts[i, j].Z, zmin, zmax);
                    }
                    for (int k = 0; k < numberContours; k++)
                    {
                        // Left triangle:
                        i0 = i;
                        j0 = j;
                        i1 = i;
                        j1 = j + 1;
                        i2 = i + 1;
                        j2 = j + 1;
                        if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k] <
                             pts[i1, j1].Z || zlevels[k] < pts[i0, j0].Z &&
                             zlevels[k] >= pts[i1, j1].Z) &&
                            (zlevels[k] >= pts[i1, j1].Z && zlevels[k]
                             < pts[i2, j2].Z || zlevels[k] < pts[i1, j1].Z &&
                             zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i1, j1].Z - pts[i0, j0].Z);
                            pta[0] = new Point3D(pts[i0, j0].X, (1 - zratio) * pts[i0, j0].Y + zratio * pts[i1, j1].Y, cs.Zmin);
                            zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z);
                            pta[1] = new Point3D((1 - zratio) * pts[i1, j1].X + zratio * pts[i2, j2].X, pts[i1, j1].Y, cs.Zmin);
                            pta[0] = cs.Normalize3D(m, pta[0]);
                            pta[1] = cs.Normalize3D(m, pta[1]);
                            DrawLine3D(cs, ds, brush, new Point(pta[0].X, pta[0].Y), new Point(pta[1].X, pta[1].Y));
                        }
                        else if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k]
                                  < pts[i2, j2].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i2, j2].Z) &&
                                 (zlevels[k] >= pts[i1, j1].Z && zlevels[k]
                                  < pts[i2, j2].Z || zlevels[k] < pts[i1, j1].Z &&
                                  zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) / (pts[i2, j2].Z - pts[i0, j0].Z);
                            pta[0] = new Point3D((1 - zratio) * pts[i0, j0].X + zratio * pts[i2, j2].X, (1 - zratio) * pts[i0, j0].Y +
                                                 zratio * pts[i2, j2].Y, cs.Zmin);
                            zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z);
                            pta[1] = new Point3D((1 - zratio) * pts[i1, j1].X + zratio * pts[i2, j2].X, pts[i1, j1].Y, cs.Zmin);
                            pta[0] = cs.Normalize3D(m, pta[0]);
                            pta[1] = cs.Normalize3D(m, pta[1]);
                            DrawLine3D(cs, ds, brush, new Point(pta[0].X, pta[0].Y), new Point(pta[1].X, pta[1].Y));
                        }
                        else if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k]
                                  < pts[i1, j1].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i1, j1].Z) &&
                                 (zlevels[k] >= pts[i0, j0].Z && zlevels[k]
                                  < pts[i2, j2].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i1, j1].Z - pts[i0, j0].Z);
                            pta[0] = new Point3D(pts[i0, j0].X, (1 - zratio) * pts[i0, j0].Y + zratio * pts[i1, j1].Y, cs.Zmin);
                            zratio = (zlevels[k] - pts[i0, j0].Z) / (pts[i2, j2].Z - pts[i0, j0].Z);
                            pta[1] = new Point3D(pts[i0, j0].X * (1 - zratio) + pts[i2, j2].X * zratio,
                                                 pts[i0, j0].Y * (1 - zratio) + pts[i2, j2].Y * zratio, cs.Zmin);
                            pta[0] = cs.Normalize3D(m, pta[0]);
                            pta[1] = cs.Normalize3D(m, pta[1]);
                            DrawLine3D(cs, ds, brush, new Point(pta[0].X, pta[0].Y), new Point(pta[1].X, pta[1].Y));
                        }

                        // right triangle:
                        i0 = i;
                        j0 = j;
                        i1 = i + 1;
                        j1 = j;
                        i2 = i + 1;
                        j2 = j + 1;
                        if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k] <
                             pts[i1, j1].Z || zlevels[k] < pts[i0, j0].Z &&
                             zlevels[k] >= pts[i1, j1].Z) &&
                            (zlevels[k] >= pts[i1, j1].Z && zlevels[k]
                             < pts[i2, j2].Z || zlevels[k] < pts[i1, j1].Z &&
                             zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i1, j1].Z - pts[i0, j0].Z);
                            pta[0] = new Point3D(pts[i0, j0].X * (1 - zratio) + pts[i1, j1].X * zratio, pts[i0, j0].Y, cs.Zmin);
                            zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z);
                            pta[1] = new Point3D(pts[i1, j1].X, pts[i1, j1].Y * (1 - zratio) + pts[i2, j2].Y * zratio, cs.Zmin);
                            pta[0] = cs.Normalize3D(m, pta[0]);
                            pta[1] = cs.Normalize3D(m, pta[1]);
                            DrawLine3D(cs, ds, brush, new Point(pta[0].X, pta[0].Y), new Point(pta[1].X, pta[1].Y));
                        }
                        else if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k]
                                  < pts[i2, j2].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i2, j2].Z) &&
                                 (zlevels[k] >= pts[i1, j1].Z && zlevels[k] <
                                  pts[i2, j2].Z || zlevels[k] < pts[i1, j1].Z &&
                                  zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) /
                                     (pts[i2, j2].Z - pts[i0, j0].Z);
                            pta[0] = new Point3D(pts[i0, j0].X * (1 - zratio) + pts[i2, j2].X * zratio,
                                                 pts[i0, j0].Y * (1 - zratio) + pts[i2, j2].Y * zratio, cs.Zmin);
                            zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z);
                            pta[1] = new Point3D(pts[i1, j1].X, pts[i1, j1].Y * (1 - zratio) + pts[i2, j2].Y * zratio, cs.Zmin);
                            pta[0] = cs.Normalize3D(m, pta[0]);
                            pta[1] = cs.Normalize3D(m, pta[1]);
                            DrawLine3D(cs, ds, brush, new Point(pta[0].X, pta[0].Y), new Point(pta[1].X, pta[1].Y));
                        }
                        else if ((zlevels[k] >= pts[i0, j0].Z && zlevels[k]
                                  < pts[i1, j1].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i1, j1].Z) &&
                                 (zlevels[k] >= pts[i0, j0].Z && zlevels[k] <
                                  pts[i2, j2].Z || zlevels[k] < pts[i0, j0].Z &&
                                  zlevels[k] >= pts[i2, j2].Z))
                        {
                            zratio = (zlevels[k] - pts[i0, j0].Z) / (pts[i1, j1].Z - pts[i0, j0].Z);
                            pta[0] = new Point3D(pts[i0, j0].X * (1 - zratio) + pts[i1, j1].X * zratio, pts[i0, j0].Y, cs.Zmin);
                            zratio = (zlevels[k] - pts[i0, j0].Z) / (pts[i2, j2].Z - pts[i0, j0].Z);
                            pta[1] = new Point3D(pts[i0, j0].X * (1 - zratio) + pts[i2, j2].X * zratio,
                                                 pts[i0, j0].Y * (1 - zratio) + pts[i2, j2].Y * zratio, cs.Zmin);
                            pta[0] = cs.Normalize3D(m, pta[0]);
                            pta[1] = cs.Normalize3D(m, pta[1]);
                            DrawLine3D(cs, ds, brush, new Point(pta[0].X, pta[0].Y), new Point(pta[1].X, pta[1].Y));
                        }
                    }
                }
            }
        }
        public void AddSurface(ChartStyle cs, DataSeriesSurface ds)
        {
            Matrix3D m   = Utility.AzimuthElevation(cs.Elevation, cs.Azimuth);
            Polygon  plg = new Polygon();

            Point3D[,] pts  = ds.PointArray;
            Point3D[,] pts1 = new Point3D[pts.GetLength(0), pts.GetLength(1)];
            //double[,] zValues = new double[pts.GetLength(0), pts.GetLength(1)];
            double zmin = ds.ZDataMin();
            double zmax = ds.ZDataMax();

            for (int i = 0; i < pts.GetLength(0); i++)
            {
                for (int j = 0; j < pts.GetLength(1); j++)
                {
                    //zValues[i, j] = pts[i, j].Z;
                    pts1[i, j] = pts[i, j];
                    pts[i, j]  = cs.Normalize3D(m, pts[i, j]);
                }
            }

            // Draw surface chart:
            if (!IsInterp)
            {
                for (int i = 0; i < pts.GetLength(0) - 1; i++)
                {
                    int ii = i;
                    if (cs.Elevation >= 0)
                    {
                        ii = i;
                        if (cs.Azimuth >= -180 && cs.Azimuth < 0)
                        {
                            ii = pts.GetLength(0) - 2 - i;
                        }
                    }
                    else
                    {
                        ii = pts.GetLength(0) - 2 - i;
                        if (cs.Azimuth >= -180 && cs.Azimuth < 0)
                        {
                            ii = i;
                        }
                    }
                    for (int j = 0; j < pts.GetLength(1) - 1; j++)
                    {
                        int jj = j;
                        if (cs.Elevation < 0)
                        {
                            jj = pts.GetLength(1) - 2 - j;
                        }
                        plg = new Polygon();
                        plg.Points.Add(new Point(pts[ii, jj].X, pts[ii, jj].Y));
                        plg.Points.Add(new Point(pts[ii, jj + 1].X, pts[ii, jj + 1].Y));
                        plg.Points.Add(new Point(pts[ii + 1, jj + 1].X, pts[ii + 1, jj + 1].Y));
                        plg.Points.Add(new Point(pts[ii + 1, jj].X, pts[ii + 1, jj].Y));

                        plg.StrokeThickness = ds.LineThickness;
                        plg.Stroke          = ds.LineColor;
                        plg.Fill            = GetBrush(pts1[ii, jj].Z, zmin, zmax);
                        cs.ChartCanvas.Children.Add(plg);
                    }
                }
                if (cs.IsColorBar && IsColormap)
                {
                    AddColorBar(cs, ds, zmin, zmax);
                }
            }
            else if (IsInterp)
            {
                for (int i = 0; i < pts.GetLength(0) - 1; i++)
                {
                    int ii = i;
                    if (cs.Elevation >= 0)
                    {
                        ii = i;
                        if (cs.Azimuth >= -180 && cs.Azimuth < 0)
                        {
                            ii = pts.GetLength(0) - 2 - i;
                        }
                    }
                    else
                    {
                        ii = pts.GetLength(0) - 2 - i;
                        if (cs.Azimuth >= -180 && cs.Azimuth < 0)
                        {
                            ii = i;
                        }
                    }
                    for (int j = 0; j < pts.GetLength(1) - 1; j++)
                    {
                        int jj = j;
                        if (cs.Elevation < 0)
                        {
                            jj = pts.GetLength(1) - 2 - j;
                        }

                        Point3D[] points = new Point3D[4];
                        points[0] = pts1[ii, j];
                        points[1] = pts1[ii, j + 1];
                        points[2] = pts1[ii + 1, j + 1];
                        points[3] = pts1[ii + 1, j];
                        Interp(cs, m, points, zmin, zmax);
                        plg        = new Polygon();
                        plg.Stroke = ds.LineColor;
                        plg.Points.Add(new Point(pts[ii, j].X, pts[ii, j].Y));
                        plg.Points.Add(new Point(pts[ii, j + 1].X, pts[ii, j + 1].Y));
                        plg.Points.Add(new Point(pts[ii + 1, j + 1].X, pts[ii + 1, j + 1].Y));
                        plg.Points.Add(new Point(pts[ii + 1, j].X, pts[ii + 1, j].Y));
                        cs.ChartCanvas.Children.Add(plg);
                    }
                }
            }
            if (cs.IsColorBar && IsColormap)
            {
                AddColorBar(cs, ds, zmin, zmax);
            }
        }
        private void AddBar3D(ChartStyle2D cs, Bar3DStyle bs)
        {
            Matrix3D m = Utility.AzimuthElevation(cs.Elevation, cs.Azimuth);

            Point[] pta = new Point[4];
            Point3D[,] pts = bs.PointArray;

            // Find the minumum and maximum z values:
            double zmin = bs.ZDataMin();
            double zmax = bs.ZDataMax();

            // Check parameters:
            double xlength = bs.XLength;

            if (xlength <= 0)
            {
                xlength = 0.1 * bs.XSpacing;
            }
            else if (xlength > 0.5)
            {
                xlength = 0.5 * bs.XSpacing;
            }
            else
            {
                xlength = bs.XLength * bs.XSpacing;
            }
            double ylength = bs.YLength;

            if (ylength <= 0)
            {
                ylength = 0.1 * bs.YSpacing;
            }
            else if (ylength > 0.5)
            {
                ylength = 0.5 * bs.YSpacing;
            }
            else
            {
                ylength = bs.YLength * bs.YSpacing;
            }
            double zorigin = bs.ZOrigin;

            // Draw 3D bars:
            for (int i = 0; i < pts.GetLength(0) - 1; i++)
            {
                for (int j = 0; j < pts.GetLength(1) - 1; j++)
                {
                    int ii = i;
                    int jj = j;
                    if (cs.Azimuth >= -180 && cs.Azimuth < -90)
                    {
                        ii = pts.GetLength(0) - 2 - i;
                        jj = j;
                    }
                    else if (cs.Azimuth >= -90 && cs.Azimuth < 0)
                    {
                        ii = pts.GetLength(0) - 2 - i;
                        jj = pts.GetLength(1) - 2 - j;
                    }
                    else if (cs.Azimuth >= 0 && cs.Azimuth < 90)
                    {
                        ii = i;
                        jj = pts.GetLength(1) - 2 - j;
                    }
                    else if (cs.Azimuth >= 90 && cs.Azimuth <= 180)
                    {
                        ii = i;
                        jj = j;
                    }
                    DrawBar(cs, bs, m, pts[ii, jj], xlength, ylength, zorigin, zmax, zmin);
                }
            }
            if (cs.IsColorBar && IsColormap)
            {
                AddColorBar(cs, bs, zmin, zmax);
            }
        }