我有一個連接點的串列。
我想沿著自己的路徑移動點/白色方塊,如下所示:

我喜歡有一個 numpy 版本,但我不確定這是否可能。
所以python方法也可以。
最終結果應該是一個新點串列。
uj5u.com熱心網友回復:
這里有一些讓你思考的東西。我定義了一組點。我計算了線段的長度和角度(請注意,這對于垂直線段會失敗)。然后我開始繪制原始線段和當前點的 matplotlib 影片。這對你來說還不夠,因為我不是在拐角處。這些點只是在同一個方向上繼續。留給讀者的練習?
import math
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# Define a set of points that make up a rough circle.
curve = np.array((
( 0, 0 ),
( 8, 2 ),
( 12, 7 ),
( 5, 11 ),
( -2, 13 ),
( -4, 8 ),
( -2, 4 ),
( 0, 0 )
))
# Cmpute angle and length of segment.
segments = []
for c in range(len(curve)-1):
delta = curve[c 1]-curve[c]
length = math.sqrt(delta[0]*delta[0] delta[1]*delta[1])
angle = math.atan2(delta[1], delta[0])
segments.append( (delta, length, angle) )
# Step 0.5 units per frame.
STEP = 0.5
def movePoint( pt, segment ):
# Move pt down the line between prv and nxt.
ptx = math.cos(segment[2]) * STEP
pty = math.sin(segment[2]) * STEP
return pt (ptx,pty)
def advance(points, curve):
newpts = []
for i in range(len(curve)-1):
newpts.append( movePoint( points[i], segments[i]) )
return np.array(newpts)
fig, ax = plt.subplots()
plt.plot( curve[:,0], curve[:,1] )
def init():
global points
global ln
points = curve.copy()
ln = plt.scatter( points[:,0], points[:,1] )
return ln,
def update(frame):
global points
points = advance(points, curve)
ln.set_offsets( points )
return ln,
ani = FuncAnimation( fig, update, frames=12, init_func=init, blit=True )
plt.show()
uj5u.com熱心網友回復:
from typing import List
import numpy as np
class _LineSegment:
def __init__(self, v1: np.ndarray, v2: np.ndarray) -> None:
"""Helper representation of a line segment. Makes use of PolygonialPath's
data integrity (i.e. no further range checks) and implements handling
of v1 == v2 case.
"""
self.v1 = v1
self.v2 = v2
v_delta = v2 - v1
self.length = np.linalg.norm(v_delta)
self.direction = v_delta / self.length if self.length else v_delta
class PolygonalChain:
def __init__(self, vertices: List[np.ndarray]) -> None:
if len(vertices) < 2:
raise ValueError("Trivial polygonial paths not supported!")
v_shape = vertices[0].shape
if len(v_shape) != 1:
raise ValueError("Vertices have to be represented as vectors!")
if any(v.shape != v_shape for v in vertices):
raise ValueError("Vertices have to be of consistent length!")
self._vertices = vertices
self._vertices_arclen = [0]
self._strict_vertices_arclen = [0]
self._strict_segments = []
v_prev = self._vertices[0]
for v_next in vertices[1:]:
segment = _LineSegment(v_prev, v_next)
self._vertices_arclen.append(self._vertices_arclen[-1] segment.length)
if segment.length:
self._strict_vertices_arclen.append(self._vertices_arclen[-1])
self._strict_segments.append(segment)
v_prev = v_next
if not self._strict_segments:
raise ValueError("Trivial polygonial paths not supported!")
# for convenience in `point_at`, set last value to inf (to handle
# extrapolation beyond last point)
self._strict_vertices_arclen[-1] = np.inf
def vertices_arclen(self) -> List[float]:
"""For each vertice, its arc-length along the path."""
return self._vertices_arclen
def point_at(self, arclen: float) -> np.ndarray:
"""Provide point corresponding to the arc-length. Extrapolation done by
first and last segment.
"""
# map to line segment (could be optimized by bi-section)
segment_idx = 0
while arclen > self._strict_vertices_arclen[segment_idx 1]:
segment_idx = 1
# compute point
segment = self._strict_segments[segment_idx]
arclen_on_segment = arclen - self._strict_vertices_arclen[segment_idx]
return segment.v1 arclen_on_segment * segment.direction
def example() -> None:
from matplotlib import pyplot as plt
# some data
pts = [
np.array((1, 2)),
np.array((1, 2)),
np.array((3, 5)),
np.array((4, 7)),
np.array((4, 8)),
np.array((3, 6)),
]
# polygonial chain representation
chain = PolygonalChain(pts)
pts_arclen = chain.vertices_arclen()
# apply some step
delta_arclen = -0.5
pts_shifted = [chain.point_at(p_arclen delta_arclen) for p_arclen in pts_arclen]
# plot
plt.plot([p[0] for p in pts], [p[1] for p in pts], "- k")
plt.plot([p[0] for p in pts_shifted], [p[1] for p in pts_shifted], "r*")
plt.show()
if __name__ == "__main__":
example()

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/334211.html
上一篇:Numpy陣列索引與另一個矩陣
