Thread: Getting normal between two angles (Logical question)

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    16

    Question Getting normal between two angles (Logical question)

    I'm doing a routine where I get an indefinite number of values from 0-360, which are angles in degrees. I want to calculate the normal, which is the average in the middle of the start and end angle. The problem is around the switch of 360.

    Example 1:
    0, 45, 90 = Average is 45

    Example 2:
    90, 180, 270 = Average is 180

    Example 3:
    315, 0, 45 = The normal here is 0, which is easy to see, but to calculate it i need to add 360 to 0 and 45, calculate, then remove 360 again. (315+360+405)/3 = 360 -> 0.

    So how can I do this programmatically to make it work for any angles? I guess the magic part is to know when to add 360 to not mess up in the crossover at 360 degrees.
    This is not really a C question, but since I'm coding it in C/ObjC I might as well ask here.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Are your angles guaranteed to come in "increasing" order? If so, that's your hint. Otherwise you're going to have to decide why you should turn 315,0,45 into 0 and not into 120 (or 180 if you're only looking at the end angles).

    And just as a side note, "normal" already has a meaning and this ain't it.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by tabstop View Post
    Are your angles guaranteed to come in "increasing" order? If so, that's your hint. Otherwise you're going to have to decide why you should turn 315,0,45 into 0 and not into 120 (or 180 if you're only looking at the end angles).

    And just as a side note, "normal" already has a meaning and this ain't it.
    From what I understand he simply wants modulo:

    Code:
    (359 + 1 + 5) % 360 == 5
    Read up on the modulus operator.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you want to bisect angles (i.e. you are always just looking at two angles), and you always want to use the "short" side rather than go around the long way, then check whether big-small > 180; and if so, add 360 to the small one.

  5. #5
    Registered User
    Join Date
    Dec 2010
    Posts
    16
    I'm using this to calculate how an object will bounce of a surface, which I need the normal for, at least that's what I think it is called, but I probably describet it in a incorrect way.

    I get values in order in a for loop 0 to 360 for example:
    0, 20, 40, 60, 80, 280, 300, 320, 340.

    The interesting values here are 80 and 280, which is where the circual sector begins and ends, and I could indeed add 360 to 80 = 440 and get the avg which is 360, which would be the normal I'm after.

    But how do I determine that 80 and 280 is the values to work with? There is obviously a gap in the number sequence, but I don't know how to make my code know that.

    There could in some cases also be another gap in the sequence, like this:
    0, 20, 40, 60, 80, 280, 300, 340.

    But I want the biggest gap to work with. Maybe I should count the gaps in the loop and track the numbers before and after the biggest gap, but it seems so complex.

    It's so easy to tell the answer when I see it visually, but in code, it's a different story. Tabstop, do you have any suggestions for me?

    The modulus operator didn't quite help me even if it magically worked in some circumstances.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You should have a vector that represents the motion of the object, and a vector that represents the wall. Do you have a normal of the wall (you're supposed to) or a vector that represents the surface of the wall?

    Assuming you've done things correctly and have the surface of the wall, then
    resultant = velocity - 2*proj_(normal) velocity
    and you're done.

  7. #7
    Registered User
    Join Date
    Dec 2010
    Posts
    16
    Thanks, I got all that. I have everything except the normal of the wall. That's what I'm trying to figure out.

    The real issue here is that the wall is uneven, and goes in and out, so I made a routine to estimate the angle of the wall. By taking the point of the collision, I circle around a few point out and check for walls.

    In the image below the green dots represent the angles that are not covered by walls. So I basically want the average/center of these dots, that's my normal.
    Attachment 10313

    In a few cases on a strange wall, for example a very pointy mountan, there could be another green dot behind, but I want the part with the most dots to create the normal for my bounce routine.

    So as soon as I have the normal, I can easily bounce it correctly with the formula you wrote. But I still can't figure out how to get the center of the circular sector from my list of angles?

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So how are you drawing the brown blob mountain thing? It looks like a bunch of lines/triangles/straight things glued together. That's where your normals come from -- the normal of the line that is in force where you intersect.

  9. #9
    Registered User
    Join Date
    Dec 2010
    Posts
    16
    It's a pixelbased collisionmap, so there are no known angles. That's why I need to estimate the angle of the collided pixel, by looking at neighboring pixels to find a plane to make a normal from.

    What I'm gonna try now is to make an array of all angles that are free/non-colliding, add 360 to all below 180, and sort it. Then create an array called sections, that will store all angles that are connected. Like this with a step of 20:

    angles = [0, 20, 40, 80, 100, 120, 220, 240, 260, 280, 300, 320, 340];
    angles_fixed = [360, 380, 400, 440, 460, 480, 220, 240, 260, 280, 300, 320, 340];
    angles_sorted = [220, 240, 260, 280, 300, 320, 340, 360, 380, 400, 440, 460, 480];
    section[0] = [220, 240, 260, 280, 300, 320, 340, 360, 380, 400];
    section[1] = [440, 460, 480];

    Which array has most values? section[1], use that to get normal:
    (220+400)/2 = 310

    It seems like a pretty bloated way to get the result, but I think it might work. Do you have any other better ideas? If this all sounds nonsense to you, I understand.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So how are you modeling this object in your program? If you are tempted to answer "with the bitmap/image", then that means the answer is really "I'm not". Hence your first order of business is to then put the mountain in your program, since it isn't yet. I'm guessing for this it doesn't have to be exact pixel for pixel, but you'll want to put the outline of the mountain (as a bunch of line segments) as a thing in your program.

  11. #11
    Registered User
    Join Date
    Dec 2010
    Posts
    16
    I'm not sure what you mean by modelling, but I have a collisionmap as a char[] of the bitmap x/y coords, to tell me where it's mountain or air, so I know if I collide or not. So as soon as I collide with the collisionmap, I calculate the angle of the plane from around that pixel.

    I need to do it pixel by pixel, since the map is gonna be "breakable", which will update the bitmap and the collisionmap. This may cause some funky collision, but I guess that's just finetuning on how pixel perfect it needs to be. Average to a bunch of pixels, and it might just work..

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You need to distinguish between what an object is, and how you draw it. For example, look at your ship. You draw your ship with a "Y", more or less. But that's not what it is, in your code. The ship is an object that has a size, an orientation (facing direction), a reference point (front of the ship, center of the ship, whichever you chose), a position, and probably a velocity and acceleration as well. You need something similar for your blob as well.

  13. #13
    Registered User
    Join Date
    Dec 2010
    Posts
    16
    Hmm.. I'm not sure I follow how that would help me. I draw the background, and I also have a parallell collision map as an object, which I work with to find out when I collide, and now the angle of each pixel, by averaging the pixels around. The green dots around is really showing where the normal is. Now I'm working through a lot of numbers to actually find the center.

    I don't see what I should do with objects to make this happen?

  14. #14
    Registered User
    Join Date
    Dec 2010
    Posts
    113
    Quote Originally Posted by BlueGooGames View Post
    I'm doing a routine where I get an indefinite number of values from 0-360, which are angles in degrees. I want to calculate the normal, which is the average in the middle of the start and end angle. The problem is around the switch of 360.

    Example 1:
    0, 45, 90 = Average is 45

    Example 2:
    90, 180, 270 = Average is 180

    Example 3:
    315, 0, 45 = The normal here is 0, which is easy to see, but to calculate it i need to add 360 to 0 and 45, calculate, then remove 360 again. (315+360+405)/3 = 360 -> 0.

    So how can I do this programmatically to make it work for any angles? I guess the magic part is to know when to add 360 to not mess up in the crossover at 360 degrees.
    This is not really a C question, but since I'm coding it in C/ObjC I might as well ask here.
    I haven't understood the other messages, but I can suggest something to this message.

    What about defining two normals firstly:

    N1=(Max+Min)/2
    N2=N1+180

    Then choosing the one you want to get

    Example 1:
    N1=(90+0)/2=45
    N2=45+180=225

    Example 2:
    N1=(90+270)/2=180
    N2=180+180=360

    Example 3:

    N1=(315+45)/2=180
    N2=360

    Another example:

    270 and 40;

    N1=(270+40)/2=155
    N2=155+180=335

  15. #15
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by BlueGooGames View Post
    Hmm.. I'm not sure I follow how that would help me. I draw the background, and I also have a parallell collision map as an object, which I work with to find out when I collide, and now the angle of each pixel, by averaging the pixels around. The green dots around is really showing where the normal is. Now I'm working through a lot of numbers to actually find the center.

    I don't see what I should do with objects to make this happen?
    Let's make an easy blob that's a triangle. So your object has three sides (you can store as endpoints and work out normals as needed). So:
    Code:
    for each side in object
        does ship hit side?
            if so, bounce it off
    end for

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie question, C #
    By mate222 in forum C# Programming
    Replies: 4
    Last Post: 12-01-2009, 06:24 AM
  2. another do while question
    By kbpsu in forum C++ Programming
    Replies: 3
    Last Post: 03-23-2009, 12:14 PM
  3. Question type program for beginners
    By Kirdra in forum C++ Programming
    Replies: 7
    Last Post: 09-15-2002, 05:10 AM
  4. Question about logical operators
    By JohnMayer in forum C Programming
    Replies: 3
    Last Post: 07-22-2002, 06:32 PM
  5. logical expression question
    By JohnMayer in forum C Programming
    Replies: 1
    Last Post: 07-22-2002, 03:46 PM