I was wondering whether there is an option in Mathematica that enables me to smooth the corners of a shape. The example I want to start with is the pentagon.
This can be crudely specified as
Graphics[
Polygon[
{{Sin[2π/5], Cos[2π/5]}, {Sin[4π/5], -Cos[π/5]},
{-Sin[4π/5], -Cos[Pi/5]}, {-Sin[2π/5], Cos[2π/5]},
{0, 1}}]
]
Unfortunately, I see no easy way that enables me to round the corners. What I am after is something that looks like this:
I would think Mathematica would have such a feature, but I can't seem to find anything. I'd be grateful if you could shine some light on this. Maybe this isn't as trivial as it seems.
Answer
UPDATE:
The previous version of my answer worked, but did not give control on the rounding radius, nor did it fully work with as a starting point for a geometric region for further calculations. Here is a version that is still based on spline curves, but it gives full control over the corner rounding radius. It also returns a FilledCurve
object that in my opinion is easier to style and can also be discretized reliably to use in further calculations.
Clear[splineRoundedNgon]
splineRoundedNgon[n_Integer /; n >= 3, roundingRadius_?(0 <= # <= 1 &)] :=
Module[{vertices, circleCenters, tangentPoints, splineControlPoints},
vertices = CirclePoints[n];
circleCenters = CirclePoints[1 - Sec[Pi/n] roundingRadius, n];
tangentPoints =
{
Table[RotationMatrix[2 i Pi/n].{circleCenters[[1, 1]], vertices[[1, 2]]}, {i, 0, n - 1}],
Table[RotationMatrix[2 i Pi/n].{circleCenters[[-1, 1]], vertices[[-1, 2]]}, {i, 1, n}]
};
splineControlPoints = Flatten[Transpose[Insert[tangentPoints, vertices, 2]], 1];
FilledCurve@BSplineCurve[splineControlPoints, SplineClosed -> True]
]
Here's the obligatory animation :-)
Animate[
Graphics[
{EdgeForm[{Thickness[0.01], Black}], FaceForm[Darker@Green],
splineRoundedNgon[5, radius]}
],
{{radius, 0, "Rounding\nradius"}, 0, 1}
]
And here is an example of a discretized region obtained from it:
DiscretizeGraphics[splineRoundedNgon[5, 0.3], MaxCellMeasure -> 0.001]
Such regions can be used e.g. as domains for plotting and in NDSolve
calculations. For instance:
Plot3D[
y Sin[5 x] + x Cos[7 y], {x, y} ∈ DiscretizeGraphics@splineRoundedNgon[5, 0.4]
]
You can also create a spline curve to get a bit more roundness in the corners than allowed by JoinedForm
. You need to double each control point in your spline definition to have the spline "hug" the points more closely. This is conveniently wrapped up in the roundRegPoly
helper function below:
Clear[roundRegPoly]
roundRegPoly[n_Integer /; n >= 3] :=
FilledCurve@BSplineCurve[
Flatten[#, 1] &@Transpose[{#, #}] &@CirclePoints[n],
SplineClosed -> True
]
Graphics[
{Darker@Green, EdgeForm[{Thickness[0.01], Black}], roundRegPoly[5]},
PlotRangePadding -> Scaled[.1]
]
Comments
Post a Comment