Bezier Curve Angle Calculation Silverlight


Introduction

A Bezier curve is a curve which is one of the most frequently used for computer graphics. Higher dimensions of Bezier curves are used for 3D works, which also includes Bezier triangle. Pierre Bezier, a fresh engineer who worked for Renault, derived the concept behind the calculative mechanism of the curve, which he used to design automobile body parts. In general, Bezier equations are simple but parametric equations in a variable of t (where t ranges from 0 – 1).

The Bezier Curve

Bezier Curve

Where are we going to use this?

As a software engineer / programmer, this is a question which we have when we see some irregular mathematical calculations. But the answer is thatwe use Beziers in almost all graphic related works to draw simple but smooth curves. We use Bezier curves in almost all animations for smooth movement from one point to another in the background. This is widely used in Adobe Flash and Silverlight in their transformation as well.

At times, when you are using 3D animation, Bezier curves are used to define the 3D path and the 2D curves for key frame interpolation.

We also use Bezier if we want to create stretched text, or funny looking faces, as there is a lot of calculation; to be specific, a lot of mathematical calculation in the background which performs these functions.

In this article, I am trying to define a simple Bezier curve (and its points) and find the angle at any given point of the Bezier. This article will help a lot for someone who already has a Bezier curve(s) and want to move an object through it maintaining the rotation of the object.

How did I end up doing this?

I had a requirement where an object path needed to be plotted in a given canvas, and the points needed to be converted into smooth curves. On completing this, I had to move an object (like an arrow) from the starting position to the ending position, maintaining the arrow’s rotation angle.

I initially thought it was a screwed up requirement, but as you know, the Wiki has almost all the definitions to calculations. Being an enthusiast in mathematics, I took the challenge to drive through the Bezier curves for a while and ended up with a standard function.

 Collapse
B(t) = (1-t)<sup>2</sup> P0 + 2(1-t) t P1 + t<sup>2</sup>P2 , t ranges from 0,1

This is the function for a Quadratic Bezier curve where P0 is the starting point, P2 is the ending point, and the curve passes through P1. There are various other Bezier curves which can be solved using the given function.

We convert this function into X, Y coordinates as given below:

  • B(t)x = (1-t)2 P0x + 2(1-t) t P1x + t2P2x , t ranges from 0,1 (determines the x coordinate of the curve)
  • B(t)y = (1-t)2 P0y + 2(1-t) t P1y + t2P2y , t ranges from 0,1 (determines the y coordinate of the curve)

We will be able to get a range of values on substituting values for t(0-1); giving a more precise value for t will give you minute values for x, y coordinates, making it smooth.

Code description

The code is divided into the following blocks:

  • Draw a Bezier curve (Silverlight already has this one).
  • Find the Bezier coordinates for each part of the curve.
  • Determine the angle between the points.
  • Draw your arrow.

The System.Windows.Media namespace already comes with various classes for drawing Bezier segments. They are BezierSegment (to draw a cubic Bezier curve between two points), PolyBezierSegment (to draw multiple cubic Bezier curves), QuadraticBezierSegment (to draw a quadratic Bezier curve), and PolyQuadraticBezierSegment (to draw a series of Quadratic Bezier curves).

We use the QuadraticBezierSegment class as given below which will create a Bezier curve for the three points given.

 Collapse
Path p = new Path();
p.Stroke= new SolidColorBrush(Color.FromArgb(100,255,100,255));
p.StrokeThickness= 2;
//Setting the path.
QuadraticBezierSegment qg = new QuadraticBezierSegment();

qg.Point1 = new Point(Convert.ToDouble(p1x.Text), Convert.ToDouble(p1y.Text));
//P1

qg.Point2 = new Point(Convert.ToDouble(p2x.Text), Convert.ToDouble(p2y.Text));
//P2

PathFigure pf = new PathFigure();
pf.StartPoint = new Point(Convert.ToDouble(p0x.Text),
                          Convert.ToDouble(p0y.Text));
//P0

pf.Segments.Add(qg);
PathGeometry pg = new PathGeometry();
pg.Figures.Add(pf);
p.Data=pg;
LayoutRoot.Children.Add(p);

We already have a Bezier curve drawn with the above given code; once the curve is drawn, we are going to determine the various points involved in the curve. For my purpose, I only wanted to determine the end point arrow, so I am limiting the value of t from 0.99 to 1 with which I will only get two points (which is required to determine the angle of the arrow).

Note: If you want to find all the points involved in the curve, you should replace the start value from 0.99 to 0, and if you want to go into minute curve points, change the value of increment from 0.01 to any value lesser.

 Collapse
double x = 0, y = 0;
double xold = 0, yold = 0;
double angle = 0;
for (double t = 0.99; t < 1.001; t += 0.01)
{
    x = ((1 - t) * (1 - t) * p0.X) + (2 * t * (1 - t) * p1.X) + (t * t * p2.X);
    //this statement is used to determine the x coordinate of the curve. 

    y = ((1 - t) * (1 - t) * p0.Y) + (2 * t * (1 - t) * p1.Y) + (t * t * p2.Y);
    //this statement is used to determine the y coordinate of the curve. 

    x = Math.Round(x, 3);
    y = Math.Round(y, 3);
    angle = Math.Round(Angle(xold, yold, x, y), 3);
    textBox1.Text += "Angle = " + angle.ToString() + "Degrees :" +
                     x.ToString() + "," + y.ToString() + "\n";

    xold = x; yold = y;
}

