Skip to content

Clarify the member local coordinate system convention#315

Open
bjude wants to merge 4 commits into
JWock82:mainfrom
bjude:local_axis_docs
Open

Clarify the member local coordinate system convention#315
bjude wants to merge 4 commits into
JWock82:mainfrom
bjude:local_axis_docs

Conversation

@bjude
Copy link
Copy Markdown
Contributor

@bjude bjude commented Mar 30, 2026

Updates the documentation to reflect the logic in Member3D.T()

There is also a drive-by fix to a relevant section in rendering.rst, a missing newline broke the rendering of the member local coordinate system section

Comment thread docs/source/member.rst Outdated
Comment on lines +55 to +58
- For other members, the local x-axis is projected into the global XZ plane and the local y-axis is
determined by the cross product of this projected vector and the member local x-axis. The ordering
of the cross product is such that the resulting local y-axis has a positive global y component (i.e.
the top of the beam is always pointing in the positive global y direction)
Copy link
Copy Markdown
Owner

@JWock82 JWock82 Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local x axis is always the vector from the i-node to the j-node, and the local y-axis is always 90 degrees from the x-axis. This is important for beams that slope (e.g. roof members). It is not a projection.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the X axis is always the beam direction, I was detailing the process for determining the local y-axis for diagonal beams (this else branch) which involves a projection and a cross product.

If it's not clear that this is for determining the y-axis, rather than a modification of the x-axis, I can reword

Comment thread docs/source/member.rst

Rotations are applied by using the right-hand rule, with positive rotations being clockwise if
looking down the member from the i-node to j-node.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The right hand rule says counter-clockwise rotations are positive.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will only be CCW if you're looking down the beam with the local X pointing towards you. Looking from the i-node -> j-node (local X away from you) it will be CW

Copy link
Copy Markdown
Owner

@JWock82 JWock82 Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your right hand grips the axis, and your thumb points down it. The direction of your grip is counter-clockwise if your thumb represents the positive x-axis starting at i and heading toward j.

image

Unless you twist your right hand so your thumb is pointing away from you in an unnatural way, when you look at it it's counter-clockwise.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with everything except the CW/CCW conclusion.

In the image on the right, the i-node would be bottom left, j-node top right. If your head was down at the i-node (i.e. local x-axis pointing away from you) you would see the fingers curling CW. It will appear CCW if your thumb is pointing back towards you, but then you'd be looking from the j-node to the i-node.

In any case, CW rotation is what Pynite implements:
image


model = FEModel3D()

n1 = model.add_node("n1", 0, 0, 0)
n2 = model.add_node("n2", 1, 0, 0)
n3 = model.add_node("n3", 0, 0, 0.5)
n4 = model.add_node("n4", 1, 0, 0.5)

mat = model.add_material('mat', 1, 1, 0.3, 1)
sect = model.add_section('sect', 1, 1, 1, 1)

model.add_member('mem', "n1", "n2", "mat", "sect", rotation=0)
model.add_member('mem_rot', "n3", "n4", "mat", "sect", rotation=10)

r = Rendering.Renderer(model)
r.member_csys = True
r.render_model()```

@bjude bjude requested a review from JWock82 May 1, 2026 00:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants