Как сгладить обводку, учитывая некоторые координаты (x, y) обводки по порядку?

Решение сериализатора / десериализатора, указанное xbakesx, является превосходным, если вы хотите полностью разделить класс enor enum из его представления JSON.

Альтернативно, если вы предпочитаете автономное решение, реализация основанные на @JsonCreator и @JsonValue, были бы более удобными.

Таким образом, используя пример Стэнли, это полное автономное решение (Java 6, Jackson 1.9):

public enum DeviceScheduleFormat {
    Weekday,
    EvenOdd,
    Interval;

    private static Map<String, DeviceScheduleFormat> namesMap = new HashMap<String, DeviceScheduleFormat>(3);

    static {
        namesMap.put("weekday", Weekday);
        namesMap.put("even-odd", EvenOdd);
        namesMap.put("interval", Interval);
    }

    @JsonCreator
    public static DeviceScheduleFormat forValue(String value) {
        return namesMap.get(StringUtils.lowerCase(value));
    }

    @JsonValue
    public String toValue() {
        for (Entry<String, DeviceScheduleFormat> entry : namesMap.entrySet()) {
            if (entry.getValue() == this)
                return entry.getKey();
        }

        return null; // or fail
    }
}
1
задан Reblochon Masque 22 February 2019 в 02:16
поделиться

3 ответа

Вы можете использовать B-spline (splprep и splev) из scipy.interpolate:

import numpy as np
from scipy.interpolate import splprep, splev
import matplotlib.pyplot as plt

X = np.array([1, 3, 6, 8, 5])
Y = np.array([1, 8, 4, 4, 1])
pts = np.vstack((X, Y))
# Find the B-spline representation of an N-dimensional curve
tck, u = splprep(pts, s=0.0)
u_new = np.linspace(u.min(), u.max(), 1000)
# Evaluate a B-spline
x_new, y_new = splev(u_new, tck)

plt.plot(x_new, y_new, 'b--')
plt.show()

Это даст вам нечто похожее на то, что вы просили:

[113 ] enter image description here

Вы можете поиграть с параметрами splprep, чтобы изменить результат. Вы можете найти более подробную информацию в этой публикации StackOverflow .

0
ответ дан Noam Peled 22 February 2019 в 02:16
поделиться

См. алгоритм Чайкина .

Алгоритм Чайкина - это геометрические алгоритмы, которые работают с полигоном управления напрямую. Схема генерации кривой основана на «разрезании углов», когда алгоритм генерирует новый многоугольник управления, обрезая углы от исходного.
Рисунок ниже иллюстрирует эту идею, когда начальный контрольный многоугольник был преобразован во второй многоугольник (немного смещен) путем обрезания углов первой последовательности.

enter image description here

Вот пример реализации.

"""
polygoninterpolation.py
Chaikin's Algorith for curves
http://graphics.cs.ucdavis.edu/~joy/GeometricModelingLectures/Unit-7-Notes/Chaikins-Algorithm.pdf
"""
import math
import random
from graphics import *


class MultiLine:

    def __init__(self, points=None, rgb_color=(255, 255, 255), width=1):
        self.lines = []
        if points is None:
            self.points = []
        else:
            self.points = points
            self._build_lines()
        self.rgb_color = rgb_color
        self.width = width

    def add_point(self):
        self.points.append(point)

    def _build_lines(self):
        for idx, point in enumerate(self.points[:-1]):
            self.lines.append(Line(self.points[idx], self.points[idx + 1]))

    def draw(self, win):
        for line in self.lines:
            line.setOutline(color_rgb(*self.rgb_color))
            line.setWidth(self.width)
            line.draw(win)


def get_chaikin(points, factor=4):
    new_points = []   # [points[0]]
    for idx in range(len(points) - 1):
        p1, p2 = points[idx], points[idx+1]
        p_one_qtr, p_three_qtr = get_quarter_points(p1, p2, factor)
        new_points.append(p_one_qtr)
        new_points.append(p_three_qtr)
    return new_points   # + [points[-1]]  # for a closed polygon


