figure 1. shows circle obtain from 3 verts minimum.
The following code is the least bit of code you need to get the circle center from 3 verts using trig.
Missing convenience for semi high precision modelling
Periodically I miss the most elementary CAD features in Blender. While Blender is not designed for ultra high precision modeling, there's still room for precision before resorting to simply "eye-balling" it. Core developers are busy making Blender awesome in other ways, so instead of sidetracking them I like to experiment and learn how to make these tools myself. Whatever, I just need this stuff and don't want to wait.Additions to tinyCAD
Blender doesn't keep track of origins / centers of its primitives. For circles, let's not beat around the bush, this is highly annoying. Once you edit or move a circle mesh you lose the ability to change its parameters. Often I need to find the center of a circle after some of its vertices have been deleted. If you still have 3 points, the origin can be found easily using trigonometry. I'll add this to the tinyCAD. My implementation will work on either selecting two adjacent edges, or 3 vertices (not necessarily adjacent)edit
This is now added to the github version as 'Circle Centers', prior to updating the addons/contrib version.The following code is the least bit of code you need to get the circle center from 3 verts using trig.
import bpy
import bmesh
import math
import mathutils
from mathutils import geometry
from mathutils import Vector
def generate_3PT_mode_1(pts=[]):
verts, edges = [], []
V = Vector
# construction
v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
edge1_mid = v1.lerp(v2, 0.5)
edge2_mid = v3.lerp(v4, 0.5)
axis = geometry.normal(v1, v2, v4)
mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)
# triangle edges
v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid
r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
if r:
# for general use this requires: matrix_local * p1
p1, _ = r
bpy.context.scene.cursor_location = p1
else:
print('not on a circle')
return verts, edges
def get_three_verts_from_selection(obj):
me = obj.data
bm = bmesh.from_edit_mesh(me)
if hasattr(bm.verts, "ensure_lookup_table"):
bm.verts.ensure_lookup_table()
bm.edges.ensure_lookup_table()
return [v.co[:] for v in bm.verts if v.select]
obj = bpy.context.object
pts = get_three_verts_from_selection(obj)
generate_3PT_mode_1(pts)