| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- 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;
- }
- }
- }
|