e can determine the angle between two different points using geometric functions. This is explained beautifully in the link provided by Carlos Femmer (thank you man): http://www.carlosfemmer.com/post/2006/02/Calculate-Angle-between-2-points-using-C.aspx.

I have used the same function mentioned in the above URL.

The last part of this article is to draw an arrow based on the angle we have determined from the last point of the Bezier curve. I have used arotateImage function which does the functionality of rotating an arrow based on the angle. The code below explains the details involved.

 Collapse
//code to be placed in the Bezier Function
Image image = new Image();
Uri uri = new Uri("arrow.jpg", UriKind.Relative);
ImageSource img = new System.Windows.Media.Imaging.BitmapImage(uri);
image.Margin = new Thickness(x, y, 0, 0);

image.SetValue(Image.SourceProperty, img);
image.Width = 36;
image.Height = 32;
image.Stretch = Stretch.Fill;
image.VerticalAlignment = System.Windows.VerticalAlignment.Top;
image.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;

LayoutRoot.Children.Add(image);

private void rotateImage(double angle, Image image1)
{
    WriteableBitmap bm;
    RotateTransform objTran;

    try
    {
        objTran = new RotateTransform();
        objTran.CenterX = 0.5 * image1.Width;
        objTran.CenterY = 0.5 * image1.Height;

        objTran.Angle = angle;

        bm = new WriteableBitmap(image1, objTran);
        image1.Source = (System.Windows.Media.ImageSource)bm;
        bm = null;
        GC.Collect();
    }
    catch (Exception ex)
    {
        //do waht ever you want here :) 

    }

Other variances

We can create variances of Bezier using the formula below:

History

The code does not have much of a history, I just wrote it a couple of days back, but I do have one. Not writing it here as you guys might screw me with your comments.

John Joseph

John Joseph

John Joseph

johnjoseph 8 gmail.com

Sound activated switch in C#/WPF, Clap Switch C#


Introduction 

The article is a sound activated switch done in WPF (.Net 4.0) for controlling your applications or function based on sound variation. I have used NAudio library to capture the sound signals. The application has been designed to be a very simple and easy to use one.

NAudio is licensed under Microsoft Public License (Ms-PL) with which you will be able to use it where ever you want, even in your commercial applications, so feel free to use it in your Applications.

How did this happen…

There was a requirement to activate a switch when a tennis ball is hit (related to a tennis coaching application). The application had to record a video a couple of seconds before the ball was hit.

I did some research and found a very good article in channel9 (mentioned in the reference section) which contains the major functionality, but was meant for different purpose.  I tweaked it with some small functionality to create the Sound activated switch; you can even call it a Clap Switch in C# / WPF.

What is all this?

NAudio includes a class called WaveIn which is the main class we are going to use for this application. WaveIn also contains a static function called DeviceCount for getting the count of input devices.

WaveInCapabilities class is used to get the device information from waveInDevice (which is represented as an integer).

An event called DataAvailable is raised when there is an input sound signal (which can be even plotted). The event will be the total Bytes recorded and the buffer object, which means that the event will be triggered in frequent intervals (almost real-time) and will contain an array of the buffered values, which will be a byte array and for our application it should be converted to float.

We then compare the sound levels and make the necessary changes to sensitivity levels (0-100) which will be compared with the sound values. You can probably trigger your other functions from here.

         private float bigValue;
        WaveIn waveIn;
        private double MaxValue;
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (Convert.ToInt16(textBox1.Text) > 100)
            {
                MessageBox.Show("Invalid Value");
                return;
            }
            else
                MaxValue = Convert.ToDouble(textBox1.Text) / 100;
            bigValue = 0;
            waveIn= new WaveIn();
            int waveInDevices = WaveIn.DeviceCount;
            //get the devicecount

            for (int waveInDevice = 0; waveInDevice < waveInDevices; waveInDevice++)
            {
                WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
            }
            //load in the deviceinfo using the GetCapabilties function

            waveIn.DeviceNumber = 0;
            waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(waveIn_DataAvailable);
            int sampleRate = 8000; // 8 kHz
            int channels = 1; // mono
            waveIn.WaveFormat = new WaveFormat(sampleRate, channels);
            //Setting the format
            waveIn.StartRecording();
        }
  void waveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            for (int index = 0; index < e.BytesRecorded; index += 2)
            {
                short sample = (short)((e.Buffer[index + 1] << 8) |
                                        e.Buffer[index + 0]);
                float sample32 = sample / 32768f;
                label1.Content = sample32.ToString();
                if (bigValue < sample32)
                {
                    bigValue = sample32;
                    label2.Content = bigValue.ToString();
                    if (bigValue > MaxValue)
                    {
                        waveIn.StopRecording();

                        MessageBox.Show("Did you Clap?");
                    }
                }
            }

        }

You want to use this somewhere?

I am using this application for switching of Video Streams based on the voice, I also see various application in your day to day applications where you want to control any part of your application with sound activation like, show a status report when you manager / boss start making weird sounds :), you need to keep the sensitivity level accordingly though.

Clap switches are traditionally used in Electronic applications and you will see a wide variety of applications related to clap switches, an advance form of this application will be voice recognition(which is already available) in the Speech to Text facility in SAPI.

NAudio provides some samples where you can easily work on Sound Visualization in .NET, thought .NET is not the best solution for this, and it performs fairly above expectation when it comes to Audio functions.

Reference

The article named .Net Voice by Mark Heath is the real source behind this article, i just added some frills to his, and create a different function.

http://channel9.msdn.com/coding4fun/articles/NET-Voice-Recorder  

About

John Joseph

John Joseph

John Joseph

johnjoseph 8 gmail