Maulik Lathiya
Maulik Lathiya

Reputation: 173

Get points x distance inside a polygon

I can't figure out a way to do this. I have a list of vector2 points and I need all the points which are inside that polygon with a x distance.

So I have a List of Green points and looking for a List of Red points that have a x distance from respective green points.

enter image description here

I am thinking of getting 2 imaginary points, 1 unity towards the previous and next point. Then moving towards the center of that 2 points by x distance. But then if the inter angle is not 90 then it will move outside of the polygon.

Vector2 me = point; // point
Vector2 next = n_point; // on left
Vector2 previous = p_point; // on right
//Debug.DrawLine(me, (me - next), Color.green);
// 2 points ep1 & ep2 
Vector2 center = Vector2.Lerp(ep1,ep2, 0.5f); 
Vector2 finalpoint = Vector2.Lerp(me,center,0.1f); //move towards center

enter image description here

I think I am overthinking this. Is there a super-easy way to do this?

Upvotes: 0

Views: 316

Answers (2)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112392

Assuming that all the edges are either horizontal or vertical I would simply consider each possible case separately.

Get the direction vectors.

Vector2 from = me - previous;
Vector2 to = next - me;

I also assume that there is always a turn. I.e., if from is horizontal, then to is vertical and vice versa. Either x or y is 0.0f and the other coordinate is not zero. I also assume that the x-axis points to the right and the y-axis upwards. Assuming points are listed clock-wise.

float x, y;
if (from.x > 0.0f) { // from points to the right
    y = me.y - distance;
    if (to.y > 0.0f) x = me.x + distance else x = me.x - distance;
} else if (from.x < 0.0f) { // from points to the left
    y = me.y + distance;
    if (to.y > 0.0f) x = me.x + distance else x = me.x - distance;
} else if (from.y > 0.0f) { // from points upwards
    x = me.x + distance;
    if (to.x > 0.0f) y = me.y - distance else y = me.y + distance;
} else { // from.y < 0.0f, points downwards
    x = me.x - distance;
    if (to.x > 0.0f) y = me.y - distance else y = me.y + distance;
}
Vector2 me_inner = new Vector2(x, y);

I hope I got all the signs right.

Upvotes: 1

JonasH
JonasH

Reputation: 36371

There are two methods that spring to mind

Option1:

  1. For each line define a normal, i.e. a perpendicular line pointing outward
  2. Define a normal for each vertex as the average of the normals of the lines the vertex is part of.
  3. Move the vertex X units along the normal.

This is fairly easy to implement, but may have problems with self-intersection for some kinds of geometry.

Option2:

  1. For each line define a normal, i.e. a perpendicular line pointing outward
  2. Move each line-segment X Units along the normal.
  3. for each sequential pair of line segments determine if:
  4. the two line segments intersect, if so, use the intersection point as the vertex. i.e. add the intersection point into your point-list.
  5. If they do not intersect, insert a new line segment between the start and end point of the lines. i.e. Insert both start and end vertex to your point-list.

This should handle self-intersection better, but there might still be problem-cases. And it a bit more cumbersome to implement. It somewhat depend on how exact you need the new line positioned, and well it should handle different kinds of geometry.

Upvotes: 0

Related Questions