private void Interp(Graphics g, ChartStyle cs, ChartStyle2D cs2d, Matrix3 m, Point3[] pta, float zmin, float zmax, int flag, Axes ax, ViewAngle va, ChartLabels cl) { SolidBrush aBrush = new SolidBrush(Color.Black); PointF[] points = new PointF[4]; int npoints = NumberInterp; Point3[,] pts = new Point3[npoints + 1, npoints + 1]; Point3[,] pts1 = new Point3[npoints + 1, npoints + 1]; float x0 = pta[0].X; float y0 = pta[0].Y; float x1 = pta[2].X; float y1 = pta[2].Y; float dx = (x1 - x0) / npoints; float dy = (y1 - y0) / npoints; float C00 = pta[0].Z; float C10 = pta[3].Z; float C11 = pta[2].Z; float C01 = pta[1].Z; float x, y, C; Color color; if (flag == 1) // For Surface chart { for (int i = 0; i <= npoints; i++) { x = x0 + i * dx; for (int j = 0; j <= npoints; j++) { y = y0 + j * dy; C = (y1 - y) * ((x1 - x) * C00 + (x - x0) * C10) / (x1 - x0) / (y1 - y0) + (y - y0) * ((x1 - x) * C01 + (x - x0) * C11) / (x1 - x0) / (y1 - y0); pts[i, j] = new Point3(x, y, C, 1); pts[i, j].Transform(m, chart3d, ax, cs, cl); } } for (int i = 0; i < npoints; i++) { for (int j = 0; j < npoints; j++) { color = AddColor(cs, pts[i, j], zmin, zmax, ax, va, cl); aBrush = new SolidBrush(color); points[0] = new PointF(pts[i, j].X, pts[i, j].Y); points[1] = new PointF(pts[i + 1, j].X, pts[i + 1, j].Y); points[2] = new PointF(pts[i + 1, j + 1].X, pts[i + 1, j + 1].Y); points[3] = new PointF(pts[i, j + 1].X, pts[i, j + 1].Y); g.FillPolygon(aBrush, points); aBrush.Dispose(); } } } else if (flag == 2) // For XYColor chart { for (int i = 0; i <= npoints; i++) { x = x0 + i * dx; for (int j = 0; j <= npoints; j++) { y = y0 + j * dy; C = (y1 - y) * ((x1 - x) * C00 + (x - x0) * C10) / (x1 - x0) / (y1 - y0) + (y - y0) * ((x1 - x) * C01 + (x - x0) * C11) / (x1 - x0) / (y1 - y0); pts[i, j] = new Point3(x, y, C, 1); } } for (int i = 0; i < npoints; i++) { for (int j = 0; j < npoints; j++) { color = AddColor(cs, pts[i, j], zmin, zmax, ax, va, cl); aBrush = new SolidBrush(color); points[0] = cs2d.Point2D(new PointF(pts[i, j].X, pts[i, j].Y), ax); points[1] = cs2d.Point2D(new PointF(pts[i + 1, j].X, pts[i + 1, j].Y), ax); points[2] = cs2d.Point2D(new PointF(pts[i + 1, j + 1].X, pts[i + 1, j + 1].Y), ax); points[3] = cs2d.Point2D(new PointF(pts[i, j + 1].X, pts[i, j + 1].Y), ax); g.FillPolygon(aBrush, points); aBrush.Dispose(); } } } else if (flag == 3) // For XYColor3D chart { for (int i = 0; i <= npoints; i++) { x = x0 + i * dx; for (int j = 0; j <= npoints; j++) { y = y0 + j * dy; C = (y1 - y) * ((x1 - x) * C00 + (x - x0) * C10) / (x1 - x0) / (y1 - y0) + (y - y0) * ((x1 - x) * C01 + (x - x0) * C11) / (x1 - x0) / (y1 - y0); pts1[i, j] = new Point3(x, y, C, 1); pts[i, j] = new Point3(x, y, ax.ZMin, 1); pts[i, j].Transform(m, chart3d, ax, cs, cl); } } for (int i = 0; i < npoints; i++) { for (int j = 0; j < npoints; j++) { color = AddColor(cs, pts1[i, j], zmin, zmax, ax, va, cl); aBrush = new SolidBrush(color); points[0] = new PointF(pts[i, j].X, pts[i, j].Y); points[1] = new PointF(pts[i + 1, j].X, pts[i + 1, j].Y); points[2] = new PointF(pts[i + 1, j + 1].X, pts[i + 1, j + 1].Y); points[3] = new PointF(pts[i, j + 1].X, pts[i, j + 1].Y); g.FillPolygon(aBrush, points); aBrush.Dispose(); } } } }
private void AddContour(Graphics g, DataSeries ds, ChartStyle cs, ChartStyle2D cs2d, Axes ax, ViewAngle va, ChartLabels cl) { Pen aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.Thickness); aPen.DashStyle = ds.LineStyle.Pattern; SolidBrush aBrush = new SolidBrush(Color.White); PointF[] pta = new PointF[2]; Point3[,] pts = ds.PointArray; Matrix3 m = new Matrix3(); // Find the minumum and maximum z values: float zmin = ds.ZDataMin(); float zmax = ds.ZDataMax(); float[] zlevels = new float[numberContours]; for (int i = 0; i < numberContours; i++) { zlevels[i] = zmin + i * (zmax - zmin) / (numberContours - 1); } int i0, i1, i2, j0, j1, j2; float 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 && ChartType != ChartTypeEnum.SurfaceFillContour) { Color color = AddColor(cs, pts[i, j], zmin, zmax, ax, va, cl); aPen = new Pen(color, ds.LineStyle.Thickness); aPen.DashStyle = ds.LineStyle.Pattern; } 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.Point2D(new PointF(pts[i0, j0].X, (1 - zratio) * pts[i0, j0].Y + zratio * pts[i1, j1].Y), ax); zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z); pta[1] = cs2d.Point2D(new PointF((1 - zratio) * pts[i1, j1].X + zratio * pts[i2, j2].X, pts[i1, j1].Y), ax); g.DrawLine(aPen, 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.Point2D(new PointF((1 - zratio) * pts[i0, j0].X + zratio * pts[i2, j2].X, (1 - zratio) * pts[i0, j0].Y + zratio * pts[i2, j2].Y), ax); zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z); pta[1] = cs2d.Point2D(new PointF((1 - zratio) * pts[i1, j1].X + zratio * pts[i2, j2].X, pts[i1, j1].Y), ax); g.DrawLine(aPen, 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.Point2D(new PointF(pts[i0, j0].X, (1 - zratio) * pts[i0, j0].Y + zratio * pts[i1, j1].Y), ax); zratio = (zlevels[k] - pts[i0, j0].Z) / (pts[i2, j2].Z - pts[i0, j0].Z); pta[1] = cs2d.Point2D(new PointF(pts[i0, j0].X * (1 - zratio) + pts[i2, j2].X * zratio, pts[i0, j0].Y * (1 - zratio) + pts[i2, j2].Y * zratio), ax); g.DrawLine(aPen, 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.Point2D(new PointF(pts[i0, j0].X * (1 - zratio) + pts[i1, j1].X * zratio, pts[i0, j0].Y), ax); zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z); pta[1] = cs2d.Point2D(new PointF(pts[i1, j1].X, pts[i1, j1].Y * (1 - zratio) + pts[i2, j2].Y * zratio), ax); g.DrawLine(aPen, 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.Point2D(new PointF(pts[i0, j0].X * (1 - zratio) + pts[i2, j2].X * zratio, pts[i0, j0].Y * (1 - zratio) + pts[i2, j2].Y * zratio), ax); zratio = (zlevels[k] - pts[i1, j1].Z) / (pts[i2, j2].Z - pts[i1, j1].Z); pta[1] = cs2d.Point2D(new PointF(pts[i1, j1].X, pts[i1, j1].Y * (1 - zratio) + pts[i2, j2].Y * zratio), ax); g.DrawLine(aPen, 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.Point2D(new PointF(pts[i0, j0].X * (1 - zratio) + pts[i1, j1].X * zratio, pts[i0, j0].Y), ax); zratio = (zlevels[k] - pts[i0, j0].Z) / (pts[i2, j2].Z - pts[i0, j0].Z); pta[1] = cs2d.Point2D(new PointF(pts[i0, j0].X * (1 - zratio) + pts[i2, j2].X * zratio, pts[i0, j0].Y * (1 - zratio) + pts[i2, j2].Y * zratio), ax); g.DrawLine(aPen, pta[0], pta[1]); } } } } }
private void AddXYColor(Graphics g, DataSeries ds, ChartStyle cs, ChartStyle2D cs2d, Axes ax, ViewAngle va, ChartLabels cl) { Pen aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.Thickness); aPen.DashStyle = ds.LineStyle.Pattern; SolidBrush aBrush = new SolidBrush(Color.White); PointF[] pta = new PointF[4]; Point3[,] pts = ds.PointArray; Matrix3 m = new Matrix3(); // Find the minumum and maximum z values: float zmin = ds.ZDataMin(); float 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++) { pta[0] = cs2d.Point2D(new PointF(pts[i, j].X, pts[i, j].Y), ax); pta[1] = cs2d.Point2D(new PointF(pts[i, j + 1].X, pts[i, j + 1].Y), ax); pta[2] = cs2d.Point2D(new PointF(pts[i + 1, j + 1].X, pts[i + 1, j + 1].Y), ax); pta[3] = cs2d.Point2D(new PointF(pts[i + 1, j].X, pts[i + 1, j].Y), ax); Color color = AddColor(cs, pts[i, j], zmin, zmax, ax, va, cl); aBrush = new SolidBrush(color); g.FillPolygon(aBrush, pta); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pta); } } } } // Draw refined surface: else if (IsInterp) { for (int i = 0; i < pts.GetLength(0) - 1; i++) { for (int j = 0; j < pts.GetLength(1) - 1; j++) { Point3[] points = new Point3[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]; Interp(g, cs, cs2d, m, points, zmin, zmax, 2, ax, va, cl); pta[0] = cs2d.Point2D(new PointF(pts[i, j].X, pts[i, j].Y), ax); pta[1] = cs2d.Point2D(new PointF(pts[i, j + 1].X, pts[i, j + 1].Y), ax); pta[2] = cs2d.Point2D(new PointF(pts[i + 1, j + 1].X, pts[i + 1, j + 1].Y), ax); pta[3] = cs2d.Point2D(new PointF(pts[i + 1, j].X, pts[i + 1, j].Y), ax); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pta); } } } } }