private void RenderFunction() { int w = this.imageBuffer.Width - 2; int h = this.imageBuffer.Height - 2; int cx = this.imageBuffer.Width / 2; int cy = this.imageBuffer.Height / 2; double[, ,] points = new double[h, w, 4]; RawExpression efx = this.function.Simplify(); var edfdx = efx.Different("x").Simplify(); var edfdy = efx.Different("y").Simplify(); var fx = efx.ToCode(); var dfdx = edfdx.ToCode(); var dfdy = edfdy.ToCode(); UpdateMessage("Computing..."); gpu.FillPoints(this.imageBuffer.Width, this.imageBuffer.Height, this.unitPixels, this.originX, this.originY, fx, dfdx, dfdy, points); //int done = 0; //int max = w + h; //int total = Environment.ProcessorCount * 8; //Parallel.For(0, total, (i) => //{ // int dh = (h + total - h % total) / total; // int dw = (w + total - w % total) / total; // int starty = 1 + i * dh; // int endy = Math.Min(h + 1, starty + dh); // int startx = 1 + i * dw; // int endx = Math.Min(w + 1, startx + dw); // int loops = (endy - starty + 1) + (endx - startx + 1); // for (int y = starty; y < endy; y++) // { // double py = this.originY + (double)(y - cy) / this.unitPixels; // RawExpression efx = this.function.Apply("y", py).Simplify(); // RawExpression edfx = efx.Different("x").Simplify(); // Func<double, double> fx = efx.Compile("x"); // Func<double, double> dfx = edfx.Compile("x"); // for (int x = 1; x <= w; x++) // { // points[y - 1, x - 1, 0] = fx.Solve(dfx, points[y - 1, x - 1, 0]); // } // int current = Interlocked.Increment(ref done); // if (current % 10 == 0) // { // UpdateMessage(current.ToString() + "/" + max.ToString()); // } // } // for (int x = startx; x < endx; x++) // { // double px = this.originX + (double)(cx - x) / this.unitPixels; // RawExpression efy = this.function.Apply("x", px).Simplify(); // RawExpression edfy = efy.Different("y").Simplify(); // Func<double, double> fy = efy.Compile("y"); // Func<double, double> dfy = edfy.Compile("y"); // for (int y = 1; y <= h; y++) // { // points[y - 1, x - 1, 3] = fy.Solve(dfy, points[y - 1, x - 1, 3]); // } // int current = Interlocked.Increment(ref done); // if (current % 10 == 0) // { // UpdateMessage(current.ToString() + "/" + max.ToString()); // } // } //}); UpdateMessage("Rendering..."); BitmapData data = this.imageBuffer.LockBits(new Rectangle(0, 0, this.imageBuffer.Width, this.imageBuffer.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); for (int y = 1; y <= h; y++) { for (int x = 1; x <= w; x++) { double x1 = points[y - 1, x - 1, 0]; double y1 = points[y - 1, x - 1, 1]; double x2 = points[y - 1, x - 1, 2]; double y2 = points[y - 1, x - 1, 3]; if (!double.IsInfinity(x1) && !double.IsNaN(x1)) { Fill(data, x1, y1, cx, cy, w, h); } if (!double.IsInfinity(y2) && !double.IsNaN(y2)) { Fill(data, x2, y2, cx, cy, w, h); } } } this.imageBuffer.UnlockBits(data); UpdateMessage("(Ready)"); }
public string ToCode(RawExpression expression) { return(expression.ToCode()); }
static void Main(string[] args) { { string e = "(k1 *Cs1 + k2 * Co2) / (k1 * C1 + k2 * C2)"; { RawExpression exp = RawExpression.Parse(e); RawExpression dk1 = exp.Different("k1").Simplify(); RawExpression dk2 = exp.Different("k2").Simplify(); Console.WriteLine("input:\t\t" + e); Console.WriteLine("parse:\t\t" + exp.ToCode()); Console.WriteLine("dk1:\t\t" + dk1.ToCode()); Console.WriteLine("dk2:\t\t" + dk2.ToCode()); } // cs1 = 128, Co2 = 1024, C1 = 256, C2 = 2048 Dictionary <string, double> values = new Dictionary <string, double> { { "Cs1", 128 }, { "Co2", 1024 }, { "C1", 256 }, { "C2", 2048 }, }; foreach (var p in values) { Console.WriteLine("{0} => {1}", p.Value, p.Key); } { RawExpression exp = RawExpression.Parse(e).Apply(values).Simplify(); RawExpression dk1 = exp.Different("k1").Simplify(); RawExpression dk2 = exp.Different("k2").Simplify(); Console.WriteLine("applied:\t" + exp.ToCode()); Console.WriteLine("dk1:\t\t" + dk1.ToCode()); Console.WriteLine("dk2:\t\t" + dk2.ToCode()); } } { string[] expressions = { "1", "1.2", "-3", "12+34", "56*78", "x^y", "x+2*y+4", "(x+y)*(3+4)", "exp(x+y)", "x+ln(y)", "x/y", "exp(x)/ln(x)", "sin(x)", "cos(x)", "tan(x)", "cot(x)", "sec(x)", "csc(x)", }; foreach (var e in expressions) { RawExpression exp = RawExpression.Parse(e); Console.WriteLine("input:\t\t" + e); Console.WriteLine("parse:\t\t" + exp.ToCode()); Console.WriteLine("simplified:\t" + exp.Simplify().ToCode()); Console.WriteLine("dx:\t\t" + exp.Different("x").Simplify().ToCode()); Console.WriteLine("dy:\t\t" + exp.Different("y").Simplify().ToCode()); Console.WriteLine("no x:\t\t" + exp.Apply("x", 0).Simplify().ToCode()); Console.WriteLine("no y:\t\t" + exp.Apply("y", 0).Simplify().ToCode()); Console.WriteLine(); Debug.Assert(exp.ToCode() == RawExpression.Parse(exp.ToCode()).ToCode()); } } { string[] expressions = { "(x-3)*(x-5)", "ln(x)/ln(2)-3", "(x-5)^2-4", }; foreach (var e in expressions) { RawExpression exp = RawExpression.Parse(e); Console.WriteLine("input:\t\t" + e); Console.WriteLine("parse:\t\t" + exp.ToCode()); for (int i = 0; i < 10; i++) { Console.WriteLine("solve:\t\t" + i.ToString() + " => " + exp.Solve("x", i).ToString()); } Console.WriteLine(); } } }