Created
August 22, 2019 17:08
-
-
Save Cranc/4516db74ffb5114d16f470bce6db8655 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Spline_Engine.Splines | |
{ | |
class NURBS : Interfaces.SplineInterface | |
{ | |
//step size for drawing | |
private double increment = 0.01; | |
private int degree = 1; | |
public void Draw(Canvas panel, List<Vector3> points, Guid uid) | |
{ | |
DrawNURBS(points, panel, uid); | |
DrawPoints(points, panel, uid); | |
DrawHelperLine(points, panel, uid); | |
} | |
private void DrawNURBS(List<Vector3> points, Canvas panel, Guid uid) | |
{ | |
if (points.Count < 4) | |
return; | |
PointCollection draw_points = new PointCollection(); | |
List<double> knotSequenz = CalculateKnotVector(degree, points.Count); | |
List<int> weights = new List<int>(); | |
//generate weights | |
for(int i = 0; i < points.Count; i++) | |
{ | |
weights.Add(1); | |
} | |
for (double u = 0; u <= 1; u += increment) | |
{ | |
double x = 0; | |
double y = 0; | |
for (int i = 0; i < points.Count; i++) | |
{ | |
double _base = NurbsBaseEquation(u, i, degree, knotSequenz, weights); | |
x += _base * points[i].X; | |
y += _base * points[i].Y; | |
} | |
draw_points.Add(new Point(x, y)); | |
} | |
var polyLine = new Polyline(); | |
polyLine.Uid = uid.ToString(); | |
polyLine.Stroke = Brushes.Green; | |
polyLine.StrokeThickness = 2; | |
polyLine.FillRule = FillRule.EvenOdd; | |
polyLine.Points = draw_points; | |
panel.Children.Add(polyLine); | |
} | |
private List<double> CalculateKnotVector(int degree, int pointCount) | |
{ | |
int len = pointCount + degree + 1; | |
int lower = len - 1 - 2 * degree; | |
List<double> knotSequenz = new List<double>(); | |
knotSequenz.Add(0); | |
for (int i = 1; i < len; i++) | |
{ | |
if(i <= degree) | |
{ | |
knotSequenz.Add(0); | |
} else if(i >= len - degree - 1) | |
{ | |
knotSequenz.Add(1); | |
} | |
else | |
{ | |
int upper = i - degree; | |
knotSequenz.Add(upper / lower); | |
} | |
} | |
return knotSequenz; | |
} | |
private double NurbsBaseEquation(double u, int i, int n, List<double> knotSequenz, List<int> weights) | |
{ | |
double upper = RecursiveBaseEquation(u, i, n, knotSequenz) * weights[i]; | |
double lower = 0; | |
for(int j = 0; j < n; j++) | |
{ | |
lower += RecursiveBaseEquation(u, j, n, knotSequenz) * weights[j]; | |
} | |
return upper / lower; | |
} | |
private double RecursiveBaseEquation(double u, int i, int n, List<double> knotSequenz) | |
{ | |
//return 0.0; | |
if(n == 0) | |
{ | |
if(knotSequenz[i] <= u && u < knotSequenz[i + 1]) | |
{ | |
return 1.0; | |
} else | |
{ | |
return 0.0; | |
} | |
} | |
return (u - knotSequenz[i]) / (knotSequenz[i + n] - knotSequenz[i]) * RecursiveBaseEquation(u, i, n - 1, knotSequenz) + | |
(knotSequenz[i + 1 + n] - u) / (knotSequenz[i + 1 + n] - knotSequenz[i + 1]) * RecursiveBaseEquation(u, i + 1, n - 1, knotSequenz); | |
} | |
private void DrawPoints(List<Vector3> points, Canvas panel, Guid uid) | |
{ | |
foreach (var point in points) | |
{ | |
var circle = new Ellipse(); | |
circle.Uid = uid.ToString(); | |
circle.Width = 10; | |
circle.Height = 10; | |
circle.Stroke = Brushes.Orange; | |
circle.Fill = Brushes.Orange; | |
panel.Children.Add(circle); | |
double left = point.X - (10 / 2); | |
double top = point.Y - (10 / 2); | |
Canvas.SetLeft(circle, left); | |
Canvas.SetTop(circle, top); | |
} | |
} | |
private void DrawHelperLine(List<Vector3> points, Canvas panel, Guid uid) | |
{ | |
PointCollection draw_points = new PointCollection(); | |
foreach (var point in points) | |
{ | |
draw_points.Add(new Point(point.X, point.Y)); | |
} | |
var polyLine = new Polyline(); | |
polyLine.Uid = uid.ToString(); | |
polyLine.Stroke = Brushes.Orange; | |
polyLine.StrokeThickness = 1; | |
polyLine.FillRule = FillRule.EvenOdd; | |
polyLine.Points = draw_points; | |
panel.Children.Add(polyLine); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment