LoginSignup
3
4

More than 5 years have passed since last update.

Python+Scipyでランダムに作成した点から凸包を描く

Posted at

久しぶりに小ネタ。

やること

  • 適当に2次元に点群を取得する
  • 点群から凸包を計算する
  • 点群と凸包をmatplotlibで描画する

ソース

# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import scipy.spatial as ssp


def point_in_hull(point, hull, tolerance=1e-6):
  return all(
    (np.dot(eq[:-1], point) + eq[-1] <= tolerance)
    for eq in hull.equations)


def main():
  N = 100
  points = np.random.rand(N, 2)
  idx_bases = np.random.choice(range(N), 5, replace=False)
  bases = points[idx_bases, :]

  # hull
  hull = ssp.ConvexHull(bases)
  idx = [i for i in range(N) if point_in_hull(points[i, :], hull)]

  # vis
  fig = plt.figure(figsize=(5, 5))
  ax = fig.gca()
  ax.scatter(points[:, 0], points[:, 1], c='r', marker='o')
  ax.scatter(bases[:, 0], bases[:, 1], c='b', marker='o')

  # in hull vertex and borders
  pidx = points[idx, :]
  ax.scatter(pidx[:, 0], pidx[:, 1], c='c', marker='x')
  for simplex in hull.simplices:
    plt.plot(bases[simplex, 0], bases[simplex, 1], "k--")

  ax.axis("off")
  ax.margins(x=0.015, y=0.015)
  ax.set_position([0.05, 0.05, 0.9, 0.9])
  plt.show()
  plt.close()


if __name__ == '__main__':
  main()

実行例

example.png

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4