• 0

C# Drawing Triangles


Question

Hi,

I was wondering how i would go about drawing a simple but accurate triangle in C# given all angles and lengths

I know how to draw simple triangles with .DrawPolygon() with a few Points but i dont know how to get an accurate representation of the triangle on a windows form taking into account angles and side lengths.

Also is there a way of attaching labels to the triangle such as a,b,c etc along with curves for the angles that move with the triiangle if angles/lengths change or when the form is resized.

Any ideas or suggestions welcome!

Thanks in advance

Link to comment
Share on other sites

18 answers to this question

Recommended Posts

  • 0

SOHCAHTOA is your friend. Pick a base point. Using that base point and the lengths/angles, calculate the 2 other vertices of the triangle. Feed those 3 points to the DrawPolygon method.

Link to comment
Share on other sites

  • 0

SOHCAHTOA will only work on right angled triangles. I have already worked out all angles/sides using sine/cosine rules etc but dont know how to convert these results into an accurate drawing of a triangle. I can get two of the points but have no idea how to calculate the third one so that it takes into account side lengths and angles.

Link to comment
Share on other sites

  • 0

Could you not draw a right angled triangle from (1, 1) vertically upwards, and then use SOHCAHTOA to get the distance on the x-axis between (1, 1) and (?, ?), and then use that knowledge to get the point on the Y-axis?

Link to comment
Share on other sites

  • 0

Finding the coordinates of the third point knowing all angles and the coordinates of the other two is elementary trigonometry. I would explain, but I feel like I'm missing something here, it's too obvious.

Link to comment
Share on other sites

  • 0

@ Majesticmerc - I think that would work but i dont see how i would e able to implement that where the range of triangles can be so great. Basically i'm making a triangle solver that gives you a visual represntation of the triangle after calculation. As triangles can take many forms this method would have to be adapted every time, resulting in stupidly complex code for such a problem. I was just wondering if there was any formula i could use that takes the coordinates and angle and gives the other point?

@ +Dr_Asik - I know. Seemed to be such a trivial problem to me at first but i still cant get a practical and adaptive solution that would work on all triangles

Thanks for the replies

Link to comment
Share on other sites

  • 0

Actually it's be easiest (and fastest) with vector algebra.

You know 2 points of the triangle; these define a vector. You know the angles between this vector and the other two segments. You are therefore able to find the two vectors describing the other two segments. Having found these vectors, you simply have to find their intersection, which is the third point.

Simple algorithm:

Points P1, P2 (values known), P3 (unknown)

Angles A1, A2, A3 (each angle corresponds to a point)

Vector V3 = P2 - P1

Vector V2 = rotate V3 anti-clockwise* around P1 by A1

Vector V1 = rotate V3 clockwise* around P2 by A2

P3 = intersection of V1 and V2

If you're looking for a good math library to help with this, I suggest OpenTK.

*Assuming P3 is above the segment P1-P2. In fact, if you only know two points, three angles and the length of each segment, there are two possible answers; one if P3 is on one side of P1-P2, the other if P3 is on the other side. You'll need additional information to disambiguate that.

Link to comment
Share on other sites

  • 0

SOHCAHTOA will only work on right angled triangles.

Exactly. So draw a vertical line at (?, ?) and you have 2 right-angle triangles. I'm somewhat surprised this isn't native to anyone who passed 9th grade math.

For the y-coordinate: 5*sin(51 degrees) + 1 = y

For the x-coordinate: 5*cos(51 degress) + 1 = x

Alternatively:

For the y-coordinate: 7*sin(34 degrees) + 1 = y

For the x-coordinate: 10 - 5*cos(34 degress) = x

Dr_Asik: somebody who can't find a right-angle triangle in that diagram is certainly going to be boggled with vectors.

Link to comment
Share on other sites

  • 0

Your method is fine but it assumes the two known points form a horizontal (or vertical) segment. It's going to get complicated to deal with segments at arbitrary angles, at which point vectors become a much simpler way of doing this than trigonometry. Besides, vectors are generally preferred because they are computationally efficient.

Link to comment
Share on other sites

  • 0

Your method is fine but it assumes the two known points form a horizontal (or vertical) segment.

Nope, it will work with any orientation. It's just a matter of having a reference point, and the OP has 2.
Link to comment
Share on other sites

  • 0

If the triangle had been, for example, rotated 30 degrees around its point (1, 1), with the same values of lengths and angles, the method you provided would not give the correct result. It would give the same result as if the triangle had not been rotated, i.e. it does not account for arbitrary orientations. Furthermore the triangle could be flipped around any axis passing by (1, 1) and your method wouldn't account for it either, because the only thing you're considering is one point and angle and you just assume a specific orientation.

Link to comment
Share on other sites

  • 0

Thanks +Dr_Asik the information on vectors helped a lot

@ boogerjones - its not that i dont understand basic trigonometry, in fact i tried that exact approach when i tried to figure at out a solution, however it turned out to be very difficult to implement on triangles that dont have a side parallel to an axis.

Plus there is nothing at all wrong with the triangle, all angles/sides are valid

Furthermore any ideas on how to implement angle labelling on the triangle (the curve portion). My previous attempts all resulted in arcs that over-ran the sides. I suppose i would have to calulate some more points on the line corresponding to a shift in the x and y values of the vertex

Finally is there a simple way of scaling the triangle up to fit the picturebox that its begin drawn on? At the moment i sam simply multiplying the side lengths by a constant value to enlarge the drawing. If not it appears extremely small for values such as 5 as it works in pixels. I was wondering of a possible way to make the drawing fill the picturebox whilst maintaining the correct angles etc.

Thanks again for the replies

Link to comment
Share on other sites

  • 0

Let's do this properly. :p

Neowin%20-%20CSharp%20-%20Drawing%20triangles.png

I assume that the coordinates of A and B are given, A is in the lower left corner of the triangle and B is in the lower right corner. (*)

A must be fixed, B can be given by its coordinates or by the length of AB (= c) and the angle between AB and the horizontal line through A (= theta).

First of all, we need the angle alpha at point A between AB and AC (b and c). Either this is already given or it has to be calculated using the length of the third side with the cosine rule:

cosine_1.png

which immediately leads to:

cosine_2.png

If B is given by its coordinates, we first must determine the angle theta. Given A(x1, y1) and B(x2, y2), theta can be found using:

tan_theta.png

Note that theta can be a positive or negative angle. This sign depends on whether B is above or below the horizontal line through A. It is important not to drop the negative sign here as it is makes a big difference!

If x1 equals x2, then A and B are positioned on a vertical line and the angle between AB and the horizontal line through A equals 90 degrees (= pi/2 rad). If y1 equals y2 then A and B are positioned on a horizontal line but then ABC would be a line segment instead of a true triangle.

Now that alpha and theta are known, we can calculate the angle phi between AC (= b) and the horizontal line through A. The calculation is pretty simple:

phi.png

At this point, the position of C relative to A is completely determined by the angle phi and the length of AC (= b). We can now express the coordinates of C as:

vector_c.png

I'm not saying this is the easiest way to do it, it was simply the first one I could come up with. As you can see, a lot depends on what elements are actually given. It's up to you to decide how you're going to implement this: will you allow all kinds of possible combinations or will you lock it down to only a few possibilities?

(*) In the general case, you can simply swap your points around on beforehand before you do your calculations. If you're starting off with two points and an angle between two sides, you can use the law of sines and the sum of angles to find the other angles.

  • Like 3
Link to comment
Share on other sites

  • 0

Thanks Calculator, great explanation!

I think i'm going to have the user input the sides and angles they know and before the triangle gets drawn, calculate all unkowns. May take a bit more work but in the end for most triangles you can do the same as shown in your example (of course checking angle sizes to determine where the right angled triangle will be positioned).

Any ideas on the labels and scaling?

Thanks for the reply!

Link to comment
Share on other sites

  • 0

Scaling shouldn't pose too much of a problem. After all coordinates have been calculated, scale (and translate) them accordingly before drawing them. Perhaps you should allow the user to scale and move the drawing with some kind of hand and zoom tool?

Labels should be straight-forward as well, you'll just have to look out to position the labels such that they don't overlap or intersect with sides or angles. A possible solution for labels assigned to corner points would be to divide the angle in half and offset the label in the opposite direction. Say, if you have a corner of 60 degrees, you'd offset the label in the - 30 degrees direction from the corner point so that it's always "outside" the triangle.

Drawing curves for the angles can be done with Graphics.DrawArc(). Specify a square with its center in the corner point as rect parameter and then do some work with the angles for the startAngle and sweepAngle. If you want a fill as well, call Graphics.FillPie() with similar parameters.

Link to comment
Share on other sites

  • 0

Wow nice answer Calculator. I had the same formulae, except for working out phi. I tip my hat to you sir!

Link to comment
Share on other sites

  • 0

Oh dear, here we go again. I found a way to do this using just the cosine of alpha (the angle between the two sides) and the sign of the angle. How? With vectors of course! :D

Drawing%20Triangles%20-%20Attempt%202.png

Given the coordinates of A and B and the angle alpha between AB and AC where C is the third point whose coordinates must be found. If alpha is unknown but the length of all sides are known, alpha can be found using the cosine rule as explained in my previous post.

Define two vectors u and v as:

vectors_uv.png

Geometrically, these vectors represent the two sides AB and AC with A translated to the origin (0,0). The coordinates of C are unknown and thus so are the coordinates of v. However, when the coordinates of v are found, C can easily be found by translating back to A (adding A to v).

The scalar product of the vectors u and v can be expressed analytically or geometrically:

scalar_product.png

Since u and v are the result of a translation from A to O, the lengths of AB and AC as well as the angle between them correspond to the lengths and angle of u and v. Thus this can also be written as:

scalar_product_2.png

The length of v is known to equal b, however the coordinates are unknown. Using the definition of the vector norm, we find:

vectornorm_v.png

We now have a system of two equations in two unknowns (v1 and v2):

system.png

To solve this, we can rewrite the first equation as:

solve_1.png

and substitute this in the second equation. This leads to the following quadratic equation in v1:

solve_2.png

where the second expression is found using the vector norm formula for u: vectornorm_u.png

The solution of this equation leads to the following formula for v1:

solution_v1.png

This is where problems may arise:

  • The plus/minus sign is quite tricky. The positive sign corresponds to the solution with the greatest value for v1 and thus with the vector with the greatest x-coordinate. The negative sign corresponds to the vector with the smallest x-coordinate. In other words, one corresponds with a positive angle and the other with a negative angle. However, this doesn't necessarily mean that the positive sign corresponds with the positive angle, as this depends on the location of the vector u and the angle alpha. I haven't figured out how to determine the right solution, I think you'll have to do some logic with the parameters for this.
  • It is not guaranteed that the square root is real, in other words that the expression inside the square root is positive. I'm not really certain how all different parameters affect this root, it looks quite nasty.

Now that v1 is found, the second coordinate can be found by filling in the value for v1 in:

solve_1.png

C is then found by adding A to v:

solution_C.png

The obvious advantage here is that you don't need any cyclometric function, only the cosine is used. The disadvantages are listed above, it may fail in certain cases. Perhaps this can be optimized to account for these cases, perhaps not.

I think you're better off sticking with the previous method for now, it was fun to try though. :p

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.