Difference between revisions of "User:Caron/memo"

From Custom Mario Kart
Jump to navigation Jump to search
m
Line 121: Line 121:
 
<b>二等分線</b>...非凸の頂点と隣の2点から二等分線を求める<br>
 
<b>二等分線</b>...非凸の頂点と隣の2点から二等分線を求める<br>
 
<b>移動距離</b>...これが問題、素直に100ずつ移動させるか、一気に移動させる方法がないか模索中。
 
<b>移動距離</b>...これが問題、素直に100ずつ移動させるか、一気に移動させる方法がないか模索中。
 +
 +
== Internal nodes ==
 +
<b>チェックポイントのパス構造には内部ノードは存在してはいけない</b>(自身のコース製作で経験済み)。CPUとアイテムルートは別にパス関係が木構造になっていてもok.

Revision as of 05:11, 19 June 2021

Graphviz

import graphviz # type: ignore

dgraph = graphviz.Digraph(**kwargs)
for i, _ in enumerate(self._data):
    dgraph.node(self._gn(i))
for i, _data in enumerate(self._data):
    label = str(_data[1]-_data[0])
    for nxt in np.unique(_data[8:14])[:-1]: # 255は除外
        dgraph.edge(self._gn(i), self._gn(nxt), label=label)

if render:
    dgraph.render(view=view)
elif view:
    dgraph.view()


Smoothing:Catmull–Clark

faceは不要なのでCatmull-clarkの途中処理まで
not tested yet


counts = round(counts) if isinstance(counts, float) else counts
for _ in range(counts):
    data_size = len(target)
    smoothed = create_new_data(self._sectionname, 2, 2*data_size-1)

    smoothed[::2,:] = target # type: ignore

    # Center position
    smoothed[1::2,0:3] = ((target[:-1,0:3] + target[1:,0:3])/2)
    # Average((cur + center_1 + center_2)/3)
    smoothed[2:-2:2,0:3] = (smoothed[1:-2:2,0:3] + smoothed[3::2,0:3] + smoothed[2:-2:2,0:3])/3

    # update settings
    smoothed = update_settings(
        iter = range(1, len(smoothed)-1),
        old_array=target,
        new_array=smoothed
        )

    # clone array for next iteration.
    target = smoothed.copy()


Smoothing:Spline interpolation

こっちの方が元の曲線に近くフィットしてくれる
not tested yet


pos = target[:, :3].T
m = len(pos[0])

# create knots vector
tck, _ = interpolate.splprep(pos, s=m+np.sqrt(m), k=4)
u_counts = np.linspace(0,1,round(m*counts))

# fitting
fitted = np.vstack(interpolate.splev(u_counts, tck)).T

### update settings: start
data_size = len(fitted)
update_idx = np.zeros([0]*data_size)
# find nearest positions
for idx in range(m):
    old_vec = np.tile(pos.T[idx], (data_size, 1))
    norm = np.linalg.norm(old_vec - fitted, axis=-1)
    update_idx[idx] = np.argmin(norm)
smoothed = create_new_data(self._sectionname, 2, data_size)
smoothed[:,:3] = fitted
# POTI Setting is start at target[3:], but ENPT, ITPT are target[4:].
start = 4 if self._sectionname != 'POTI' else 3 
smoothed[update_idx,start:] = target[:,start:]
smoothed = update_settings(
    iter=range(1, m),
    old_array=target,
    new_array=smoothed,
    spline_index=update_idx
)


Convex Quadrilaterals or not

Caron is cq.jpg
緑の角度の総和が2πになればよい。

def is_convex(pt1: np.ndarray, pt2: np.ndarray) -> bool:
    pos = np.vstack([pt1.reshape(2,2), pt2.reshape(2,2)[::-1]])
    flat = pos.flatten()
    if flat.shape[0] != np.unique(flat).shape[0]:
        return False

    # vector
    pos = pos - np.roll(pos, 2)
    # concatnate
    pos = np.hstack([pos, np.roll(pos, 2)])
    # \vec{A} \bullet \vec{B}
    _inner = np.apply_along_axis(
        lambda x: np.inner(x[:2], x[2:4]), 1, pos)
    # |\vec{A}| \cdot |\vec{B}|
    _len = np.apply_along_axis(
        lambda x: np.linalg.norm(x[:2])*np.linalg.norm(x[2:4]), 1, pos)
    # \sum_i \frac{\vec{A_i} \bullet \vec{B_i}}{|\vec{A_i}| \cdot |\vec{B_i}|}
    if round(abs(np.sum(_inner/_len)*360/np.pi)) != 0:
        return True
    return False


Fix Non-convex Quadrilaterals

これでいけそう
Caron cq f image.png

非凸の頂点...簡単。反時計回りで行くなら時計回りになっている点を見つければそれが非凸の頂点。
二等分線...非凸の頂点と隣の2点から二等分線を求める
移動距離...これが問題、素直に100ずつ移動させるか、一気に移動させる方法がないか模索中。

Internal nodes

チェックポイントのパス構造には内部ノードは存在してはいけない(自身のコース製作で経験済み)。CPUとアイテムルートは別にパス関係が木構造になっていてもok.