Search code examples
pythongeometry2dresampling

Python - How to resample a 2D shape?


I am writing a python script for some geometrical data manipulation (calculating motion trajectories for a multi-drive industrial machine). Generally, the idea is that there is a given shape (let's say - an ellipse, but it general case it can be any convex shape, defined with a series of 2D points), which is rotated and it's uppermost tangent point must be followed. I don't have a problem with the latter part but I need a little hint with the 2D shape preparation.

Let's say that the ellipse was defined with too little points, for example - 25. (As I said, ultimately this can be any shape, for example a rounded hexagon). To maintain necessary precision I need far more points (let's say - 1000), preferably equally distributed over whole shape or with higher density of points near corners, sharp curves, etc.

I have a few things ringing in my head, I guess that DFT (FFT) would be a good starting point for this resampling, analyzing the scipy.signal.resample() I have found out that there are far more functions in the scipy.signal package which sound promising to me...

What I'm asking for is a suggestion which way I should follow, what tool I should try for this job, which may be the most suitable. Maybe there is a tool meant exactly for what I'm looking for or maybe I'm overthinking this and one of the implementations of FFT like resample() will work just fine (of course, after some adjustments at the starting and ending point of the shape to make sure it's closing without issues)?

Scipy.signal sounds promising, however, as far as I understand, it is meant to work with time series data, not geometrical data - I guess this may cause some problems as my data isn't a function (in a mathematical understanding).

Thanks and best regards!


Solution

  • As far as I understood, what you want is to get an interpolated version of your original data.

    The DFT (or FFT) will not achieve this purpose, since it will perform a Fourier Transform (which is not what you want).

    Talking theoretically, what you need to interpolate your data is to define a function to calculate the result in the new-data-points.

    So, let's say your data contains 5 points, in which one you have a 1D (to simplify) number stored, representing your data, and you want a new array with 10 points, filled with the linear-interpolation of your original data.

    Using numpy.interp:

    import numpy as np
    original_data = [2, 0, 3, 5, 1] # define your data in 1D
    new_data_resolution = 0.5 # define new sampling distance (i.e, your x-axis resolution)
    interp_data = np.interp(
        x = np.arange(0, 5-1+new_data_resolution , new_data_resolution), # new sampling points (new axis)
        xp = range(original_data),
        fp = original_data
    )
    # now interp_data contains (5-1) / 0.5 + 1 = 9 points
    

    After this, you will have a (5-1) / new_resolution (which is greater than 5, since new_resolution < 1)-length data, whose values will be (in this case) a linear interpolation of your original data.

    After you have achieved/understood this example, you can dive in the scipy.interpolate module to get a better understanding in the interpolation functions (my example uses a linear function to get the data in the missing points).

    Applying this to n-D dimensional arrays is straight-forward, iterating over each dimension of your data.