Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing rectangle between two points with arbitrary width

Tags:

math

qt

opengl

2d

I'm trying to draw a line between two (2D) points when the user swipes their finger across a touch screen. To do this, I plan on drawing a rectangle on every touch update between the X and Y of the previous touch update and the X and Y of the latest touch update. This should create a continuous and solid line as the user swipes their finger across the screen. However, I would also like this line to have an arbitrary width. My question is, how should I go about calculating the coordinates I need for each rectangle (x1, y1, x2, y2)?

--

Also: if anyone has any information on how I could then go about applying anti-aliasing to this line it'd be a massive help.

like image 591
AaronDS Avatar asked Oct 21 '11 19:10

AaronDS


2 Answers

Calculate a vector between start and end points

V.X := Point2.X - Point1.X;
V.Y := Point2.Y - Point1.Y;

Then calculate a perpendicular to it (just swap X and Y coordinates)

P.X := V.Y; //Use separate variable otherwise you overwrite X coordinate here
P.Y := -V.X; //Flip the sign of either the X or Y (edit by adam.wulf)

Normalize that perpendicular

Length = sqrt(P.X * P.X + P.Y * P.Y); //Thats length of perpendicular
N.X = P.X / Length;
N.Y = P.Y / Length; //Now N is normalized perpendicular

Calculate 4 points that form a rectangle by adding normalized perpendicular and multiplying it by half of the desired width

R1.X := Point1.X + N.X * Width / 2;
R1.Y := Point1.Y + N.Y * Width / 2;
R2.X := Point1.X - N.X * Width / 2;
R2.Y := Point1.Y - N.Y * Width / 2;
R3.X := Point2.X + N.X * Width / 2;
R3.Y := Point2.Y + N.Y * Width / 2;
R4.X := Point2.X - N.X * Width / 2;
R4.Y := Point2.Y - N.Y * Width / 2;

Draw rectangle using these 4 points.

Here's the picture:

Drawing rectangle between two points

EDIT: To answer the comments: If X and Y are the same then the line is exactly diagonal and perpendicular to a diagonal is a diagonal. Normalization is a method of making a length to equal to 1, so that the width of your line in this example will not depend on perpendiculars length (which is equal to lines length here).

like image 132
Kromster Avatar answered Nov 02 '22 15:11

Kromster


Easy way (I'll call the "width" the thickness of the line):

We need to calculate 2 values, the shift on the x axis and the shift on the y axis for each of the 4 corners. Which is easy enough.

The dimensions of the line are:

width = x2 - x1

height = y2 - y1

Now the x shift (let's call it xS):

xS = (thickness * height / length of line) / 2

yS = (thickness * width / length of line) / 2

To find the length of the line, use Pythagoras's theorem:

length = square_root(width * width + height * height)

Now you have the x shift and y shift.

First coordinate is: (x1 - xS, y1 + yS)

Second: (x1 + xS, y1 - yS)

Third: (x2 + xS, y2 - yS)

Fourth: (x2 - xS, y2 + yS)

And there you go! (Those coordinates are drawn counterclockwise, the default for OpenGL)

like image 40
Fault Avatar answered Nov 02 '22 13:11

Fault