Advertisement
Guest User

Untitled

a guest
Nov 18th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.42 KB | None | 0 0
  1. public partial class Function2D : Form
  2. {
  3. Graphics g;
  4. Bitmap b;
  5. Rectangle r;
  6. BL.Function2D func;
  7. float tRange1 = -5;
  8. float tRange2 = 5;
  9. double tStep = 0.05;
  10. bool isPressed = false;
  11. float fMouseX;
  12. float fMouseY;
  13.  
  14. public Function2D()
  15. {
  16. InitializeComponent();
  17. r = new Rectangle(0,0,pictureBox1.Width, pictureBox1.Height);
  18. b = new Bitmap(r.Width,r.Height);
  19. g = Graphics.FromImage(b);
  20.  
  21.  
  22. tRange1 = float.Parse(tRangeTextBox.Text.Split(';')[0]);
  23. tRange2 = float.Parse(tRangeTextBox.Text.Split(';')[1]);
  24. tStep = Convert.ToDouble(tStepTextBox.Text);
  25.  
  26. func = new BL.Function2D(xFunctionTextBox.Text, yFunctionTextBox.Text, tRange1, tRange2);
  27. func.fOffsetX = -pictureBox1.Width / 2;
  28. func.fOffsetY = -pictureBox1.Height / 2;
  29.  
  30. pictureBox1.MouseWheel += new MouseEventHandler(MouseWheelScale);
  31. pictureBox1.MouseMove += new MouseEventHandler(MouseMoves);
  32. pictureBox1.MouseDown += new MouseEventHandler(p1MouseDown);
  33. pictureBox1.MouseUp += new MouseEventHandler(p1MouseUp);
  34. }
  35. private void p1MouseDown(object sender, MouseEventArgs e)
  36. {
  37. fMouseX = e.X;
  38. fMouseY = e.Y;
  39.  
  40. func.fStartPanX = fMouseX;
  41. func.fStartPanY = fMouseY;
  42. isPressed = true;
  43. }
  44.  
  45. private void p1MouseUp(object sender, MouseEventArgs e)
  46. {
  47. isPressed = false;
  48. }
  49.  
  50. private void MouseMoves(object sender, MouseEventArgs e)
  51. {
  52. if (isPressed)
  53. {
  54. func.fStartPanX = fMouseX;
  55. func.fStartPanY = fMouseY;
  56. func.Span(e.X, e.Y);
  57. Draw(g, r);
  58. }
  59. }
  60.  
  61. private void MouseWheelScale(object sender, MouseEventArgs e)
  62. {
  63. func.Scale(e.Delta, e.X, e.Y);
  64. Draw(g,r);
  65. }
  66.  
  67. private void DrawGraphicButton_Click(object sender, EventArgs e)
  68. {
  69. Draw(g, r);
  70. }
  71.  
  72. private void Draw(Graphics g, Rectangle r)
  73. {
  74. b = new Bitmap(r.Width, r.Height);
  75. func.Draw(b, Color.Black);
  76. pictureBox1.Image = b;
  77. }
  78.  
  79. private void button1_Click(object sender, EventArgs e)
  80. {
  81. func = new BL.Function2D(xFunctionTextBox.Text, yFunctionTextBox.Text, tRange1, tRange2);
  82. func.fOffsetX = -pictureBox1.Width / 2;
  83. func.fOffsetY = -pictureBox1.Height / 2;
  84. }
  85. }
  86.  
  87.  
  88.  
  89.  
  90. ----------------------------------------------------------
  91.  
  92.  
  93. public class Function2D
  94. {
  95. public List<PointF> Points { get; set; } = new List<PointF>();
  96. List<PointF> transformedPoints;
  97. public string FormulaX { get; private set; }
  98. public string FormulaY { get; private set; }
  99. private float tMin;
  100. private float tMax;
  101.  
  102. public float fOffsetX { get; set; } = 0.0f;
  103. public float fOffsetY { get; set; } = 0.0f;
  104. public float fScaleX { get; set; }
  105. public float fScaleY { get; set; }
  106.  
  107. public float fStartPanX { get; set; } = 0.0f;
  108. public float fStartPanY { get; set; } = 0.0f;
  109.  
  110. public void Span(int fMouseX, float fMouseY)
  111. {
  112. fOffsetX -= ((float)(fMouseX) - fStartPanX) / fScaleX;
  113. fOffsetY -= ((float)(fMouseY) - fStartPanY) / fScaleY;
  114.  
  115. fStartPanX = fMouseX;
  116. fStartPanY = fMouseY;
  117. }
  118.  
  119. public void Scale(int delta, float fMouseX, float fMouseY)
  120. {
  121. float fMouseWorldX_BeforeZoom = 0;
  122. float fMouseWorldY_BeforeZoom = 0;
  123. ScreenToWorld(fMouseX, fMouseY, ref fMouseWorldX_BeforeZoom, ref fMouseWorldY_BeforeZoom);
  124. if (delta > 0)
  125. {
  126. fScaleX *= 1.1f;
  127. fScaleY *= 1.1f;
  128. }
  129. else if (delta < 0)
  130. {
  131. fScaleX *= 0.9f;
  132. fScaleY *= 0.9f;
  133. }
  134. float fMouseWorldX_AfterZoom = 0;
  135. float fMouseWorldY_AfterZoom = 0;
  136. ScreenToWorld(fMouseX, fMouseY, ref fMouseWorldX_AfterZoom, ref fMouseWorldY_AfterZoom);
  137. fOffsetX += (fMouseWorldX_BeforeZoom - fMouseWorldX_AfterZoom);
  138. fOffsetY += (fMouseWorldY_BeforeZoom - fMouseWorldY_AfterZoom);
  139. }
  140.  
  141. private void ScreenToWorld(float xs, float ys, ref float xw, ref float yw)
  142. {
  143. xw = ((float)xs / fScaleX) + fOffsetX;
  144. yw = ((float)ys / fScaleY) + fOffsetY;
  145. }
  146.  
  147. private void WorldToScreen(float xw, float yw, ref float xs, ref float ys)
  148. {
  149. xs = (float)((xw - fOffsetX) * fScaleX);
  150. ys = (float)((yw - fOffsetY) * fScaleY);
  151. }
  152.  
  153. public Function2D(string formulaX, string formulaY, float tMin, float tMax)
  154. {
  155. FormulaX = formulaX;
  156. FormulaY = formulaY;
  157. fScaleX = 1.0f;
  158. fScaleY= 1.0f;
  159. this.tMin = tMin;
  160. this.tMax = tMax;
  161. ParseFunc();
  162. }
  163.  
  164. public void Draw(Bitmap b, Color color)
  165. {
  166. transformedPoints = new List<PointF>(Points.Count);
  167. for (int i = 0; i < Points.Count; i++)
  168. {
  169. float x = 0;
  170. float y = 0;
  171. WorldToScreen(Points[i].X, Points[i].Y, ref x, ref y);
  172. transformedPoints.Add(new PointF(x, y));
  173. }
  174. DrawingAlgorithms.BresenhamsLines(b, transformedPoints.ToArray(), color);
  175. }
  176.  
  177. private bool ParseFunc()
  178. {
  179. string dst;
  180. string dst2;
  181. FormulaParser parser = new FormulaParser();
  182. FormulaParser.Formula formulaX = parser.CreateFormula(FormulaX.Replace('t', 'x'), out dst);
  183. FormulaParser.Formula formulaY = parser.CreateFormula(FormulaY.Replace('t', 'x'), out dst2);
  184.  
  185. for (double i = tMin; i <= tMax; i += 0.05)
  186. {
  187. double x = formulaX(i, 0, 0) * fScaleX;
  188. double y = formulaY(i, 0, 0) * fScaleY;
  189. Points.Add(new PointF((float)x, -(float)y));
  190. }
  191.  
  192. return true;
  193. }
  194.  
  195. }
  196.  
  197. ------------------------------------------------
  198.  
  199.  
  200. public class FormulaParser
  201. {
  202. public delegate double Formula(double x, double y, double z);
  203.  
  204. public Formula CreateFormula(string InputFormula, out string dst)
  205. {
  206. string code =
  207. @"using System;
  208.  
  209. static class Code
  210. {
  211. public static double Formula(double x, double y, double z)
  212. {
  213. return {source};
  214. }
  215. }";
  216. string s = @"-?[\d.]+|\#\d+|[a-z]";
  217. string[] patterns =
  218. {
  219. $@"(?<A>sin|cos|log|exp|abs|acs|sqr)?\((?:{s})\)",
  220. $@"({s})\^({s})",
  221. $@"(?:{s})[*/](?:{s})",
  222. $@"(?:{s})[+-](?:{s})"
  223. };
  224. InputFormula = Regex.Replace(InputFormula, @"\s+", "").ToLower().Replace(',', '.');
  225. Dictionary<string, string> dic = new Dictionary<string, string>();
  226. Func<string, string> f1 = null;
  227. f1 = s1 =>
  228. {
  229. foreach (string p in patterns)
  230. {
  231. var m = Regex.Match(s1, p);
  232. if (m.Success)
  233. {
  234. string value = m.Value;
  235. if (m.Groups["A"].Success)
  236. {
  237. value = value.Replace("sin", "Math.Sin");
  238. value = value.Replace("cos", "Math.Cos");
  239. value = value.Replace("log", "Math.Log");
  240. value = value.Replace("exp", "Math.Exp");
  241. value = value.Replace("abs", "Math.Abs");
  242. value = value.Replace("acs", "Math.Acos");
  243. value = value.Replace("sqr", "Math.Sqrt");
  244. }
  245. if (m.Groups[1].Success && m.Groups[2].Success)
  246. {
  247. value = $"Math.Pow({m.Groups[1]},{m.Groups[2]})";
  248. }
  249. string key = $"#{dic.Count}";
  250. dic.Add(key, value);
  251. string ss = s1.Substring(0, m.Index) + key + s1.Substring(m.Index + m.Length);
  252. return f1(ss);
  253. }
  254. }
  255. return s1;
  256. };
  257. Func<string, string> f2 = null;
  258. f2 = s1 =>
  259. {
  260. string ss = Regex.Replace(s1, @"\#\d+", x => dic[x.Value]);
  261. return ss == s1 ? ss : f2(ss);
  262. };
  263. dst = f2(f1(InputFormula));
  264. code = code.Replace("{source}", dst);
  265. var compiler = CodeDomProvider.CreateProvider("C#");
  266. CompilerParameters parameters = new CompilerParameters();
  267. parameters.GenerateInMemory = true;
  268. var result = compiler.CompileAssemblyFromSource(parameters, code);
  269. if (result.Errors.Count == 0)
  270. {
  271. var assembly = result.CompiledAssembly;
  272. var type = assembly.GetType("Code");
  273. var method = type.GetMethod("Formula");
  274. return (Formula)Delegate.CreateDelegate(typeof(Formula), method);
  275. }
  276. return null;
  277. }
  278. }
  279.  
  280. ---------------------------------------------------------------------
  281.  
  282. public class DrawingAlgorithms
  283. {
  284. public static void DDA(Graphics g, float x1, float y1, float x2, float y2, float coeff = 20)
  285. {
  286. float dx = x2 - x1;
  287. float dy = y2 - y1;
  288. float L = Math.Max(Math.Abs(dx), Math.Abs(dy));
  289. float dx1 = dx / L;
  290. float dy1 = dy / L;
  291. float x = x1;
  292. float y = y1;
  293. for (int i = 1; i <= L + 1; i++)
  294. {
  295. g.FillRectangle(Brushes.Orange, Convert.ToInt32(x) * coeff, Convert.ToInt32(y) * coeff, coeff, coeff);
  296. x += dx1;
  297. y += dy1;
  298. }
  299. }
  300.  
  301. public static void DDA(Bitmap b, Color color, float x1, float y1, float x2, float y2)
  302. {
  303. float dx = x2 - x1;
  304. float dy = y2 - y1;
  305. float L = Math.Max(Math.Abs(dx), Math.Abs(dy));
  306. float dx1 = dx / L;
  307. float dy1 = dy / L;
  308. float x = x1;
  309. float y = y1;
  310. for (int i = 1; i <= L + 1; i++)
  311. {
  312. b.SetPixel(Convert.ToInt32(x), Convert.ToInt32(y), color);
  313. x += dx1;
  314. y += dy1;
  315. }
  316. }
  317.  
  318. public static void BresenhamsLine(Graphics g, float x1, float y1, float x2, float y2, float coeff = 0)
  319. {
  320. bool swapped = false;
  321. float dx = Math.Abs(x2 - x1); float cx = x2 > x1 ? 1 : -1;
  322. float dy = Math.Abs(y2 - y1); float cy = y2 > y1 ? 1 : -1;
  323. if (Math.Abs(dy) > Math.Abs(dx))
  324. {
  325. Swap(ref x1, ref y1);
  326. Swap(ref x2, ref y2);
  327. Swap(ref dx, ref dy);
  328. Swap(ref cx, ref cy);
  329. swapped = true;
  330. }
  331. if (cx == -1)
  332. {
  333. Swap(ref x1, ref x2);
  334. Swap(ref y1, ref y2);
  335. cy = cy == 1 ? -1 : 1;
  336. }
  337. float err = 2 * dy - dx;
  338. float xStep = 2 * dy;
  339. float yStep = 2 * dy - 2 * dx;
  340. for (; x1 <= x2; x1 += 1)
  341. {
  342. g.FillRectangle(Brushes.Black, swapped ? y1 * coeff : x1 * coeff, swapped ? x1 * coeff : y1 * coeff, coeff, coeff);
  343. if (err > 0)
  344. {
  345. y1 += cy;
  346. err += yStep;
  347. }
  348. else
  349. {
  350. err += xStep;
  351. }
  352. }
  353. }
  354. public static void BresenhamsLine(Bitmap b, Color color, float x1, float y1, float x2, float y2)
  355. {
  356. bool swapped = false;
  357. float dx = Math.Abs(x2 - x1); float cx = x2 > x1 ? 1 : -1;
  358. float dy = Math.Abs(y2 - y1); float cy = y2 > y1 ? 1 : -1;
  359. if (Math.Abs(dy) > Math.Abs(dx))
  360. {
  361. Swap(ref x1, ref y1);
  362. Swap(ref x2, ref y2);
  363. Swap(ref dx, ref dy);
  364. Swap(ref cx, ref cy);
  365. swapped = true;
  366. }
  367. if (cx == -1)
  368. {
  369. Swap(ref x1, ref x2);
  370. Swap(ref y1, ref y2);
  371. cy = cy == 1 ? -1 : 1;
  372. }
  373. float err = 2 * dy - dx;
  374. float xStep = 2 * dy;
  375. float yStep = 2 * dy - 2 * dx;
  376. for (; x1 <= x2; x1 += 1)
  377. {
  378. int t1 = (swapped ? (int)y1 : (int)x1);
  379. int t2 = (swapped ? (int)x1 : (int)y1);
  380. if (t1 < b.Width && t2 < b.Height && t1 > 0 && t2 > 0)
  381. {
  382. b.SetPixel(swapped ? (int)y1 : (int)x1, swapped ? (int)x1 : (int)y1, color);
  383. }
  384. if (err > 0)
  385. {
  386. y1 += cy;
  387. err += yStep;
  388. }
  389. else
  390. {
  391. err += xStep;
  392. }
  393. }
  394. }
  395.  
  396. public static void BresenhamsLines(Graphics g, PointF[] points, float coeff = 0)
  397. {
  398. for (int i = 0; i < points.Length - 1; i++)
  399. {
  400. BresenhamsLine(g, points[i].X, points[i].Y, points[i + 1].X, points[i + 1].Y, 1);
  401. }
  402. }
  403.  
  404. public static void BresenhamsLines(Bitmap b, PointF[] points, Color color)
  405. {
  406. for (int i = 1; i < points.Length - 1; i++)
  407. {
  408. BresenhamsLine(b, color, points[i].X, points[i].Y, points[i - 1].X, points[i - 1].Y);
  409. }
  410. }
  411.  
  412. private static void Swap<T>(ref T a, ref T b)
  413. {
  414. T temp = a;
  415. a = b;
  416. b = temp;
  417. }
  418.  
  419. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement