Thursday, February 11, 2010

Angle math

I've got a new applet posted on my web page, which I wrote for my son Ben. He is seven. It is a demonstration of how angles work. You can drag the points of the triangle around, and it will continuously update the display of numbers showing what angle is formed at each point. It also gives a little readout showing that the three angles will, indeed, always add up to 180 degrees.

I like to do a little graphical application every once in a while just to stay in practice. There are a lot of concepts from trigonometry that have to be applied. Debugging graphics is sometimes a tricky affair, because if you don't do the right thing then you might wind up with nothing but a blank screen, or a line might appear wildly out of place. Finding the angles required remembering what sines and cotangents and such represent. (SOH CAH TOA! That's one that never leaves your memory, but I got sin and asin mixed up for a while.)

I also had to fudge the numbers a little bit. For instance, one angle might be 70.14 and another might be 50.34. The third angle should be 59.52. However, if you reduce those to one significant figure, you find that 70.1+50.3+59.5 = 179.9. So I had to fake the third angle (a3) as displaying 180-a1-a2.

The hardest challenge came after I decided to change "nearly" right angles into true right angles. Notice that if you drag one corner so that it forms an angle between 80 and 100 degrees, it will automatically snap to the correct position so that it is 90 degrees. I had to put some thought into making that work, and here's the solution I wound up with.

  1. Write an expression of the line segment opposite the point being moved.
  2. Find a vector perpendicular to that line.
  3. Project the moved point along that vector to find where it intersects the opposite segment.
  4. Find the actual distance that the point must be from the segment in order to make a 90 degree angle.
  5. Move the point there.

I had originally used only a "Point" class and a "Triangle" class to represent the problem space; I soon realized I needed a "Vector" class as well (one which could be used to offset a point, normalized, reversed, or made perpendicular to another vector). Then I had to make yet another class, "Line," in order to properly calculate where intersections can be found. I borrowed a lot from this page, and found out just how long it had been since I needed to do that math -- I had a totally incorrect idea of how a line formula is expressed.

Basically the key to correcting your math mistakes -- and I made a lot! -- is to create either a printout or a visual representation at every step. For instance: I think I've normalized the vector correctly, better print out the coordinates and make sure the length is really 1. I need to draw an extra line to make sure it really goes through this point. I need to draw an extra point to make sure it really intersects that line. Do these two lines LOOK perpendicular to me? And so on.

If I had remembered the math better then some of this rigor wouldn't have been necessary. But really, caution and constant testing while coding eliminates the need to be a perfect math whiz. Coding is both theoretical and experimental, you see.

4 comments:

  1. If you truly loved your son, you would have made HIM program that applet! He's seven - that's old enough for Java, at the very least.

    On a side note, how difficult would it be to, let's say, input how many points on your shape you want, and let the program do the rest of the math for calculating angles for pentagons, hexagons, or even decemyriagons? Would that take a lot more math, with your current setup?

    Also, out of curiosity, did you manually tell the program which starting positions to place the points, or did you tell them to start out equidistant from each other and the center?

    Neat little program, btw.

    ReplyDelete
  2. If you truly loved your son, you would have made HIM program that applet! He's seven - that's old enough for Java, at the very least.

    I've showed him Java programming, in short bursts. However, I'm not optimistic enough to expect him to handle trig.

    On a side note, how difficult would it be to, let's say, input how many points on your shape you want, and let the program do the rest of the math for calculating angles for pentagons, hexagons, or even decemyriagons? Would that take a lot more math, with your current setup?

    Yes and no. Managing arbitrarily large polygons and summing the angles would be a trivial change. However, some of the angles would then be convex, which wouldn't be handled well as the program is written. Also, some of the calculations are made based on known math of triangles, such as the routine that forces it to construct a right angle perpendicular to the third side. I'd either have to take that out or find a cleverer way to handle it (perhaps by forming a virtual triangle from the two adjacent points).

    Also, out of curiosity, did you manually tell the program which starting positions to place the points, or did you tell them to start out equidistant from each other and the center?

    As it is written now, I defined the points myself. It would be more elegant to do it the other way, but I did it the quick kludgy way because it would be easy, and would not affect the rest of the program if changed.

    ReplyDelete
  3. Thanks for the reply. I only do a bit of self-taught programming every now and then, so I like to see how other people go about handling these issues, simple as they may be.

    ReplyDelete
  4. My son's geometry teacher used the phrase "Some Old Hippy Caught Another Hippie Tripping On Acid," to remember SOH CAH TOA

    ReplyDelete