Stream: helpdesk (published)

Topic: Rotate a 3D point around another


view this post on Zulip cormullion (Jan 23 2021 at 14:33):

Anyone know how I can use Rotations.jl to rotate a 3D point around another? I'm struggling with the README.md:

function rotateby(pt::Point3D, about::Point3D, angleX, angleY, angleZ)
    ...
    return pt1
end

view this post on Zulip Florian Große (Jan 23 2021 at 16:33):

It seems like they have XYZ-axis rotations. That's totally not my field, but I would guess that given points x and y and a rotation R around the origin, a rotation of x around y would simply decompose to R*(x-y) + y (?)

view this post on Zulip Patrick Bouffard (Jan 25 2021 at 00:14):

I think you'll need to better define exactly what you mean by angleX, angleY, angleZ.. It sounds from your comment in the issue you opened that you might need to get familiar with the different ways rotations can be represented -- probably what you want corresponds to one of them but from what you've said so far I can't tell which.

There are lots of resources I could point you to but it'd be useful to know where you're starting from. E.g. https://rotations.berkeley.edu/contents/ is very comprehensive but pretty mathy and likely overkill.

So, maybe you can say a bit more about where angleX/Y/Z come from and the context of how you intend to use rotateby.

view this post on Zulip cormullion (Jan 25 2021 at 09:43):

Hi Patrick! Thanks for helping me out, I appreciate it.

So let's say I'm thinking of a point A in 3D space, at Point3D(1, 1, 0). I want to rotate this by π radians around the z axis. So I get B, Point3D(1, -1, 0). Then I want to rotate this around the y axis by π radians, so I get C, Point3D(-1.0, -1.0, 0). I could also get to C by rotating A around the x-axis.
Screenshot-2021-01-25-at-09.38.42.png
In this case obviously rotations can be either clockwise or anticlockwise (I used π for simplicity ), but any convention is OK.

This was the kind of thing I was thinking for "3D rotations made easy". I thought it could probably be done in a few lines... Perhaps I'm wrong.

view this post on Zulip Pranshu Malik (Jan 25 2021 at 10:15):

I think what you need here are relative poses. You can define/think of a point as a reference frame, and since you want the axes to be parallel, you can have all games at 0 relative angle to the origin. Then convert one point (or frame) to another point's frame of reference (simply subtract coordinates) and then use a rotx/roty/rotz. Then compose the result with the reference point's translation. In all it'll look like this:

rotz(p2-p1, angle) + p1

view this post on Zulip Pranshu Malik (Jan 25 2021 at 10:16):

The same was also mentioned by Florian above

view this post on Zulip Florian Große (Jan 25 2021 at 10:28):

Yes, that's what I meant. I think what @Patrick Bouffard is hinting it is, that simply saying you want tp rotate degrees a, b, c around the x, y, z axes doesn't get you too far, because the order of application is not irrelevant for rotations! Imagine you start at a point on your x-axis, say (1., 0., 0.) and you just want to rotate 90° around the x and y axes. If you start by rotating around x, you don't change your point on the x-axis, so the rotation around y will bring you to (0., 0., ±1.). But if you start by rotating around y, you go to (0., 0., ±1.) initially and suddenly, your rotation around x is now actually doing something and you end up at (0., ±1., 0.). So you either have to do one rotation at a time or specify which convention you use when you say a° around x and b° around y.

view this post on Zulip cormullion (Jan 25 2021 at 10:31):

So that's why I've been having trouble! :) Perhaps I shouldn't be trying to do three rotations at once, just provide a rotateX() rotateY() and rotate(Z) functions instead...

view this post on Zulip Florian Große (Jan 25 2021 at 10:31):

That said, I found the package you are probably looking for:

https://github.com/JuliaGeometry/CoordinateTransformations.jl

Which was linked from Rotations.jl. It has a recenter method:

"""
recenter(trans::Union{AbstractMatrix,Transformation}, origin::AbstractVector) -> ctrans

Return a new transformation ctrans such that point origin servesas the origin-of-coordinates for trans. Translation by ±originoccurs both before and after applying trans,...
"""

view this post on Zulip Pranshu Malik (Jan 25 2021 at 10:34):

Yup, or there are also matrices for rotation along any axis. So if you can define one axis around which you have one rotation corresponding to 3 rotations from the origin, then that might be what you want. But only limited transformations will fit this criteria

view this post on Zulip cormullion (Jan 25 2021 at 10:38):

Yes I'm sure these packages can easily do this sort of thing without breaking into a sweat. It's just sometimes hard for me to find out how to do the simple things. I suppose they're not really intended for that though.

view this post on Zulip Patrick Bouffard (Jan 25 2021 at 16:48):

Did angleX/Y/Z come from another source and you are trying to apply them correctly? Or are you saying that you need to rotate points and are trying to work out a way to do so? If it's the former then it's important you interpret the 3 values correctly--there are a number of ways you could do so. Some of them are more common than others depending on if you're doing aerospace, or physics, or whatever. But if it's the latter the problem is reversed: there are a lot of different ways you can parametrize rotations and they all have pros and cons that depend on the application.

If you give us a bit more context that will help give you better advice!

view this post on Zulip cormullion (Jan 25 2021 at 17:44):

Well as Florian said I'm probably getting confused by the fact that rotations have to applied in a particular order, so perhaps it isn't a brilliant idea to try to supply all rotations in one function call.
Screenshot-2021-01-25-at-17.36.33.png
I originally thought that there might be an easy alternative to all these rotation functions by just switching to calls to Rotations.jl or CoordinateTransformations.jl functions, but I wasn't able to get much from the READMEs, since they're obviously aimed at a different level of user (PhD rather than GCSE :)). I'll probably stick to what I have at the moment, just switching to separate functions...

view this post on Zulip Pranshu Malik (Jan 25 2021 at 17:56):

Which library are you using to display text in 3D plots? I'd like to do this for a package too

view this post on Zulip cormullion (Jan 25 2021 at 18:03):

I use a small package called Thebes.jl, but it's fairly simplistic, and I want to improve the rotations code... :joy:

view this post on Zulip Patrick Bouffard (Jan 25 2021 at 18:03):

Haha, fair point about the docs, though don't let that intimidate you! Assuming you don't just have this one thing to do and then never touch rotations in 3D again I think it would be good for you to find a resource that meets you where you're at mathematically. You definitely don't need a PhD to grasp the basics or even the advanced stuff.

But you will need to be comfortable at least with vectors, matrix multiplication, and basic trigonometry (just sin & cos). If you are then it'd be easy to help you, but again also knowing more about what you're trying to do here will really be useful.

view this post on Zulip cormullion (Jan 25 2021 at 18:06):

Thanks Patrick! I like to encounter challenges sequentially, but multiple things arrive very quickly in JuliaGeometry!:joy:

view this post on Zulip Patrick Bouffard (Jan 25 2021 at 18:13):

Fair enough. Neat package! Can you say more specifically what you want to improve? It looks like you have something that works.

view this post on Zulip cormullion (Jan 25 2021 at 18:34):

Well either I don't understand my code or my code doesn't understand me, I'm not sure which it is. So I thought I'd investigate using someone else's code, which - I usually find - is better... :joy: Perhaps I just have to watch more videos...

view this post on Zulip cormullion (Jan 26 2021 at 13:27):

Thanks for all the help! The answer is:

using Rotations
function rotateby(point::Point3D, about::Point3D, angleX, angleY, angleZ)
    RotXYZ(angleX, angleY, angleZ) * (point - about) + about
end

(Chris Foster helped me out!)


Last updated: Oct 02 2023 at 04:34 UTC