Search Unity

Math help, vertex normal or what is it called?

Discussion in 'Editor & General Support' started by johot, Apr 19, 2011.

  1. johot

    johot

    Joined:
    Apr 11, 2011
    Posts:
    201
    This seems like a simple problem but im having some issues.

    I have a flat polygon used as the landscape in a 2d game. Now I want to create a new mesh following the original mesh around as a border. To do that I want to expand the polygons coordinates at the vertices. How do I found this position at each vertex? Is it called vertex normals?

    I guess I need to get the tangent at each vertex and then the normal of that tangent?

    So say I have a shape looking like this:

    /\ then I want to get the line

    |
    /\

    How do I do this in the easiest way? Thanks!
     
  2. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    As near as I can tell, what you're wanting to do is, for each vertex, compute a point along the normal of that vertex by some specified distance, e.g.:

    Code (csharp):
    1. new_vertex_position = vertex_position + vertex_normal * distance
    I may not be understanding correctly though.
     
  3. johot

    johot

    Joined:
    Apr 11, 2011
    Posts:
    201
    Hmm no it doesn't seem to work.

    I am using a 2D (flat) mesh. The normals for each vertice seem to be (0,0,-1) which is what you get when you calculate the normal for two vectors I guess.

    So I need something else I don't know what the mathematical term is. I was looking into using things like projection also, dividing stuff into triangles, finding the projection on the vector going from a to c and so on.

    But this got to be really simple right? I just want to be able to extend the vertex positions outwards on my flat mesh without the need to scale everything and recenter it.
     
  4. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    What you get when you calculate a normal depends on the input (it won't always be 0, 0, -1).

    Well, that's what the example I posted earlier does. If that's not working, I'd guess either it's a problem with your implementation, or I'm not understanding correctly what you're wanting to do.

    When you say 'outwards', do you mean outwards from the plane of the polygon? Or do you mean outwards and away from the polygon, but remaining in the plane of the polygon? (An image would probably help, if you could put one together somehow.)

    [Edit: I did see your ASCII diagram above, but that could be either of the options I mentioned, depending on how you look at it.]
     
  5. johot

    johot

    Joined:
    Apr 11, 2011
    Posts:
    201
    I mean extending outwards in the polygons plane, not up in the z-axis.

    What im currently looking at is simply scaling everything and then calculating the offset everything gets but checking the bounds of the mesh.

    But simply extending the position of the vertices outwards, in the plane of the 2D mesh would be nice, however right now im not sure how well it will work since the amount of expansion needed will be different for different vertices.
     
  6. johot

    johot

    Joined:
    Apr 11, 2011
    Posts:
    201
    I just realised I really need a soution where i can find normals along the outline of the polygon, just scaling it up and centering around the original object will not work.

    I just need to find an algorithm so I can create an outline for a polygon mesh in 2D :)
     
  7. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    How about using trig: http://markup.io/v/3yvk8rt7d0y7

    Get the yellow angle from vectors created from getting the next and previous verts on the outer band. Once you have the yellow angle you can get the green vector which is just the inverse of what you actually want.

    Oh yeah, and hurry up and get this on the Asset Store! Some of us are waiting :)
     
  8. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    Just to provide an alternate solution, this can be done with some simple vector math.

    Let two consecutive vertices of the polygon be p1 and p2. The direction vector for the edge connecting the two vertices is then:

    Code (csharp):
    1. edge = p2 - p1;
    The normal to the edge is then:

    Code (csharp):
    1. normal = normalize(vector2(-edge.y, edge.x));
    Or (edge.y, -edge.x), depending.

    Once you've computed the normal for each edge, you can compute the outward-facing normal for any vertex as the normalized average of the normals of the two edges that touch that vertex.

    If the polygon is a regular n-gon, you can create an outline of uniform thickness fairly easily this way.

    For arbitrary polygons, it's a bit more difficult to ensure that the thickness of the outline remains constant. An alternative solution is to make a copy of each edge, push each copy out along its normal by the desired outline thickness, and then intersect the supporting lines for the edges to yield the 'outer' vertices for the outline. This will work ok as long as the interior angles aren't too small. As the interior angle gets smaller though, the outer intersection point will get pushed farther and farther away from the polygon, which can produce undesirable results. This can be solved by beveling the outline corner.

    Again though, if your polygons are regular n-gons or if you don't need that degree of accuracy, you can just use the 'edge normal averaging' method described previously.
     
  9. johot

    johot

    Joined:
    Apr 11, 2011
    Posts:
    201
    Thanks guys I made it! I worked from your sample Jesse, but im sure they would both yield the same result!

    Heres a sample image, blue lines are the edge normals and red the vertex normals. And the green is a sample outline! I'll see if I run in to more problems regarding angles and such later on!



    BTW: Why would I need to do some kind of averaging of the two normals I get from the edge to the left and right of the vertex? I only added the normals of those edges and then normalized to get the vertex normal. Correct?
     
    Last edited: Apr 19, 2011
  10. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    You got it right. This:

    And this:

    Are effectively the same thing. Conceptually it's a normalized average, but in practice, this:

    Code (csharp):
    1. vertex_normal = normalize((normal_1 + normal_2) / 2);
    And this:

    Code (csharp):
    1. vertex_normal = normalize(normal_1 + normal_2);
    Will produce equivalent results, so you can skip the division by 2 (as you're doing already).