/MathUtils/Graphic/MGraphic.cs

https://github.com/THROYAN/MagicLibrary
C# | 272 lines | 239 code | 29 blank | 4 comment | 8 complexity | d4bc8c7d343dd4a1bcdb3c13e3fa84ec MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Drawing;
  6. using MagicLibrary.MathUtils;
  7. namespace MagicLibrary.Graphic
  8. {
  9. public static class MGraphic
  10. {
  11. public static Matrix R(double angle)
  12. {
  13. double a = angle * Math.PI / 180;
  14. Matrix mR = new Matrix(new double[3, 3] {
  15. {Math.Cos(a),-Math.Sin(a),0},
  16. {Math.Sin(a),Math.Cos(a),0},
  17. {0,0,1}
  18. });
  19. return mR;
  20. }
  21. public static Matrix R(double angle, PointF p)
  22. {
  23. return T(p) * R(angle) * T(-p.X, -p.Y);
  24. }
  25. public static Matrix S(double sx, double sy)
  26. {
  27. Matrix mS = new Matrix(new double[3, 3]{
  28. {sx,0,0},
  29. {0,sy,0},
  30. {0,0,1}
  31. });
  32. return mS;
  33. }
  34. public static Matrix T(PointF d)
  35. {
  36. Matrix mT = new Matrix(new double[3, 3]{
  37. {1,0,d.X},
  38. {0,1,d.Y},
  39. {0,0,1}
  40. });
  41. return mT;
  42. }
  43. public static Matrix T(float X,float Y)
  44. {
  45. return T(new PointF(X, Y));
  46. }
  47. public static Matrix Pr(PointF O)
  48. {
  49. Matrix mPr = new Matrix(new double[3, 3]{
  50. {1,0,0},
  51. {0,1,0},
  52. {-1/O.X,-1/O.Y,1}
  53. });
  54. return mPr;
  55. }
  56. public static PointF Rotation(PointF P, double angle)
  57. {
  58. double a = angle * Math.PI / 180;
  59. Matrix mP = new Matrix(new double[2, 1]{
  60. {P.X},
  61. {P.Y}
  62. });
  63. Matrix mR = new Matrix(new double[2, 2] {
  64. {Math.Cos(a),-Math.Sin(a)},
  65. {Math.Sin(a),Math.Cos(a)}
  66. });
  67. Matrix res = mR * mP;
  68. return res.ToPointF();
  69. }
  70. public static PointF Transpanation(PointF P, PointF d)
  71. {
  72. Matrix mP = new Matrix(new double[3, 1]{
  73. {P.X},
  74. {P.Y},
  75. {1}
  76. });
  77. Matrix mT = new Matrix(new double[3, 3]{
  78. {1,0,d.X},
  79. {0,1,d.Y},
  80. {0,0,1}
  81. });
  82. Matrix res = mT * mP;
  83. return res.ToPointF();
  84. }
  85. public static PointF Scale(PointF P, double sx, double sy)
  86. {
  87. Matrix mP = new Matrix(new double[2, 1]{
  88. {P.X},
  89. {P.Y}
  90. });
  91. Matrix mS = new Matrix(new double[2, 2]{
  92. {sx,0},
  93. {0,sy}
  94. });
  95. Matrix res = mS * mP;
  96. return res.ToPointF();
  97. }
  98. public static PointF Proekciya(PointF P, PointF O)
  99. {
  100. Matrix mP = new Matrix(new double[3, 1]{
  101. {P.X},
  102. {P.Y},
  103. {1}
  104. });
  105. Matrix mPr = new Matrix(new double[3, 3]{
  106. {1,0,0},
  107. {0,1,0},
  108. {1/O.X,1/O.Y,1}
  109. });
  110. Matrix res = mPr * mP;
  111. return res.ToPointF();
  112. }
  113. public static PointF Projection(PointF P, double a, double b)
  114. {
  115. return Proekciya(P, new PointF((float)a,(float)b));
  116. }
  117. public static PointF Transpanation(PointF P, double dx, double dy)
  118. {
  119. return Transpanation(P, new PointF((float)dx, (float)dy));
  120. }
  121. public static PointF UseMixedTransformation(PointF P, Matrix m)
  122. {
  123. return m * P;
  124. }
  125. public static PointF UseMixedTransformation(float X, float Y, Matrix m)
  126. {
  127. return m * (new PointF(X, Y));
  128. }
  129. public static PointF[] UseMixedTransformations(PointF[] Ps, Matrix m)
  130. {
  131. PointF[] nPs = new PointF[Ps.Length];
  132. for (int i = 0; i < Ps.Length; i++)
  133. nPs[i] = UseMixedTransformation(Ps[i], m);
  134. return nPs;
  135. }
  136. private static PointF[] SplineFunctionOo(PointF[] points, double t)
  137. {
  138. PointF[] result = new PointF[points.Length - 1];
  139. for (int i = 0; i < points.Length - 1; i++)
  140. {
  141. result[i] = new PointF(
  142. (1 - (float)t) * points[i].X + (float)t * points[i + 1].X,
  143. (1 - (float)t) * points[i].Y + (float)t * points[i + 1].Y
  144. );
  145. }
  146. return result;
  147. }
  148. private static PointF SplinePoint(PointF[] points, double t)
  149. {
  150. PointF[] p = new PointF[points.Length];
  151. points.CopyTo(p, 0);
  152. while (p.Length > 1)
  153. {
  154. p = SplineFunctionOo(p, t);
  155. }
  156. return p[0];
  157. }
  158. private static PointF[] SplinePoints(PointF[] points, double eps)
  159. {
  160. List<PointF> ps = new List<PointF>();
  161. for (double t = 0; t <= 1; t += eps)
  162. {
  163. ps.Add(SplinePoint(points, t));
  164. }
  165. return ps.ToArray();
  166. }
  167. public static void DrawSpline(Graphics g, Pen p, PointF[] points, double eps = 0.001)
  168. {
  169. g.DrawLines(p, SplinePoints(points,eps));
  170. }
  171. public static void DrawSpline(Graphics g, Pen p, PointF[] points, Matrix m, double eps = 0.001)
  172. {
  173. DrawSpline(g, p, m * points, eps);
  174. }
  175. private static PointF[][] PointsForEllipse(float x, float y, float width, float height)
  176. {
  177. return new PointF[][]{
  178. new PointF[]{
  179. new PointF(x,y + height/2), // _
  180. new PointF(x,y+height/4),
  181. //new PointF(x,y), // /
  182. new PointF(x +width/4,y),
  183. new PointF(x + width/2,y),
  184. },
  185. new PointF[]{
  186. new PointF(x + width/2,y), // _
  187. new PointF(x+3*width/4,y),
  188. //new PointF(x+w,y), // \
  189. new PointF(x + width, y+height/4),
  190. new PointF(x+width,y+height/2),
  191. },
  192. new PointF[]{
  193. new PointF(x+width,y+height/2),
  194. new PointF(x+width,y+3*height/4),
  195. //new PointF(x+w,y+h),// _/
  196. new PointF(x+3 * width / 4,y + height),
  197. new PointF(x+width/2,y+height),
  198. },
  199. new PointF[]{
  200. new PointF(x+width/2,y+height),
  201. new PointF(x+width/4,y+height),
  202. //new PointF(x,y+h), // \_
  203. new PointF(x,y+3*height/4),
  204. new PointF(x,y+height/2),
  205. },
  206. };
  207. }
  208. public static void DrawEllipse(Graphics g, Pen p, float x, float y, float width, float height, Matrix m = null, double eps = 0.001)
  209. {
  210. if (m == null)
  211. {
  212. PointsForEllipse(x, y, width, height).ToList().ForEach(pt => MGraphic.DrawSpline(g, p, pt, eps));
  213. }
  214. else
  215. PointsForEllipse(x, y, width, height).ToList().ForEach(pt => MGraphic.DrawSpline(g, p, m * pt, eps));
  216. }
  217. public static void DrawEllipse(Graphics g, Pen p, PointF pt, SizeF s, Matrix m = null, double eps = 0.001)
  218. {
  219. DrawEllipse(g, p, pt.X, pt.Y, s.Width, s.Height, m, eps);
  220. }
  221. public static void DrawEllipse(Graphics g, Pen p, RectangleF r, Matrix m = null, double eps = 0.001)
  222. {
  223. DrawEllipse(g,p,r.X,r.Y,r.Width,r.Height,m,eps);
  224. }
  225. public static void DrawFillEllipse(Graphics g, Brush b, float x, float y, float width, float height, Matrix m = null, double eps = 0.001)
  226. {
  227. List<PointF> ps = new List<PointF>();
  228. if (m == null)
  229. PointsForEllipse(x, y, width, height).ToList().ForEach(p => ps.AddRange(SplinePoints(p, eps)));
  230. else
  231. PointsForEllipse(x, y, width, height).ToList().ForEach(p => ps.AddRange(SplinePoints(m * p, eps)));
  232. g.FillClosedCurve(b, ps.ToArray());
  233. }
  234. public static void DrawFillEllipse(Graphics g, Brush b, PointF pt, SizeF s, Matrix m = null, double eps = 0.001)
  235. {
  236. DrawFillEllipse(g, b, pt.X, pt.Y, s.Width, s.Height, m, eps);
  237. }
  238. public static void DrawFillEllipse(Graphics g, Brush b, RectangleF r, Matrix m = null, double eps = 0.001)
  239. {
  240. DrawFillEllipse(g, b, r.X, r.Y, r.Width, r.Height, m, eps);
  241. }
  242. }
  243. }