0

I'm here again to hopefully draw on somebody's wisdom.

My scripts function is as follows: On a different part of the script, a user determines a point on a Bezier circle or ellipse, denoted by a x,y coordinate. The Beziers centre is always 0,0, but can change in scale. I wish to find the tangent angle of the point given by the user, but the angle to the world (x or y axis) to be able to rotate another plane or flat object to lay on the Bezier. Now I know I can curve an object to a bezier, but I want to have the object not to deform with the curve.

So, trying to remember back to my school days, I've produced the following script to do such a thing,

  1. finding the 2 foci of the ellipse
  2. working out a triangle from said foci to the user defined point
  3. using trig to find the cosine of the angle of the triangle adjacent to the bezier ellipse
  4. creating a 2nd triangle with a right angle to the x axis to produce a 2nd angle to adjust the first
    import bpy
    import math
#Variables
base_size_x = 20
base_size_y = 12
loc_x = 6
loc_y = 4.8 

#Draw Ellipse
#bpy.ops.curve.primitive_bezier_circle_add(enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
#bpy.context.object.scale[0] = base_size_x*.5
#bpy.context.object.scale[1] = base_size_y*.5

#Math focal points
focal = math.sqrt(((base_size_x*.5) ** 2) - ((base_size_y*.5) ** 2))
loc_x_with_focal = loc_x+focal

#Work triangle sides  -  c a b clockwise
c = math.hypot(loc_x_with_focal,loc_y)
a = base_size_x-c
b = focal*2

#Work triangle angles   -   A B C clockwise
A_cos = round(math.acos(((b**2)+(c**2)-(a**2))/(2*(b*c))),2)
B_cos = round(math.acos(((a**2)+(c**2)-(b**2))/(2*(a*c))),2)
C_cos = round(math.acos(((a**2)+(b**2)-(c**2))/(2*(a*b))),2)

#Triangle to get angle from world x  
b_opp = loc_y #b
a_adj = focal - loc_x #a
c_hyp = math.hypot(b_opp,a_adj) #c

#Work triangle angles
A2_cos = round(math.acos(((b_opp**2)+(c_hyp**2)-(a_adj**2))/(2*(b_opp*c_hyp))),2)
B2_cos = round(math.acos(((a_adj**2)+(c_hyp**2)-(b_opp**2))/(2*(a_adj*c_hyp))),2)
C2_cos = round(math.acos(((a_adj**2)+(b_opp**2)-(c_hyp**2))/(2*(a_adj*b_opp))),2)

#Draw plane to check angle along tangent
angle = (-B2_cos-(B_cos*.5))-math.radians(90)
bpy.ops.mesh.primitive_plane_add(size=5, enter_editmode=False, align='WORLD', location=(loc_x, loc_y, 0), scale=(1, 1, 1))
bpy.ops.transform.rotate(value=1.5708, orient_axis='X', orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False), mirror=True, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
bpy.context.object.rotation_euler[2] = angle

So my question, if I may. Is there a shorter or a more refined approach to this script (I apologise on the crude code, I tend to just bash things together until they work), is there a built in math function that I'm obviously overlooking... Or does the "not broken don't fix it" apply here as the code is doing (so far) what is expected.

Kev Thomas
  • 23
  • 7
  • 1
    I got intimidated by your script, perhaps I'm missing something, but if you have a point on a circle with x:0, y:0 center, this point's coordinates are also a vector from center to that point, which rotated by 90° around Z should give you a tangent? Also... "Now I know I can curve an object to a bezier, but I want to have the object not to deform with the curve" - How do I prevent object distortion when applying a curve modifier? – Markus von Broady Aug 25 '21 at 22:35
  • @MarkusvonBroady - your correct regarding circles, unfortunately, when you start to work with ellipses, that all kinda goes out of the window. Thankyou for the link, I did stumble across this link a little while ago about half way through playing with this script, I will try to add the bone constraint method as this seems to work in the manner I'm looking for, although it still gives a deformity in the object (not as strong). I cannot get the other method to work without having a copy of the object I wish to rotate on the x-axis visible. – Kev Thomas Aug 25 '21 at 23:44
  • Further working with one of the solutions via the link provided from @MarkusvonBroady has provided me insight to a more simple solution without the need for the code above. Thankyou again, I have upvoted your comment, but cannot select it as an answer. – Kev Thomas Aug 26 '21 at 00:37
  • Also, depending how you draw the ellipse, perhaps you could treat it simply as a stretched circle... – Markus von Broady Aug 26 '21 at 08:01

0 Answers0