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); }
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); }
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); } } } }
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); }
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); }
private void AddAdjacentNeighbours(Point3D[,] edgesPoints, List <AdjacentPoints>[] adjacentPoints) { for (int i = 0; i < edgesPoints.GetLength(0); ++i) { AddEdgeNeighbours(edgesPoints, i, adjacentPoints[i]); } }
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]); }
///<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); }
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); }
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); }
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); } } }
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); }
///<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]); } } } } }
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); }
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); } }