-
Notifications
You must be signed in to change notification settings - Fork 9
/
Line.cs
116 lines (107 loc) · 3.07 KB
/
Line.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using System;
using System.Numerics;
namespace BiArcTutorial
{
/// <summary>
/// Defines a line in point-slope form: y - y1 = m * (x - x1)
/// Vertical line: m = NaN
/// Horizontal line: m = 0
/// </summary>
public struct Line
{
/// <summary>
/// Slope
/// </summary>
public readonly float m;
/// <summary>
/// Point
/// </summary>
public readonly Vector2 P;
/// <summary>
/// Define a line by two points
/// </summary>
/// <param name="P1"></param>
/// <param name="P2"></param>
public Line(Vector2 P1, Vector2 P2) : this(P1, Slope(P1, P2))
{
}
/// <summary>
/// Define a line by a point and slope
/// </summary>
/// <param name="P"></param>
/// <param name="m"></param>
public Line(Vector2 P, float m)
{
this.P = P;
this.m = m;
}
/// <summary>
/// Calculate the intersection point of this line and another one
/// </summary>
/// <param name="l"></param>
/// <returns></returns>
public Vector2 Intersection(Line l)
{
if(float.IsNaN(this.m))
{
return VerticalIntersection(this, l);
}
else if(float.IsNaN(l.m))
{
return VerticalIntersection(l, this);
}
else
{
var x = (this.m * this.P.X - l.m * l.P.X - this.P.Y + l.P.Y) / (this.m - l.m);
var y = m * x - m * P.X + P.Y;
return new Vector2(x, y);
}
}
/// <summary>
/// Special case, the first one is vertical (we suppose that the other one is not,
/// otherwise they do not cross)
/// </summary>
/// <param name="hl"></param>
/// <param name="l"></param>
/// <returns></returns>
private static Vector2 VerticalIntersection(Line vl, Line l)
{
var x = vl.P.X;
var y = l.m * (x - l.P.X) + l.P.Y;
return new Vector2(x, y);
}
/// <summary>
/// Creates a a line which is perpendicular to the line defined by P and P1 and goes through P
/// </summary>
/// <param name="P"></param>
/// <param name="P1"></param>
/// <returns></returns>
public static Line CreatePerpendicularAt(Vector2 P, Vector2 P1)
{
var m = Slope(P, P1);
if (m == 0)
{
return new Line(P, float.NaN);
}
else if(float.IsNaN(m))
{
return new Line(P, 0);
}
else
{
return new Line(P, -1f / m);
}
}
private static float Slope(Vector2 P1, Vector2 P2)
{
if(P2.X == P1.X)
{
return float.NaN;
}
else
{
return (P2.Y - P1.Y) / (P2.X - P1.X);
}
}
}
}