using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace bbiwarg.Utility { public enum LineSide { onLine = 0, above = 1, below = 2 } class Line2D { public Vector2D P1 { get; private set; } public Vector2D P2 { get; private set; } public Vector2D Direction { get; private set; } public float Length { get { return P1.getDistanceTo(P2); }} public Line2D(Vector2D p1, Vector2D p2) { setPoints(p1, p2); } private void setPoints(Vector2D p1, Vector2D p2) { //endpoints P1 = p1; P2 = p2; //direction Direction = (P1 - P2).normalize(); } public float getAngleBetween(Line2D line) { float angle = Direction.getAngleBetween(line.Direction); return Math.Min(angle, 180 - angle); } public float getParallelDistanceTo(Line2D line) { if (onSide(line.P1) != onSide(line.P2)) return 0; Vector2D a1 = projectToLine(line.P1); Vector2D a2 = projectToLine(line.P2); float distanceA1 = a1.getDistanceTo(line.P1); float distanceA2 = a2.getDistanceTo(line.P2); return Math.Min(distanceA1, distanceA2); } public float getVerticalDistanceTo(Line2D line) { Vector2D a1 = projectToLine(line.P1); Vector2D a2 = projectToLine(line.P2); if (P1.isInBox(a1, a2) || P2.isInBox(a1, a2)) return 0; float distanceP1A1 = P1.getDistanceTo(a1); float distanceP1A2 = P1.getDistanceTo(a2); float distanceP2A1 = P2.getDistanceTo(a1); float distanceP2A2 = P2.getDistanceTo(a2); return Math.Min(Math.Min(distanceP1A1, distanceP1A2), Math.Min(distanceP2A1, distanceP2A2)); } public LineSide onSide(Vector2D point) { float yPerX = Direction.Y / Direction.X; float xDiff = point.X - P1.X; float newY = P1.Y + yPerX * xDiff; if (newY < point.Y) return LineSide.above; else if (newY > point.Y) return LineSide.below; else return LineSide.onLine; } public Vector2D projectToLine(Vector2D point) { float px = point.X, py = point.Y, dx = Direction.X, dy = Direction.Y, ox = P1.X, oy = P1.Y; float diffx = px - ox; float diffy = py - oy; float diff_d = (diffx * dx + diffy * dy); float d_d = (dx * dx + dy * dy); float q = diff_d / d_d; float newX = ox + q * dx; float newY = oy + q * dy; return new Vector2D(newX, newY); } public Vector2D intersection(Line2D line) { Vector2D p = P1; Vector2D r = P2 - P1; Vector2D q = line.P1; Vector2D s = line.P2 - line.P1; float r_cross_s = r.cross(s); float q_p_cross_s = (q - p).cross(s); if (r_cross_s == 0.0) return null; float t = q_p_cross_s / r_cross_s; return p + t * r; } public override string ToString() { return (int)P1.X + "|" + (int)P1.Y + " --- " + (int)P2.X + "|" + (int)P2.Y; } } }