public CRMatrix Compose(CRMatrix b) { var result = new CRMatrix(); for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { result.Data[i, j] = Data[i, 0] * b.Data[0, j] + Data[i, 1] * b.Data[1, j] + Data[i, 2] * b.Data[2, j] + Data[i, 3] * b.Data[3, j]; } return result; }
public CRMatrix Compose(CRMatrix b) { var result = new CRMatrix(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { result.Data[i, j] = Data[i, 0] * b.Data[0, j] + Data[i, 1] * b.Data[1, j] + Data[i, 2] * b.Data[2, j] + Data[i, 3] * b.Data[3, j]; } } return(result); }
private void plotCurve(int channel, int p1, int p2, int p3, int p4) { // construct the geometry matrix from the segment var geometry = new CRMatrix(); for (int i = 0; i < 4; i++) { geometry.Data[i, 2] = 0; geometry.Data[i, 3] = 0; } for (int i = 0; i < 2; i++) { geometry.Data[0, i] = Points[channel, p1, i]; geometry.Data[1, i] = Points[channel, p2, i]; geometry.Data[2, i] = Points[channel, p3, i]; geometry.Data[3, i] = Points[channel, p4, i]; } // subdivide the curve 1000 times // n can be adjusted to give a finer or coarser curve float d = 1.0f / 1000; float d2 = d * d; float d3 = d * d * d; // construct a temporary matrix for determining the forward differencing deltas var tmp2 = new CRMatrix(); tmp2.Data[0, 3] = 1; tmp2.Data[1, 0] = d3; tmp2.Data[1, 1] = d2; tmp2.Data[1, 2] = d; tmp2.Data[2, 0] = 6 * d3; tmp2.Data[2, 1] = 2 * d2; tmp2.Data[3, 0] = 6 * d3; var basis = new CRMatrix(new float[, ] { { -0.5f, 1.5f, -1.5f, 0.5f }, { 1.0f, -2.5f, 2.0f, -0.5f }, { -0.5f, 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f } }); // compose the basis and geometry matrices var tmp1 = basis.Compose(geometry); // compose the above results to get the deltas matrix var deltas = tmp2.Compose(tmp1); // extract the x deltas float x = deltas.Data[0, 0]; float dx = deltas.Data[1, 0]; float dx2 = deltas.Data[2, 0]; float dx3 = deltas.Data[3, 0]; // extract the y deltas float y = deltas.Data[0, 1]; float dy = deltas.Data[1, 1]; float dy2 = deltas.Data[2, 1]; float dy3 = deltas.Data[3, 1]; int lastx = Math.Max(0, Math.Min(255, (int)Math.Round(x))); int lasty = Math.Max(0, Math.Min(255, (int)Math.Round(y))); Data[channel, lastx] = lasty; // loop over the curve for (int i = 0; i < 1000; i++) { // increment the x values x += dx; dx += dx2; dx2 += dx3; // increment the y values y += dy; dy += dy2; dy2 += dy3; int newx = Math.Max(0, Math.Min(255, (int)Math.Round(x))); int newy = Math.Max(0, Math.Min(255, (int)Math.Round(y))); // if this point is different than the last one...then draw it if ((lastx != newx) || (lasty != newy)) { Data[channel, newx] = newy; } lastx = newx; lasty = newy; } }
private void plotCurve(int channel, int p1, int p2, int p3, int p4) { // construct the geometry matrix from the segment var geometry = new CRMatrix(); for (int i = 0; i < 4; i++) { geometry.Data[i, 2] = 0; geometry.Data[i, 3] = 0; } for (int i = 0; i < 2; i++) { geometry.Data[0, i] = Points[channel, p1, i]; geometry.Data[1, i] = Points[channel, p2, i]; geometry.Data[2, i] = Points[channel, p3, i]; geometry.Data[3, i] = Points[channel, p4, i]; } // subdivide the curve 1000 times // n can be adjusted to give a finer or coarser curve float d = 1.0f / 1000; float d2 = d * d; float d3 = d * d * d; // construct a temporary matrix for determining the forward differencing deltas var tmp2 = new CRMatrix(); tmp2.Data[0, 3] = 1; tmp2.Data[1, 0] = d3; tmp2.Data[1, 1] = d2; tmp2.Data[1, 2] = d; tmp2.Data[2, 0] = 6 * d3; tmp2.Data[2, 1] = 2 * d2; tmp2.Data[3, 0] = 6 * d3; var basis = new CRMatrix(new float[,] { { -0.5f, 1.5f, -1.5f, 0.5f }, { 1.0f, -2.5f, 2.0f, -0.5f }, { -0.5f, 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f } }); // compose the basis and geometry matrices var tmp1 = basis.Compose(geometry); // compose the above results to get the deltas matrix var deltas = tmp2.Compose(tmp1); // extract the x deltas float x = deltas.Data[0, 0]; float dx = deltas.Data[1, 0]; float dx2 = deltas.Data[2, 0]; float dx3 = deltas.Data[3, 0]; // extract the y deltas float y = deltas.Data[0, 1]; float dy = deltas.Data[1, 1]; float dy2 = deltas.Data[2, 1]; float dy3 = deltas.Data[3, 1]; int lastx = Math.Max(0, Math.Min(255, (int)Math.Round(x))); int lasty = Math.Max(0, Math.Min(255, (int)Math.Round(y))); Data[channel, lastx] = lasty; // loop over the curve for (int i = 0; i < 1000; i++) { // increment the x values x += dx; dx += dx2; dx2 += dx3; // increment the y values y += dy; dy += dy2; dy2 += dy3; int newx = Math.Max(0, Math.Min(255, (int)Math.Round(x))); int newy = Math.Max(0, Math.Min(255, (int)Math.Round(y))); // if this point is different than the last one...then draw it if ((lastx != newx) || (lasty != newy)) { Data[channel, newx] = newy; } lastx = newx; lasty = newy; } }