5.14.2013 Measure the Angle of a Line

Find Angle from two points
When you draw a line, does that come to you that how many degrees is that line? How much is it steep or flat? Learn through your own program.


A line can be of any angle. It can be parallel to earth, or steep like a pole, or angular, like it is leaning towards something. We all know the name of Tower of Pisa. It is famous for its leaning nature. It is not perpendicular/staright/vertcal like all the other usual buildings of the world. It is not standing 90 degrees upright, but its leaning by 5.5 degrees.

Leaning tower of pisa

So if we get a imaginary line at the at the right side of the tower, then can we calculate the angle of pisa? Yes. But we need math. Specifically Geometry and more specifically Trigonometry.

Quick Tutorial

I am weak at math. So I borrowed a function from here by a user named NLGN:

function TForm1.AngleOfLine(const P1, P2: TPoint): Double;
begin
  Result := RadToDeg(ArcTan2((P2.Y - P1.Y),(P2.X - P1.X)));
  if Result < 0 then
    Result := Result + 360;
end;

Create a new Application Project (Project-> New Project-> Application-> OK).

Paste the above function below the {$R *.lfm} line. Take the cursor over the name of the function and press Ctrl+Shift+C.

Add math unit to the uses clause:
uses
  ..., math;

Find Angle from two points

Suppose that we want to calculate the angle of the diagonal line. The line starts at (0, 0) position [where it is (x, y)] and ends at (100, 100) position. From the image above, it is obvious that the angle is 45 degrees. But let our program find the angle

Switch to Form Designer (F12). Now Double click the form and enter:

Caption := FloatToStr(AngleOfLine(point(0, 0), point(100, 100)));

Our two points lies in point(0, 0) and point(100, 100).

Now run the project (F9 or Run-> Run).

You will see 45 in the Title bar of the form. It will be able to detect the angle from the two points given.

You can utilize this function to show your creativity to implement this function in many ways. We have a sample code zip file downloadable below. It is a graphical implementation of the function.






We have a TImage named Image1. In the mouse move event of it we have such code:

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  angle: ValReal;
begin
  if Clicked = true then begin // mouse is pressed
    Image1.Canvas.FillRect(0,0,Image1.Width,Image1.Height);

    Image1.Canvas.Line(Start_x, Start_y, X, Y);
    Image1.Canvas.Line(Start_x, Start_y, Start_x+50, Start_y);

    // Angle related drawings...
    angle:=AngleOfLine(Point(Start_x,Start_y), Point(X,Y));
    Image1.Canvas.Arc(Start_x-25,Start_y-25,Start_x+25,Start_y+25,
                       0,-round(angle*16));

    Edit1.Text:=FormatFloat('0.00',angle);
  end;
end;

Start_x and Start_y contains the X and Y position of mouse cursor when the mouse was pressed down.
We use arc function to draw an arc to indicate the angle's length.



Download Sample Code ZIP

You can download example source code from here: http://db.tt/S73hZLr5
Or here: http://bit.ly/10TeCxG
Size: 522 KB
The package contains compiled executable EXE file.


Ref:
http://lazarus-ccr.sourceforge.net/docs/lcl/graphics/tcanvas.arc.html
http://stackoverflow.com/questions/15596217/angle-between-two-coordinats-arctan2
http://lazarus-ccr.sourceforge.net/docs/rtl/math/radtodeg.html

Credits:
http://stackoverflow.com/users/757830/ngln

Photo: http://panfilocastaldi.wordpress.com

6 comments:

Hudsonkem Marinho said...

again you doing a great job :D, I appreciate that.

Hudsonkem Marinho said...

I would like to know you, talk a little about programmation :). my skype: hudsonkem, aaah! I would like one example about angles to ddtank tragetorie, I try but I can't understand, like... the mathematical formula '-'. so I'll waiting for u.

Adnan Shameem said...

@Hudsonkem

Thank you.

" I would like one example about angles to ddtank tragetorie"

I don't understand. Please clarify.

Eddie Bole said...

First of all let me say what a great blog this is. I have been searching for simple Delphi/Lazarus tutorials for quite a while. I love how things are explained step by step and in simple terms.
For the above code, how would you make a moveable line that originally appears in the middle. I would like to overlay a moveable line on top of a skewed (slanted) text picture. Then align the line with the slanted text and finally click a command button to rotate the picture so that the text is horizontal.

Adnan Shameem said...

@Eddie Bole
Thanks for being with LazPlanet.
By "skewed (slanted) text picture" do you mean that a picture that has a rotated text? These things are hard to understand in writing, but do you wish to rotate the picture based on a movable line? If this is what you are looking for then take the value of the "angle" variable on "TForm1.Image1MouseMove" and utilize it to rotate the image. You may have to calibrate/plus minus the value to suit the BGRA implementation of rotation of the image. For the rotation of the image try the code in this Forum post by "circular". I have never tried the code, but it should work I suppose. :)

If you are new to BGRA Bitmap and having problem with using it in your project, then look here in this wiki page.

Cindy Dy said...

I am very happy to locate your website. I just wanted to thank you for the time you spent on this great article. I definitely enjoyed reading it and I have you bookmarked to check out new stuff you post.


Yong
www.gofastek.com

 
Copyright 2013 LazPlanet
Carbon 12 Blogger template by Blogger Bits. Supported by Bloggermint