0
$\begingroup$

For example, let's say I want to construct a line from (0,0,0), to a point within the XZ plane, at an angle of 23 degrees, and with a length of 10. The endpoint would then be (10cos(23deg),0,10sin(23deg)) or something like that.

  1. Is there a way to construct a line given these endpoints?

  2. More convenient would be a way to construct a line given the origin point and an XZ vector, is that possible?

$\endgroup$

1 Answer 1

3
$\begingroup$

Use Vectors.

The mathutils module has a number of classes and methods to deal with linear algebra requirements. See mathutils.geometry for methods to find intersections and closest points of points, lines and planes. (Maybe handy re other question)

Blender comes with a python console, used below to demonstrate one way to construct the vector in question,

Start with the X axis as a basis vector

>>> x_axis = Vector((1, 0, 0))

Next make a matrix to rotate it around the Y axis to obtain any vector on XY plane, going thru (0, 0, 0).

>>> R = Matrix.Rotation(radians(23), 4, 'Y')
>>> v  = (R @ x_axis).normalized()
>>> v
Vector((0.9205049276351929, 0.0, -0.39073100686073303))

No need to normalize since the rotated unit vector will maintain its unit length.

Testing result with simple trig

>>> degrees(acos(v.x))
22.99998912203489

Notice that rotating around Y axis (looking down the axis) rotates clockwise and moves into negative quadrant. Negate either angle or axis ((0, -1, 0)) when constructing rotation matrix to screw the other way.

>>> degrees(asin(v.z))
-22.999992429369787

Angle between x axis and v

>>> degrees(x_axis.angle(v))
22.999989256384694

Note can get a signed angle using 2D vectors. eg only the XZ components

>>> degrees(v.xz.angle_signed(x_axis.xz))
-22.999992671479276

To make the vector length d multiply it by the scalar

v *= d

Make a line.

To make an edge from origin to v, it would have vert coordinates

verts = (
    (0, 0, 0),
    v,
    )

And edges (indexing verts)

edges = (
    (0, 1),
    )

which can be fed into bpy.types.Mesh.from_pydata(verts, edges, faces) Eg make a new single edge mesh named "Line"

>>> me = D.meshes.new("Line")
>>> me.from_pydata(verts, edges, [])
$\endgroup$
6
  • $\begingroup$ Thanks for that, it's all understandable! But, I entered it all into the console and no errors came back, but no object was created on my screen, either. Then I tried entering the first line into the text editor (after import bpy and import mathutils), and got the error, "python script failed..." when I ran it. No message appeared in the system console. $\endgroup$
    – WillDotson
    Commented Aug 9, 2021 at 17:41
  • $\begingroup$ It's a mesh datablock, not an object. Make an object and Link the mesh to an object. ob = D.objects.new("Line", me) $\endgroup$
    – batFINGER
    Commented Aug 9, 2021 at 17:44
  • $\begingroup$ Still no line on the screen, no object in the scene collection. $\endgroup$
    – WillDotson
    Commented Aug 9, 2021 at 21:58
  • $\begingroup$ C'mon mate, then link the object to a scene collection. blender.stackexchange.com/a/159185/15543 $\endgroup$
    – batFINGER
    Commented Aug 10, 2021 at 0:12
  • $\begingroup$ "C'mon mate" sounds like maybe I'm being impossibly dense. I should probably read a good book on python in blender before trying any of this stuff. I just figured 40 plus years of programming in various languages might help. Guess not. Here's my trouble what's a scene? a collection? a mesh (it's really a datablock, right?) a datablock--specifically? a context? What's an object (I know what it is in C++, but that's not it, is it)? Can you recommend a good, terse, complete, explanatory reference, something akin to The Waite Group's C Bible? PS I'm using Blender 2.83 for the stability. $\endgroup$
    – WillDotson
    Commented Aug 10, 2021 at 2:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .