Hello all, I'm trying to approximate a sine wave using bezier curves (for rendering speed over drawing many straight lines).
I'm trying to follow the non-C# code specified down the page at:
http://commons.wikimedia.org/wiki/File:Harmonic_partials_on_strings.svg
// Produces a sine path as flat point array {PT, PT[3], PT[3], ...}
private static List<PointF> SineWavePath(float x, float y, float width, float amp, float num_half_waves)
{
const float PI = 3.1415926535897f;
const float XD = 0.261799388f;
const float SQRT2 = 1.41421356f;
const float Y1 = (2 * SQRT2) / 7 - 1 / 7;
const float Y2 = (4 * SQRT2) / 7 - 2 / 7;
const float Y3 = SQRT2 / 2;
const float Y4 = (3 * SQRT2) / 7 + 2 / 7;
float xmul = width / (num_half_waves * PI);
float xd = XD * xmul;
List<PointF> path = new List<PointF>();
// Add the first point
path.Add(new PointF(x, y));
// Loop all the points
for(int i = 1; i <= num_half_waves; i++)
{
// Add all of the points
path.Add(new PointF(x + xd, y + amp * Y1));
path.Add(new PointF(x + 2 * xd, y + amp * Y2));
path.Add(new PointF(x + 3 * xd, y + amp * Y3));
path.Add(new PointF(x + 4 * xd, y + amp * Y4));
path.Add(new PointF(x + 5 * xd, y + amp));
path.Add(new PointF(x + 6 * xd, y + amp));
path.Add(new PointF(x + 7 * xd, y + amp));
path.Add(new PointF(x + 8 * xd, y + amp * Y4));
path.Add(new PointF(x + 9 * xd, y + amp * Y3));
path.Add(new PointF(x + 10 * xd, y + amp * Y2));
path.Add(new PointF(x + 11 * xd, y + amp * Y1));
path.Add(new PointF(x + 12 * xd, y));
x += (width / num_half_waves);
// flip over vertically every half wave
amp = amp * -1;
}
// Returnt he path
return path;
}
And then rendering simply using
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Rectangle r = this.ClientRectangle;
// Create the wave
List<PointF> path = SineWavePath(r.Left, yCenter, r.Width, mAmplitude, (float)Math.Ceiling(r.Width / mWavelength));
// Render
g.DrawBeziers(mPen, path.ToArray());
// Demonstrate where the control points are
Font font = new Font(FontFamily.GenericSansSerif, 12);
for(int i = 0; i < path.Count; i++)
{
g.DrawLine(Pens.Red, path[i], new PointF(path[i].X + 3, path[i].Y + 3));
g.DrawLine(Pens.Red, path[i], new PointF(path[i].X - 3, path[i].Y + 3));
if(i >= 1) g.DrawString((((i - 1) % 12) + 1).ToString(), font, Brushes.Black, path[i]);
}
font.Dispose();
}
However, this produces a jagged waveform that comes close, but does not approximate a sine wave.
See: http://www.actsoftheword.com/Image4.gif
Anybody see where my flaw is?