3
$\begingroup$

I wish to create a larger polygon from a smaller one through orthogonally translating each edge by a fixed distance. RegionResize with a bounding box given by RegionBounds works when my polygon is a box:

p1 = Polygon[{{0, 0}, {0, 1}, {1, 1}, {1, 0}}];

dist = .3;
b = {#[[1]] - dist, #[[2]] + dist} & /@ RegionBounds[p1];

p2 = RegionResize[p1, b];

Below, the red square is p1 and the dashed edges border p2 composed of edges each a distance dist from their corresponding ones in p1.

enter image description here

But when my input polygon is not a box, this method does not work:

p1 = Polygon[{{0, 0}, {0, .7}, {1, 1}, {1, 0}}];
b = {#[[1]] - dist, #[[2]] + dist} & /@ RegionBounds[p1];
p2 = RegionResize[p1, b];

enter image description here

Notice the top edges of p1 and p2 are closer than dist from one-another.

My polygons are in general quite complicated. Naturally I can compute the corner coordinates of the expanded polygon myself geometrically but it is irksome to do so when existing functions do so close to what I need.

In words, I wish to obtain a polygon as described by this process:

  • translate each edge in p2 a distance dist along an orthogonal line, away from the polygon area.
  • extend each edge until it intersects with its neighbouring edges.
  • return the polygon whose vertices are the ordered list of these coordinates of intersection.

Is there an elegant paradigmatic way to do this in Mathematica, e.g. using the derived regions functions?

$\endgroup$
3
  • 1
    $\begingroup$ This question / answer may be useful mathematica.stackexchange.com/a/211888/22158 $\endgroup$
    – LouisB
    Commented Oct 28, 2022 at 5:33
  • $\begingroup$ @LouisB indeed my question is a duplicate and you've already solved it, thanks! $\endgroup$
    – Anti Earth
    Commented Oct 31, 2022 at 18:41
  • $\begingroup$ @bbgodfrey that's the question LouisB linked in the comment above, and that cited in the close vote I started (to mark this question as duplicate) $\endgroup$
    – Anti Earth
    Commented Oct 31, 2022 at 20:53

1 Answer 1

1
$\begingroup$

Would it be sufficient to scale it from the centroid?

factor = 1.1;
center = RegionCentroid[p1];
ScalingTransform[{factor, factor}, c][p1]

There is also RegionDilation:

RegionDilation[p1, (ScalingTransform[{.1, .1}] @* TranslationTransform[-c])[p1]]

I chose the .1 scale (i.e. the amount of dilation) arbitrarily.

Update

I thought I should explain and provide a caveat. RegionDilation is basically doing a Minkowski sum. If you do this with a disk, you get a uniform "border" added to your region. The problem with that is that you won't have the sharp corners that you wanted. So, I just used a region that was the same shape as your original. My thinking was that similarity would give us back those corners. But on second thought, I don't think it gives us that uniform border. You might be stuck doing the algebra.

Or maybe you can translate each edge by the desired amount, use them to create infinite lines (InfiniteLine) that you can then intersect pairwise. That'll give you the new corners.

$\endgroup$
2
  • $\begingroup$ It's not sufficient to scale since I do not a priori know the scale factor nor the length (in whatever measure) of the original polygon. How would you determine factor from dist? $\endgroup$
    – Anti Earth
    Commented Oct 31, 2022 at 18:40
  • $\begingroup$ Well, the infinte line solution is the better way to go anyway, but since you asked, you have all of the vertices, and therefore sides, and so determining a scale from the offset would not be difficult. $\endgroup$
    – lericr
    Commented Oct 31, 2022 at 18:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.