unsafe private void UpdatePointVertical(int py, int jstart, int xstart, int xend) { int stride = mesh.Stride / sizeof(DisplacementVector); CosineInterpolator top = new CosineInterpolator(); CosineInterpolator bot = new CosineInterpolator(); for (int i = 0; i < handlesx; ++i) { top.Add((i + points[i, jstart].X) * xspacing, points[i, jstart].Y * yspacing); bot.Add((i + points[i, jstart].X) * xspacing, points[i, jstart].Y * yspacing); } for (int j = py - 1; j < py + 1; ++j) { if (j >= -1 && j < height) { bot = new CosineInterpolator(); for (int i = 0; i < handlesx; ++i) { bot.Add((i + points[i, j + 1].X) * xspacing, points[i, j + 1].Y * yspacing); } } float jtoytop = j * yspacing; float jtoybot = (j + 1) * yspacing; for (int x = xstart; x < xend; ++x) { float topval = -(float)(top.Interpolate(x)), bottomval = -(float)(bot.Interpolate(x)); int y1 = (int)(jtoytop - topval); int y2 = (int)(jtoybot - bottomval) + 1; float ydif = y2 - y1; if (y1 < 0) { y1 = 0; } if (y2 > mesh.Height) { y2 = mesh.Height; } DisplacementVector *ptr = mesh.GetPointAddressUnchecked(x, y1); for (int y = y1; y < y2; ++y) { float lerp = (y - y1) / ydif, val = lerp * bottomval + (1 - lerp) * topval; ptr->Y = val; ptr += stride; } } top = bot; } }
void canvas_CanvasPaint(object sender, PaintEventArgs e) { if (grid != null && gridvisible) { float xspacing = canvas.ZoomFactor * (EnvironmentParameters.SourceSurface.Width - 1) / (float)grid.Width; float yspacing = canvas.ZoomFactor * (EnvironmentParameters.SourceSurface.Height - 1) / (float)grid.Height; float handleradius = 3; e.Graphics.SmoothingMode = SmoothingMode.HighQuality; IInterpolator si = null; //draw horizontal guidelines for (int j = 0; j <= grid.Height; ++j) { if (linearInterpolationBtn.Checked) { si = new LinearInterpolator(); } else { si = new CosineInterpolator(); } for (int i = 0; i <= grid.Width; ++i) { si.Add(i + grid.GetPoint(i, j).X, j + grid.GetPoint(i, j).Y); } int linestart = Math.Max( e.ClipRectangle.Left, (int)(grid.GetPoint(0, j).X *xspacing)); int lineend = Math.Min( e.ClipRectangle.Right + 1, (int)((grid.Width + grid.GetPoint(grid.Width, j).X) * xspacing)); int len = lineend - linestart; if (len > 1) { PointF[] line = new PointF[len]; for (int x = linestart; x < lineend; ++x) { line[x - linestart] = new PointF(x, (float)(si.Interpolate(x / xspacing) * yspacing + 1)); } e.Graphics.DrawLines(gridPen, line); } } //vertical guidelines for (int i = 0; i <= grid.Width; ++i) { if (linearInterpolationBtn.Checked) { si = new LinearInterpolator(); } else { si = new CosineInterpolator(); } for (int j = 0; j <= grid.Height; ++j) { si.Add(j + grid.GetPoint(i, j).Y, i + grid.GetPoint(i, j).X); } int linestart = Math.Max( e.ClipRectangle.Top, (int)(grid.GetPoint(i, 0).Y *yspacing)); int lineend = Math.Min( e.ClipRectangle.Bottom + 1, (int)((grid.Height + grid.GetPoint(i, grid.Height).Y) * yspacing)); int len = lineend - linestart; if (len > 1) { PointF[] line = new PointF[len]; for (int y = linestart; y < lineend; ++y) { line[y - linestart] = new PointF((float)(si.Interpolate(y / yspacing) * xspacing + 1), y); } e.Graphics.DrawLines(gridPen, line); } } //draw control handles and check if the mouse is hovering over one while we're at it hovering = tracking; for (int j = 0; j <= grid.Height; ++j) { for (int i = 0; i <= grid.Width; ++i) { PointF point = new PointF( (i + grid.GetPoint(i, j).X) * xspacing + 1, (j + grid.GetPoint(i, j).Y) * yspacing + 1); RectangleF dotdrawrect = new RectangleF(point.X - handleradius, point.Y - handleradius, 2 * handleradius, 2 * handleradius); RectangleF hitrect = RectangleF.Inflate(dotdrawrect, 5, 5); if ((tracking.X == i && tracking.Y == j) || (tracking.X == -1 && hitrect.Contains(mouselocation.X * canvas.ZoomFactor, mouselocation.Y * canvas.ZoomFactor))) { e.Graphics.FillEllipse(Brushes.Black, RectangleF.Inflate(dotdrawrect, 1, 1)); e.Graphics.FillEllipse(Brushes.White, RectangleF.Inflate(dotdrawrect, -1, -1)); hovering = new Point(i, j); } else { e.Graphics.FillEllipse(Brushes.Black, dotdrawrect); } } } } }
unsafe private void UpdatePointHorizontal(int px, int istart, int ystart, int yend) { CosineInterpolator left = new CosineInterpolator(); CosineInterpolator right = new CosineInterpolator(); for (int j = 0; j < handlesy; ++j) { left.Add((j + points[istart, j].Y) * yspacing, points[istart, j].X * xspacing); right.Add((j + points[istart, j].Y) * yspacing, points[istart, j].X * xspacing); } for (int i = px - 1; i < px + 1; ++i) { if (i >= -1 && i < width) { right = new CosineInterpolator(); for (int j = 0; j < handlesy; ++j) { right.Add((j + points[i + 1, j].Y) * yspacing, points[i + 1, j].X * xspacing); } } float itoxleft = i * xspacing; float itoxright = (i + 1) * xspacing; for (int y = ystart; y < yend; ++y) { float leftval = -(float)(left.Interpolate(y)), rightval = -(float)(right.Interpolate(y)); int x1 = (int)(itoxleft - leftval); int x2 = (int)(itoxright - rightval) + 1; float xdif = x2 - x1; if (x1 < 0) { x1 = 0; } if (x2 > mesh.Width) { x2 = mesh.Width; } DisplacementVector *ptr = mesh.GetPointAddressUnchecked(x1, y); for (int x = x1; x < x2; ++x) { float lerp = (x - x1) / xdif, val = lerp * rightval + (1 - lerp) * leftval; ptr->X = val; ++ptr; } } left = right; } }