|
|
@@ -0,0 +1,99 @@
|
|
|
+using o0.Geometry2D.Float;
|
|
|
+using System;
|
|
|
+
|
|
|
+namespace o0.Project
|
|
|
+{
|
|
|
+ internal class o0Extension
|
|
|
+ {
|
|
|
+ public static void DrawLine(Matrix matrix, Line line, Func<int, int, float> setValue, Geometry2D.Float.Vector size = default, bool dashedLine = false)
|
|
|
+ {
|
|
|
+ if (size == default)
|
|
|
+ size = new Geometry2D.Float.Vector(0, 1);
|
|
|
+ if (size.x != 0)
|
|
|
+ {
|
|
|
+ var halfExtLength = size.x / 2;
|
|
|
+ var offset = new Geometry2D.Float.Vector(halfExtLength / line.Length * (line.B.x - line.A.x), halfExtLength / line.Length * (line.B.y - line.A.y));
|
|
|
+ line = new Geometry2D.Float.Line(line.A - offset, line.B + offset);
|
|
|
+ }
|
|
|
+
|
|
|
+ int drawCount = 0;
|
|
|
+ void _draw(int x, int y)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (dashedLine)
|
|
|
+ {
|
|
|
+ if (drawCount++ % 80 < 50)
|
|
|
+ matrix[x, y] = setValue(x, y);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ matrix[x, y] = setValue(x, y);
|
|
|
+ }
|
|
|
+ catch { }
|
|
|
+ }
|
|
|
+
|
|
|
+ var halfWidth = size.y / 2;
|
|
|
+ if (line.A.y == line.B.y)
|
|
|
+ {
|
|
|
+ var xRange = ((int)Math.Round(line.A.x), (int)Math.Round(line.B.x) + 1);
|
|
|
+ foreach (var y in ((int)Math.Round(line.A.y - halfWidth)).Range((int)Math.Round(line.A.y + halfWidth) + 1))
|
|
|
+ foreach (var x in xRange.Item1.Range(xRange.Item2))
|
|
|
+ _draw(x, y);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if (line.A.x == line.B.x)
|
|
|
+ {
|
|
|
+ var yRange = ((int)Math.Round(line.A.y), (int)Math.Round(line.B.y) + 1);
|
|
|
+ foreach (var x in ((int)Math.Round(line.A.x - halfWidth)).Range((int)Math.Round(line.A.x + halfWidth) + 1))
|
|
|
+ foreach (var y in yRange.Item1.Range(yRange.Item2))
|
|
|
+ _draw(x, y);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var upOffset = new Geometry2D.Float.Vector(halfWidth / line.Length * (line.A.y - line.B.y), halfWidth / line.Length * (line.B.x - line.A.x));
|
|
|
+ if (upOffset.y < 0)
|
|
|
+ upOffset = -upOffset;
|
|
|
+ Geometry2D.Float.Vector up, down, left, right;
|
|
|
+ if (upOffset.x < 0)//0-90度
|
|
|
+ {
|
|
|
+ up = line.B + upOffset;
|
|
|
+ down = line.A - upOffset;
|
|
|
+ left = line.A + upOffset;
|
|
|
+ right = line.B - upOffset;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ up = line.A + upOffset;
|
|
|
+ down = line.B - upOffset;
|
|
|
+ left = line.A - upOffset;
|
|
|
+ right = line.B + upOffset;
|
|
|
+ }
|
|
|
+ var topLeft = new Geometry2D.Float.Line(left, up);
|
|
|
+ var bottomLeft = new Geometry2D.Float.Line(left, down);
|
|
|
+ var topRight = new Geometry2D.Float.Line(up, right);
|
|
|
+ var bottomRight = new Geometry2D.Float.Line(down, right);
|
|
|
+
|
|
|
+ var topLeftXToYRate = topLeft.XToYRate;
|
|
|
+ var bottomLeftXToYRate = bottomLeft.XToYRate;
|
|
|
+ var topRightXToYRate = topRight.XToYRate;
|
|
|
+ var bottomRightXToYRate = bottomRight.XToYRate;
|
|
|
+ foreach (var y in ((int)Math.Round(down.y)).Range((int)Math.Round(up.y) + 1))
|
|
|
+ foreach (var x in ((int)Math.Max(topLeft.YToX(y, topLeftXToYRate), bottomLeft.YToX(y, bottomLeftXToYRate)))
|
|
|
+ .Range((int)Math.Min(topRight.YToX(y, topRightXToYRate), bottomRight.YToX(y, bottomRightXToYRate)) + 1))
|
|
|
+ _draw(x, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>计算点到直线的垂足,垂足坐标可能在Line的延长线上</summary>
|
|
|
+ public static Vector PointPedal(Line l, in Vector v)
|
|
|
+ {
|
|
|
+ Vector d = l.B - l.A;
|
|
|
+ float dotD = d.Dot(d);
|
|
|
+ if (dotD == 0)
|
|
|
+ throw new DivideByZeroException();
|
|
|
+ float dotL = (v - l.A).Dot(d);
|
|
|
+ Vector proj = d * (dotL / dotD);
|
|
|
+ return l.A + proj;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+}
|