Vector s and e are two given points. The goal is to find the direction between this two points and draw a circle at the position of the first point.
My current approach looks like this:
import bpy
import mathutils
obj = bpy.data.objects["Plane"]
s = obj.data.vertices[0].co
e = obj.data.vertices[1].co
v = e-s
v = v.normalized()
mesh = bpy.data.meshes.new("test") # add the new mesh
obj = bpy.data.objects.new(mesh.name, mesh)
col = bpy.data.collections["Collection"]
col.objects.link(obj)
bpy.context.view_layer.objects.active = obj
verts = []
edges = []
faces = []
b_0 = mathutils.Vector((0.0000, 0.5000, 0.0000))
b_1 = mathutils.Vector((0.3909, 0.3117, 0.0000))
b_2 = mathutils.Vector((0.4875, -0.1113, 0.0000))
b_3 = mathutils.Vector((0.2169, -0.4505, 0.0000))
b_4 = mathutils.Vector((-0.2169, -0.4505, 0.0000))
b_5 = mathutils.Vector((-0.4875, -0.1113, 0.0000))
b_6 = mathutils.Vector((-0.3909, 0.3117, 0.0000))
v_0 = v.cross(b_0) s
v_1 = v.cross(b_1) s
v_2 = v.cross(b_2) s
v_3 = v.cross(b_3) s
v_4 = v.cross(b_4) s
v_5 = v.cross(b_5) s
v_6 = v.cross(b_6) s
verts.append(v_0)
verts.append(v_1)
verts.append(v_2)
verts.append(v_3)
verts.append(v_4)
verts.append(v_5)
verts.append(v_6)
faces.append([0, 1, 2, 3, 4, 5, 6])
mesh.from_pydata(verts, edges, faces)
When moving the two vectors, the scaling of the circle is wrong.
What could be a possible solution?
Based on the answer of ardget, this is a possible solution:
import bpy
import math
import mathutils
def circle(subdivision, r, start, end):
# get vector of translation
v = end-start
v = v.normalized()
# create mesh and object
mesh = bpy.data.meshes.new("test") # add the new mesh
obj = bpy.data.objects.new(mesh.name, mesh)
col = bpy.data.collections["Collection"]
col.objects.link(obj)
bpy.context.view_layer.objects.active = obj
verts = []
edges = []
faces = []
# create circle points with number of subdivision
for i in range(subdivision):
# based on approach by Apollo
# https://stackoverflow.com/questions/39402109/generating-points-on-a-circle
x = (math.cos(2*math.pi/subdivision*i)*r)
y = (math.sin(2*math.pi/subdivision*i)*r)
v_local = mathutils.Vector((x, y, 0))
# based on answer by ardget
# https://stackoverflow.com/questions/74709362/get-direction-of-two-points-and-draw-circle-at-first-point/74724559#74724559
axis = mathutils.Vector((0.0, 0.0, 1.0))
angle = v.angle(axis, 0.0)
mat_rot = mathutils.Matrix.Rotation(angle, 4, axis.cross(v))
mat_pos = mathutils.Matrix.Translation(start)
mat = mat_pos @ mat_rot
v_global = mat @ v_local
verts.append(v_global)
# append points to create face
face = []
for i in range(subdivision):
face.append(i)
faces.append(face)
mesh.from_pydata(verts, edges, faces)
obj = bpy.data.objects["Plane"]
start = obj.data.vertices[0].co
end = obj.data.vertices[1].co
circle(10, 1, start, end)
CodePudding user response:
You might need to use a plain rotation
to avoid distortion.
b_0 = mathutils.Vector((0.0000, 0.5000, 0.0000))
b_1 = mathutils.Vector((0.3909, 0.3117, 0.0000))
b_2 = mathutils.Vector((0.4875, -0.1113, 0.0000))
b_3 = mathutils.Vector((0.2169, -0.4505, 0.0000))
b_4 = mathutils.Vector((-0.2169, -0.4505, 0.0000))
b_5 = mathutils.Vector((-0.4875, -0.1113, 0.0000))
b_6 = mathutils.Vector((-0.3909, 0.3117, 0.0000))
axis = mathutils.Vector((0.0, 0.0, 1.0))
angle = v.angle(axis, 0.0)
mat_rot = mathutils.Matrix.Rotation(angle, 4, axis.cross(v))
mat_pos = mathutils.Matrix.Translation(s)
mat = mat_pos @ mat_rot
v_0 = mat @ b_0
v_1 = mat @ b_1
v_2 = mat @ b_2
v_3 = mat @ b_3
v_4 = mat @ b_4
v_5 = mat @ b_5
v_6 = mat @ b_6