Skip to content

Commit

Permalink
represent lines in point-slope way to be able to handle vertical lines
Browse files Browse the repository at this point in the history
  • Loading branch information
domoszlai committed Oct 27, 2016
1 parent 76ae029 commit 92310fe
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 30 deletions.
8 changes: 4 additions & 4 deletions BiArc.cs
Expand Up @@ -28,15 +28,15 @@ public BiArc(Vector2 P1, Vector2 T1, Vector2 P2, Vector2 T2, Vector2 T)
var cw = sum < 0;

// Calculate perpendicular lines to the tangent at P1 and P2
var tl1 = new Line(P1, 1f / -(T1.Y / T1.X));
var tl2 = new Line(P2, 1f / -(T2.Y / T2.X));
var tl1 = Line.CreatePerpendicularAt(P1, P1 + T1);
var tl2 = Line.CreatePerpendicularAt(P2, P2 + T2);

// Calculate the perpendicular bisector of P1T and P2T
var P1T2 = (P1 + T) / 2;
var pbP1T = new Line(P1T2, 1f / -Line.Slope(P1, T));
var pbP1T = Line.CreatePerpendicularAt(P1T2, T);

var P2T2 = (P2 + T) / 2;
var pbP2T = new Line(P2T2, 1f / -Line.Slope(P2, T));
var pbP2T = Line.CreatePerpendicularAt(P2T2, T);

// The origo of the circles are at the intersection points
var C1 = tl1.Intersection(pbP1T);
Expand Down
9 changes: 9 additions & 0 deletions Form.cs
Expand Up @@ -34,6 +34,15 @@ public static PointF AsPointF(Vector2 v)
CubicBezier b4 = new CubicBezier(
new Vector2(100, 500), new Vector2(350, 100), new Vector2(100, 200), new Vector2(500, 400));

// Corner case 1
CubicBezier bt1 = new CubicBezier(
new Vector2(233.89831f, 285.0169000000001f), new Vector2(233.89831f, 293.0169000000001f),
new Vector2(230.5649766666668f, 301.0169000000001f), new Vector2(223.89831f, 309.0169000000001f));

// Corner case 2
CubicBezier bt2 = new CubicBezier(
new Vector2(204.89831f, 328.0169f), new Vector2(198.89831f ,334.0169f),
new Vector2(191.2316433333334f, 337.0169f), new Vector2(181.89831f, 337.0169f));

protected override void OnPaint(PaintEventArgs e)
{
Expand Down
56 changes: 30 additions & 26 deletions Line.cs
Expand Up @@ -4,7 +4,7 @@
namespace BiArcTutorial
{
/// <summary>
/// Defines a line with the equation y = m*x + b
/// Defines a line in point-slope form: y - y1 = m * (x - x1)
/// </summary>
public struct Line
{
Expand All @@ -13,9 +13,9 @@ public struct Line
/// </summary>
public readonly float m;
/// <summary>
/// Y-intercept
/// Point
/// </summary>
public readonly float b;
public readonly Vector2 P;

/// <summary>
/// Define a line by two points
Expand All @@ -31,19 +31,10 @@ public Line(Vector2 P1, Vector2 P2) : this(P1, Slope(P1, P2))
/// </summary>
/// <param name="P"></param>
/// <param name="m"></param>
public Line(Vector2 P, float m) : this(m, P.Y - m * P.X)
{
}

/// <summary>
/// Define a line by slope and y-intercept
/// </summary>
/// <param name="m"></param>
/// <param name="b"></param>
public Line(float m, float b)
public Line(Vector2 P, float m)
{
this.P = P;
this.m = m;
this.b = b;
}

/// <summary>
Expand All @@ -53,28 +44,41 @@ public Line(float m, float b)
/// <returns></returns>
public Vector2 Intersection(Line l)
{
var x = (this.b - l.b) / (l.m - this.m);
var y = m * x + b;
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);
}

public double Angle
/// <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)
{
get
var m = Slope(P, P1);

if (m == 0)
{
var a = Math.Atan(m);
return a < 0 ? a + Math.PI : a;
return new Line(P, 0);
}
else
{
return new Line(P, -1f / m);
}
}

public float y(float x)
{
return m * x + b;
}

public static float Slope(Vector2 P1, Vector2 P2)
{
return (P2.Y - P1.Y) / (P2.X - P1.X);
if(P2.X == P1.X)
{
return 0;
}
else
{
return (P2.Y - P1.Y) / (P2.X - P1.X);
}
}
}
}

0 comments on commit 92310fe

Please sign in to comment.