Smoothing a two-dimensional shape

I have some vaguely rectangular 2D shapes that need to be smoothed out. A simplified example:

fig, ax1 = plt.subplots(1,1, figsize=(3,3))
xs1 = [-0.25,  -0.625, -0.125, -1.25, -1.125, -1.25, 0.875, 1.0, 1.0, 0.5, 1.0, 0.625, -0.25]
ys1 = [1.25, 1.375, 1.5, 1.625, 1.75, 1.875, 1.875, 1.75, 1.625, 1.5, 1.375, 1.25, 1.25]

ax1.plot(xs1, ys1)
ax1.set_ylim(0.5,2.5)
ax1.set_xlim(-2,2) ;

enter image description hereenter image description here

I tried scipy.interpolate.RectBivariateSpline, but apparently it wants to receive data at all points (for example, for a heat map) and scipy.interpolate.interp1d, but it is smart enough to generate a 1d smoothed version.

What is the appropriate way to smooth this out?

Modify to slightly modify / explain my purpose. I do not need lines to go through all the points; in fact, I would prefer that they did not go through all the points, because there are obvious exit points that "should" be averaged with neighbors or some kind of similar approach. I included a rough hand sketch of the beginning of what I mean above.

+4
3

. P0, P1,... P (N-1) , P (i) P (i + 1),

Q (i) = (3/4) P (i) + (1/4) P (i + 1)
R (i) = (1/4) P (i) + (3/4) P (i + 1)

, 2N . , . , . , , , B-. , . (, )


Original polygon


Apply corner cutting once



enter image description here

. .

+9

, scipy.interpolate.inter1d. x, y .

:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

x = [0, 1, 1, 0, 0]
y = [0, 0, 1, 1, 0]

t = np.arange(len(x))
ti = np.linspace(0, t.max(), 10 * t.size)

xi = interp1d(t, x, kind='cubic')(ti)
yi = interp1d(t, y, kind='cubic')(ti)

fig, ax = plt.subplots()
ax.plot(xi, yi)
ax.plot(x, y)
ax.margins(0.05)
plt.show()

enter image description here

, , 0,0.

, . "" , . "" x y , "" .

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

x = [0, 1, 1, 0, 0]
y = [0, 0, 1, 1, 0]

# Pad the x and y series so it "wraps around".
# Note that if x and y are numpy arrays, you'll need to
# use np.r_ or np.concatenate instead of addition!
orig_len = len(x)
x = x[-3:-1] + x + x[1:3]
y = y[-3:-1] + y + y[1:3]

t = np.arange(len(x))
ti = np.linspace(2, orig_len + 1, 10 * orig_len)

xi = interp1d(t, x, kind='cubic')(ti)
yi = interp1d(t, y, kind='cubic')(ti)

fig, ax = plt.subplots()
ax.plot(xi, yi)
ax.plot(x, y)
ax.margins(0.05)
plt.show()

enter image description here

, :

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

x = [-0.25, -0.625, -0.125, -1.25, -1.125, -1.25,
     0.875, 1.0, 1.0, 0.5, 1.0, 0.625, -0.25]
y = [1.25, 1.375, 1.5, 1.625, 1.75, 1.875, 1.875,
     1.75, 1.625, 1.5, 1.375, 1.25, 1.25]

# Pad the x and y series so it "wraps around".
# Note that if x and y are numpy arrays, you'll need to
# use np.r_ or np.concatenate instead of addition!
orig_len = len(x)
x = x[-3:-1] + x + x[1:3]
y = y[-3:-1] + y + y[1:3]

t = np.arange(len(x))
ti = np.linspace(2, orig_len + 1, 10 * orig_len)

xi = interp1d(t, x, kind='cubic')(ti)
yi = interp1d(t, y, kind='cubic')(ti)

fig, ax = plt.subplots()
ax.plot(xi, yi)
ax.plot(x, y)
ax.margins(0.05)
plt.show()

enter image description here

, "" . . @pythonstarter - , ( , , ). , , (, (PAEK)). PAEK, , . , PAEK .

+6

, , , , . , , , . . : -, " " , ; , . , , , , ,

+3

Source: https://habr.com/ru/post/1568926/


All Articles