def get_quarter_points(p1, p2, factor=4):
    n = factor
    qtr_x = (p2.x - p1.x) / n
    qtr_y = (p2.y - p1.y) / n
    return Point(p1.x + qtr_x, p1.y + qtr_y), \
           Point(p1.x + (n-1) * qtr_x, p1.y + (n-1) * qtr_y)


win = GraphWin("My Window", 500, 500)
win.setBackground(color_rgb(0, 0, 0))


# points0 = [Point(250, 20),
#            Point(20, 400),
#            Point(480, 400)]

# points0 = [Point(20, 400),
#            Point(35, 200),
#            Point(250, 100),
#            Point(400, 150),
#            Point(450, 350),
#            Point(380, 450)]

# points0 = [Point(20, 400),
#            Point(35, 200),
#            Point(250, 100),
#            Point(400, 150),
#            Point(220, 170),
#            Point(310, 190),
#            Point(180, 270),
#            Point(450, 230),
#            Point(440, 440),
#            Point(380, 450)]

points0 = [Point(random.randrange(500), random.randrange(500)) for _ in range(random.randrange(3, 80))]

x_line0 = MultiLine(points0)
# x_line0.draw(win)

points1 = get_chaikin(points0)
x_line1 = MultiLine(points1, rgb_color=(200, 200, 200), width=1)
# x_line1.draw(win)

points2 = get_chaikin(points1)
x_line2 = MultiLine(points2, rgb_color=(200, 200, 200), width=1)
# x_line2.draw(win)

points3 = get_chaikin(points2)
x_line3 = MultiLine(points3, rgb_color=(200, 200, 200), width=1)
# x_line3.draw(win)

points4 = get_chaikin(points3)
x_line4 = MultiLine(points4, rgb_color=(200, 200, 200), width=1)
# x_line4.draw(win)

points5 = get_chaikin(points4)
x_line5 = MultiLine(points5, rgb_color=(200, 200, 200), width=1)
x_line5.draw(win)


# poly0 = Polygon(points0)
# poly0.setOutline(color_rgb(0, 255, 0))
# poly0.setWidth(1)
# poly0.draw(win)
#
# points1 = get_chaikin(points0 + [points0[0]])
# poly1 = Polygon(points1)
# poly1.setOutline(color_rgb(0, 255, 0))
# poly1.setWidth(1)
# poly1.draw(win)
#
# points2 = get_chaikin(points1 + [points1[0]])
# poly2 = Polygon(points2)
# poly2.setOutline(color_rgb(0, 255, 0))
# poly2.setWidth(1)
# poly2.draw(win)
#
# points3 = get_chaikin(points2 + [points2[0]])
# poly3 = Polygon(points3)
# poly3.setOutline(color_rgb(0, 255, 0))
# poly3.setWidth(1)
# poly3.draw(win)
#
# points4 = get_chaikin(points3 + [points3[0]])
# poly4 = Polygon(points4)
# poly4.setOutline(color_rgb(0, 255, 0))
# poly4.setWidth(1)
# poly4.draw(win)
#
# points5 = get_chaikin(points4 + [points4[0]])
# poly5 = Polygon(points5)
# poly5.setOutline(color_rgb(0, 255, 0))
# poly5.setWidth(2)
# poly5.draw(win)


print("done")


print(win.getMouse())
win.close()
0
ответ дан Reblochon Masque 22 February 2019 в 02:16
поделиться

Приведенные выше ответы очень элегантны, но вот попытка «хакерского» решения, которое гораздо менее гладкое

X_new = []
Y_new = []
for i in range(4):
    line1 = [X[i],Y[i]] + np.expand_dims(np.linspace(0,1,10),-1)*np.array([X[i+1] - X[i], Y[i+1] - Y[i]])

    line_normal = [- Y[i+1] + Y[i], X[i+1] - X[i]]
    line_normal = line_normal/np.sqrt(np.dot(line_normal, line_normal))

    line1_noisy = line1 + line_normal * 0.2*(np.random.rand(10,1) - 0.5)
    X_new.append(line1_noisy[:,0])
    Y_new.append(line1_noisy[:,1])
X_new = np.stack(X_new).reshape(-1)
Y_new = np.stack(Y_new).reshape(-1)
plt.plot(X_new, Y_new)

enter image description here

0
ответ дан orli 22 February 2019 в 02:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: