I need to make a ellipse shape through some points. Is there anything in rhino that can do that similar to Circle: fit points.
Ellipse From Points.3dm (43.3 KB)
I need to make a ellipse shape through some points. Is there anything in rhino that can do that similar to Circle: fit points.
Ellipse From Points.3dm (43.3 KB)
Hi Tommy - none that I know of, no.
-Pascal
You could look into these old topics for ‘workarounds’:
Hi there,
This is a script for Rhino8 using Numpy, we could also use the MathNet.Numerics if we wanted it to be compatible with Rhino7.
To use it with Rhino7 you can make a py script that gets the data, stores it in a json file, and then runs this file that will read the json and perform the calculation. Hope It’s clear.
Script.py (the one to run on rhino)
import json
import rhinoscriptsyntax as rs
point_ids = rs.GetObjects("Select points", rs.filter.point)
if not point_ids:
print("No points were selected.")
else:
# Convert point IDs to XYZ coordinates
points = [rs.PointCoordinates(id) for id in point_ids]
points_data = [{'X': p[0], 'Y': p[1], 'Z': p[2]} for p in points]
file_path = rs.SaveFileName("Save JSON file as", "JSON Files (*.json)|*.json||")
if file_path:
with open(file_path, 'w') as file:
json.dump(points_data, file, indent=4)
ironpython_path = "path_to_your_ironpython_exe"
calculator_file = "path_to_calculator.py" # Specify the path to your calculator.py file
subprocess.run([ironpython_path, calculator_file])
Calculator.py
import json
import numpy as np
from numpy.linalg import eig, inv
with open(Points.json', 'r') as file:
points_data = json.load(file)
x = [p['X'] for p in points_data]
y = [p['Y'] for p in points_data]
def fit_ellipse(x, y):
x, y = np.array(x), np.array(y)
D = np.vstack([x**2, x*y, y**2, x, y, np.ones_like(x)]).T
S = np.dot(D.T, D)
C = np.zeros([6, 6])
C[0, 2] = C[2, 0] = 2; C[1, 1] = -1
E, V = eig(np.dot(inv(S), C))
n = np.argmax(E)
a = V[:, n]
return a
ellipse_params = fit_ellipse(x, y)
# conic equation Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0
# for ellipse, we need B^2 - 4AC < 0 (for a real ellipse)
A, B, C, D, E, F = ellipse_params
is_ellipse = B**2 - 4*A*C < 0
is_ellipse, ellipse_params.tolist()
This works with a really great degree of precision I am veru satified with the result.
It was an intresting problem, hope this helps
If you need help setting this up just hit me up.
@Tommy804
Since this wish comes up every now and then, I’ve logged it.
https://mcneel.myjetbrains.com/youtrack/issue/RH-78096
– Dale