Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public partial class Function2D : Form
- {
- Graphics g;
- Bitmap b;
- Rectangle r;
- BL.Function2D func;
- float tRange1 = -5;
- float tRange2 = 5;
- double tStep = 0.05;
- bool isPressed = false;
- float fMouseX;
- float fMouseY;
- public Function2D()
- {
- InitializeComponent();
- r = new Rectangle(0,0,pictureBox1.Width, pictureBox1.Height);
- b = new Bitmap(r.Width,r.Height);
- g = Graphics.FromImage(b);
- tRange1 = float.Parse(tRangeTextBox.Text.Split(';')[0]);
- tRange2 = float.Parse(tRangeTextBox.Text.Split(';')[1]);
- tStep = Convert.ToDouble(tStepTextBox.Text);
- func = new BL.Function2D(xFunctionTextBox.Text, yFunctionTextBox.Text, tRange1, tRange2);
- func.fOffsetX = -pictureBox1.Width / 2;
- func.fOffsetY = -pictureBox1.Height / 2;
- pictureBox1.MouseWheel += new MouseEventHandler(MouseWheelScale);
- pictureBox1.MouseMove += new MouseEventHandler(MouseMoves);
- pictureBox1.MouseDown += new MouseEventHandler(p1MouseDown);
- pictureBox1.MouseUp += new MouseEventHandler(p1MouseUp);
- }
- private void p1MouseDown(object sender, MouseEventArgs e)
- {
- fMouseX = e.X;
- fMouseY = e.Y;
- func.fStartPanX = fMouseX;
- func.fStartPanY = fMouseY;
- isPressed = true;
- }
- private void p1MouseUp(object sender, MouseEventArgs e)
- {
- isPressed = false;
- }
- private void MouseMoves(object sender, MouseEventArgs e)
- {
- if (isPressed)
- {
- func.fStartPanX = fMouseX;
- func.fStartPanY = fMouseY;
- func.Span(e.X, e.Y);
- Draw(g, r);
- }
- }
- private void MouseWheelScale(object sender, MouseEventArgs e)
- {
- func.Scale(e.Delta, e.X, e.Y);
- Draw(g,r);
- }
- private void DrawGraphicButton_Click(object sender, EventArgs e)
- {
- Draw(g, r);
- }
- private void Draw(Graphics g, Rectangle r)
- {
- b = new Bitmap(r.Width, r.Height);
- func.Draw(b, Color.Black);
- pictureBox1.Image = b;
- }
- private void button1_Click(object sender, EventArgs e)
- {
- func = new BL.Function2D(xFunctionTextBox.Text, yFunctionTextBox.Text, tRange1, tRange2);
- func.fOffsetX = -pictureBox1.Width / 2;
- func.fOffsetY = -pictureBox1.Height / 2;
- }
- }
- ----------------------------------------------------------
- public class Function2D
- {
- public List<PointF> Points { get; set; } = new List<PointF>();
- List<PointF> transformedPoints;
- public string FormulaX { get; private set; }
- public string FormulaY { get; private set; }
- private float tMin;
- private float tMax;
- public float fOffsetX { get; set; } = 0.0f;
- public float fOffsetY { get; set; } = 0.0f;
- public float fScaleX { get; set; }
- public float fScaleY { get; set; }
- public float fStartPanX { get; set; } = 0.0f;
- public float fStartPanY { get; set; } = 0.0f;
- public void Span(int fMouseX, float fMouseY)
- {
- fOffsetX -= ((float)(fMouseX) - fStartPanX) / fScaleX;
- fOffsetY -= ((float)(fMouseY) - fStartPanY) / fScaleY;
- fStartPanX = fMouseX;
- fStartPanY = fMouseY;
- }
- public void Scale(int delta, float fMouseX, float fMouseY)
- {
- float fMouseWorldX_BeforeZoom = 0;
- float fMouseWorldY_BeforeZoom = 0;
- ScreenToWorld(fMouseX, fMouseY, ref fMouseWorldX_BeforeZoom, ref fMouseWorldY_BeforeZoom);
- if (delta > 0)
- {
- fScaleX *= 1.1f;
- fScaleY *= 1.1f;
- }
- else if (delta < 0)
- {
- fScaleX *= 0.9f;
- fScaleY *= 0.9f;
- }
- float fMouseWorldX_AfterZoom = 0;
- float fMouseWorldY_AfterZoom = 0;
- ScreenToWorld(fMouseX, fMouseY, ref fMouseWorldX_AfterZoom, ref fMouseWorldY_AfterZoom);
- fOffsetX += (fMouseWorldX_BeforeZoom - fMouseWorldX_AfterZoom);
- fOffsetY += (fMouseWorldY_BeforeZoom - fMouseWorldY_AfterZoom);
- }
- private void ScreenToWorld(float xs, float ys, ref float xw, ref float yw)
- {
- xw = ((float)xs / fScaleX) + fOffsetX;
- yw = ((float)ys / fScaleY) + fOffsetY;
- }
- private void WorldToScreen(float xw, float yw, ref float xs, ref float ys)
- {
- xs = (float)((xw - fOffsetX) * fScaleX);
- ys = (float)((yw - fOffsetY) * fScaleY);
- }
- public Function2D(string formulaX, string formulaY, float tMin, float tMax)
- {
- FormulaX = formulaX;
- FormulaY = formulaY;
- fScaleX = 1.0f;
- fScaleY= 1.0f;
- this.tMin = tMin;
- this.tMax = tMax;
- ParseFunc();
- }
- public void Draw(Bitmap b, Color color)
- {
- transformedPoints = new List<PointF>(Points.Count);
- for (int i = 0; i < Points.Count; i++)
- {
- float x = 0;
- float y = 0;
- WorldToScreen(Points[i].X, Points[i].Y, ref x, ref y);
- transformedPoints.Add(new PointF(x, y));
- }
- DrawingAlgorithms.BresenhamsLines(b, transformedPoints.ToArray(), color);
- }
- private bool ParseFunc()
- {
- string dst;
- string dst2;
- FormulaParser parser = new FormulaParser();
- FormulaParser.Formula formulaX = parser.CreateFormula(FormulaX.Replace('t', 'x'), out dst);
- FormulaParser.Formula formulaY = parser.CreateFormula(FormulaY.Replace('t', 'x'), out dst2);
- for (double i = tMin; i <= tMax; i += 0.05)
- {
- double x = formulaX(i, 0, 0) * fScaleX;
- double y = formulaY(i, 0, 0) * fScaleY;
- Points.Add(new PointF((float)x, -(float)y));
- }
- return true;
- }
- }
- ------------------------------------------------
- public class FormulaParser
- {
- public delegate double Formula(double x, double y, double z);
- public Formula CreateFormula(string InputFormula, out string dst)
- {
- string code =
- @"using System;
- static class Code
- {
- public static double Formula(double x, double y, double z)
- {
- return {source};
- }
- }";
- string s = @"-?[\d.]+|\#\d+|[a-z]";
- string[] patterns =
- {
- $@"(?<A>sin|cos|log|exp|abs|acs|sqr)?\((?:{s})\)",
- $@"({s})\^({s})",
- $@"(?:{s})[*/](?:{s})",
- $@"(?:{s})[+-](?:{s})"
- };
- InputFormula = Regex.Replace(InputFormula, @"\s+", "").ToLower().Replace(',', '.');
- Dictionary<string, string> dic = new Dictionary<string, string>();
- Func<string, string> f1 = null;
- f1 = s1 =>
- {
- foreach (string p in patterns)
- {
- var m = Regex.Match(s1, p);
- if (m.Success)
- {
- string value = m.Value;
- if (m.Groups["A"].Success)
- {
- value = value.Replace("sin", "Math.Sin");
- value = value.Replace("cos", "Math.Cos");
- value = value.Replace("log", "Math.Log");
- value = value.Replace("exp", "Math.Exp");
- value = value.Replace("abs", "Math.Abs");
- value = value.Replace("acs", "Math.Acos");
- value = value.Replace("sqr", "Math.Sqrt");
- }
- if (m.Groups[1].Success && m.Groups[2].Success)
- {
- value = $"Math.Pow({m.Groups[1]},{m.Groups[2]})";
- }
- string key = $"#{dic.Count}";
- dic.Add(key, value);
- string ss = s1.Substring(0, m.Index) + key + s1.Substring(m.Index + m.Length);
- return f1(ss);
- }
- }
- return s1;
- };
- Func<string, string> f2 = null;
- f2 = s1 =>
- {
- string ss = Regex.Replace(s1, @"\#\d+", x => dic[x.Value]);
- return ss == s1 ? ss : f2(ss);
- };
- dst = f2(f1(InputFormula));
- code = code.Replace("{source}", dst);
- var compiler = CodeDomProvider.CreateProvider("C#");
- CompilerParameters parameters = new CompilerParameters();
- parameters.GenerateInMemory = true;
- var result = compiler.CompileAssemblyFromSource(parameters, code);
- if (result.Errors.Count == 0)
- {
- var assembly = result.CompiledAssembly;
- var type = assembly.GetType("Code");
- var method = type.GetMethod("Formula");
- return (Formula)Delegate.CreateDelegate(typeof(Formula), method);
- }
- return null;
- }
- }
- ---------------------------------------------------------------------
- public class DrawingAlgorithms
- {
- public static void DDA(Graphics g, float x1, float y1, float x2, float y2, float coeff = 20)
- {
- float dx = x2 - x1;
- float dy = y2 - y1;
- float L = Math.Max(Math.Abs(dx), Math.Abs(dy));
- float dx1 = dx / L;
- float dy1 = dy / L;
- float x = x1;
- float y = y1;
- for (int i = 1; i <= L + 1; i++)
- {
- g.FillRectangle(Brushes.Orange, Convert.ToInt32(x) * coeff, Convert.ToInt32(y) * coeff, coeff, coeff);
- x += dx1;
- y += dy1;
- }
- }
- public static void DDA(Bitmap b, Color color, float x1, float y1, float x2, float y2)
- {
- float dx = x2 - x1;
- float dy = y2 - y1;
- float L = Math.Max(Math.Abs(dx), Math.Abs(dy));
- float dx1 = dx / L;
- float dy1 = dy / L;
- float x = x1;
- float y = y1;
- for (int i = 1; i <= L + 1; i++)
- {
- b.SetPixel(Convert.ToInt32(x), Convert.ToInt32(y), color);
- x += dx1;
- y += dy1;
- }
- }
- public static void BresenhamsLine(Graphics g, float x1, float y1, float x2, float y2, float coeff = 0)
- {
- bool swapped = false;
- float dx = Math.Abs(x2 - x1); float cx = x2 > x1 ? 1 : -1;
- float dy = Math.Abs(y2 - y1); float cy = y2 > y1 ? 1 : -1;
- if (Math.Abs(dy) > Math.Abs(dx))
- {
- Swap(ref x1, ref y1);
- Swap(ref x2, ref y2);
- Swap(ref dx, ref dy);
- Swap(ref cx, ref cy);
- swapped = true;
- }
- if (cx == -1)
- {
- Swap(ref x1, ref x2);
- Swap(ref y1, ref y2);
- cy = cy == 1 ? -1 : 1;
- }
- float err = 2 * dy - dx;
- float xStep = 2 * dy;
- float yStep = 2 * dy - 2 * dx;
- for (; x1 <= x2; x1 += 1)
- {
- g.FillRectangle(Brushes.Black, swapped ? y1 * coeff : x1 * coeff, swapped ? x1 * coeff : y1 * coeff, coeff, coeff);
- if (err > 0)
- {
- y1 += cy;
- err += yStep;
- }
- else
- {
- err += xStep;
- }
- }
- }
- public static void BresenhamsLine(Bitmap b, Color color, float x1, float y1, float x2, float y2)
- {
- bool swapped = false;
- float dx = Math.Abs(x2 - x1); float cx = x2 > x1 ? 1 : -1;
- float dy = Math.Abs(y2 - y1); float cy = y2 > y1 ? 1 : -1;
- if (Math.Abs(dy) > Math.Abs(dx))
- {
- Swap(ref x1, ref y1);
- Swap(ref x2, ref y2);
- Swap(ref dx, ref dy);
- Swap(ref cx, ref cy);
- swapped = true;
- }
- if (cx == -1)
- {
- Swap(ref x1, ref x2);
- Swap(ref y1, ref y2);
- cy = cy == 1 ? -1 : 1;
- }
- float err = 2 * dy - dx;
- float xStep = 2 * dy;
- float yStep = 2 * dy - 2 * dx;
- for (; x1 <= x2; x1 += 1)
- {
- int t1 = (swapped ? (int)y1 : (int)x1);
- int t2 = (swapped ? (int)x1 : (int)y1);
- if (t1 < b.Width && t2 < b.Height && t1 > 0 && t2 > 0)
- {
- b.SetPixel(swapped ? (int)y1 : (int)x1, swapped ? (int)x1 : (int)y1, color);
- }
- if (err > 0)
- {
- y1 += cy;
- err += yStep;
- }
- else
- {
- err += xStep;
- }
- }
- }
- public static void BresenhamsLines(Graphics g, PointF[] points, float coeff = 0)
- {
- for (int i = 0; i < points.Length - 1; i++)
- {
- BresenhamsLine(g, points[i].X, points[i].Y, points[i + 1].X, points[i + 1].Y, 1);
- }
- }
- public static void BresenhamsLines(Bitmap b, PointF[] points, Color color)
- {
- for (int i = 1; i < points.Length - 1; i++)
- {
- BresenhamsLine(b, color, points[i].X, points[i].Y, points[i - 1].X, points[i - 1].Y);
- }
- }
- private static void Swap<T>(ref T a, ref T b)
- {
- T temp = a;
- a = b;
- b = temp;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement