Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Monofoxe/Monofoxe.Engine/Drawing/BezierCurve.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.Xna.Framework;
using Monofoxe.Engine.Utils;

namespace Monofoxe.Engine.Drawing
{
public class BezierCurve

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be static

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to BezierCurveShape to keep consistency with other such classes.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class should have a short description.

{
public static void Draw(Vector2[] controlPoints, float interval = 0.01f)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the autodoc comment describing what the method does and what the arguments are for.

{
var points = GameMath.BezierCurvePoints(controlPoints, interval);

for (var i = 0; i < points.Length - 1; i += 1)
{
LineShape.Draw(points[i], points[i + 1]);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is inefficient, you should be pushing vertices to the vertexbatch like LineShape.Draw() does.

}
}
}
}
116 changes: 108 additions & 8 deletions Monofoxe/Monofoxe.Engine/Utils/GameMath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,24 +208,124 @@ public static float GetArea(List<Vector2> vertices)
}



#region Bezier curve stuff.
// A look up table for factorials. Capped to 16.
private static float[] Factorial = new float[]

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a private field, the naming should be _factorial

{
1.0f,
1.0f,
2.0f,
6.0f,
24.0f,
120.0f,
720.0f,
5040.0f,
40320.0f,
362880.0f,
3628800.0f,
39916800.0f,
479001600.0f,
6227020800.0f,
87178291200.0f,
1307674368000.0f,
20922789888000.0f,
};

private static float Binomial(int n, int i)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method needs at least some description. Google what it does and just copypaste a quick summary or a url to wikipedia.

{
float ni;
float a1 = Factorial[n];
float a2 = Factorial[i];
float a3 = Factorial[n - i];

ni = a1 / (a2 * a3);

return ni;
}

private static float Bernstein(int n, int i, float value)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method needs at least some description. Google what it does and just copypaste a quick summary or a url to wikipedia.

{
float value_i = MathF.Pow(value, i);
float value_n_minus_i = MathF.Pow((1 - value), (n - i));

float basis = Binomial(n, i) * value_i * value_n_minus_i;

return basis;
}
#endregion


/// <summary>
/// Calculates three-point bezier curve.
/// Calculates bezier curve.
/// </summary>
/// <param name="value">Should be in 0..1 range.</param>
public static Vector2 BezierCurve(Vector2 startPoint, Vector2 controlPoint, Vector2 endPoint, float value)
public static Vector2 BezierCurve(Vector2[] controlPoints, float value)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return three-point BezierCurve, it can exist alongside the n-point bezier.

		public static Vector2 BezierCurve(float value, params Vector2[] points)
		{ 
// ...
		}

		public static Vector2 BezierCurve(float value, Vector2 startPoint, Vector2 controlPoint, Vector2 endPoint)
		{
// ...
		}

{
float u = 1 - value;
float tt = value * value;
float uu = u * u;
int N = controlPoints.Length - 1;

if (N > 16)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also add a check for less than 3 points.

{
throw new Exception("The maximum control points allowed is 16.");
}


if (value <= 0)
{
return controlPoints[0];
}
if (value >= 1)
{
return controlPoints[controlPoints.Length - 1];
}


Vector2 pointOnCurve = uu * startPoint;
pointOnCurve += 2 * u * value * controlPoint;
pointOnCurve += tt * endPoint;
Vector2 pointOnCurve = new Vector2();

for (int i = 0; i < controlPoints.Length; ++i)
{
Vector2 bn = Bernstein(N, i, value) * controlPoints[i];

pointOnCurve += bn;
}

return pointOnCurve;
}


/// <summary>
/// Returns an array of points spaced with passed interval.
/// </summary>
public static Vector2[] BezierCurvePoints(Vector2[] controlPoints, float interval = 0.01f)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this method, it's not really needed.

{
int N = controlPoints.Length - 1;

if (N > 16)
{
throw new Exception("The maximum control points allowed is 16.");
}


List<Vector2> points = new List<Vector2>();

for (float t = 0.0f; t <= 1.0f + interval - 0.0001f; t += interval)
{
Vector2 p = new Vector2();

for (int i = 0; i < controlPoints.Length; ++i)
{
Vector2 bn = Bernstein(N, i, t) * controlPoints[i];

p += bn;
}

points.Add(p);
}

return points.ToArray();
}


/// <summary>
/// Returns a projection aligned to the Y axis.
/// </summary>
Expand Down
35 changes: 34 additions & 1 deletion Samples/Monofoxe.Samples/Demos/UtilsDemo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class UtilsDemo : Entity

Sprite _fireSprite;


Vector2[] _bezierCurvePoints;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private Vector2[] _bezierCurvePoints;


public UtilsDemo(Layer layer) : base(layer)
{
Expand Down Expand Up @@ -118,6 +118,18 @@ public UtilsDemo(Layer layer) : base(layer)
_stateMachine.AddState(TestStates.Blue, Blue);
_stateMachine.AddState(TestStates.Red, Red);
// State machine.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add three-point bezier demo and add a demo that calls GameMath.BezierCurve directly.


// Bezier curve.
_bezierCurvePoints = new Vector2[]
{
new Vector2(57, 410),
new Vector2(170, 500),
new Vector2(291, 410),
new Vector2(330, 500)
};
// Bezier curve.

}

/// <summary>
Expand Down Expand Up @@ -313,6 +325,8 @@ public override void Draw()


DrawDampers();

DrawBeizerCurve();
}

private FloatDamper _floatDamper1 = new FloatDamper(0, 1, 1, 0);
Expand Down Expand Up @@ -345,6 +359,25 @@ private void DrawDampers()
LineShape.Draw(_baseAnglePos, _baseAnglePos + _angleDamper.Value.ToVector2() * 50);
}

private void DrawBeizerCurve()
{
for (var i = 0; i < _bezierCurvePoints.Length - 1; i += 1)
{
CircleShape.Draw(_bezierCurvePoints[i], 3, ShapeFill.Solid);

LineShape.Draw(_bezierCurvePoints[i], _bezierCurvePoints[i + 1]);
}
CircleShape.Draw(_bezierCurvePoints[_bezierCurvePoints.Length - 1], 3, ShapeFill.Solid);


var prevColor = GraphicsMgr.CurrentColor;
GraphicsMgr.CurrentColor = Color.Red;

BezierCurve.Draw(_bezierCurvePoints);

GraphicsMgr.CurrentColor = prevColor;
}

public override void Destroy()
{
base.Destroy();
Expand Down