File: fit_circle.py

package info (click to toggle)
vedo 2025.5.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,404 kB
  • sloc: python: 64,792; javascript: 1,932; xml: 437; sh: 139; makefile: 6
file content (34 lines) | stat: -rw-r--r-- 985 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"""Fit circles analytically to measure
the signed curvature of a line"""
from vedo import *

shape = Spline([
    [1.0, 2.0, -1.0],
    [1.5, 0.0,  0.4],
    [2.0, 4.0,  0.5],
    [4.0, 1.5, -0.3]],
    res=200,
)

n = 5  # nr. of points to use for the fit
npt = shape.npoints

points = shape.points
fitpts, circles, curvs = [], [], [0]*npt

for i in range(n, npt - n-1):
    pts = points[i-n:i+n]
    center, R, normal = fit_circle(pts)
    z = cross(pts[-1]-pts[0], center-pts[0])[2]
    curvs[i] = sqrt(1/R) * z/abs(z)
    if R < 0.75:
        circle = Circle(center, r=R).wireframe()
        circle.reorient([0,0,1], normal)
        circles.append(circle)
        fitpts.append(center)

shape.lw(8).cmap('coolwarm', curvs).add_scalarbar3d(title=':pm1/:sqrtR', c='w')
# use this trick to make the scalarbar3d become a 2d screen object:
shape.scalarbar = shape.scalarbar.clone2d("bottom-right", 0.2)

show(shape, circles, Points(fitpts, c='white'), __doc__, axes=1, bg='bb').close()