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 PointOnLine { get; private set; } public Vector2D Direction { get; private set; } public Line2D(Vector2D pointOnLine, Vector2D direction) { PointOnLine = pointOnLine; Direction = direction.normalize(); } public float getAngleBetween(Line2D line) { float angle = Direction.getAngleBetween(line.Direction); return Math.Min(angle, 180 - angle); } public LineSide onSide(Vector2D point) { float yPerX = Direction.Y / Direction.X; float xDiff = point.X - PointOnLine.X; float newY = PointOnLine.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 = PointOnLine.X, oy = PointOnLine.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 getIntersection(Line2D line) { Vector2D p = PointOnLine; Vector2D r = Direction; Vector2D q = line.PointOnLine; Vector2D s = line.Direction; 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; } } }