Решение сериализатора / десериализатора, указанное 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
}
}
Вы можете использовать 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()
Это даст вам нечто похожее на то, что вы просили:
Вы можете поиграть с параметрами splprep, чтобы изменить результат. Вы можете найти более подробную информацию в этой публикации StackOverflow .
См. алгоритм Чайкина .
Алгоритм Чайкина - это геометрические алгоритмы, которые работают с полигоном управления напрямую. Схема генерации кривой основана на «разрезании углов», когда алгоритм генерирует новый многоугольник управления, обрезая углы от исходного.
Рисунок ниже иллюстрирует эту идею, когда начальный контрольный многоугольник был преобразован во второй многоугольник (немного смещен) путем обрезания углов первой последовательности.
Вот пример реализации.
"""
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()
Приведенные выше ответы очень элегантны, но вот попытка «хакерского» решения, которое гораздо менее гладкое
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)