Calculate Rotation Around 1 Axis to "Aim" Another Transform

I have thought myself into a hole here. My education was full of rotation matrices and inverse kinematics, but I’m definitely losing my groove. I have a simple problem and I will try to articulate a simple example of it in action:

I have transform, A, which has a child transform, B. However, B is offset from the origin by some distance on the X axis. So whenever A rotates around the Y axis, transform B has a circular motion in world space.

I then have a target transform, C, that I want transform B to look straight towards (Z forward). However, transform A is the only one that can rotate in this scenario.

How can I figure out what ϴ will be before rotating A? I have attached an image demonstrating this problem.

Where I am stuck at in my (maybe wrong) solution thus far-

I have created a rotation matrix R = [T]^-1 * [R] * [T] for rotating around the fixed point, but what this doesn’t account for is the equation that solves the “look at target” situation.

I am not sure how to do it without a solver iterative approach.

You would rotate A to iteratively solve a resultant rotation of B that points at C.

There probably is a matrix expression you can use but someone stronger in linear math than I might have to chime in.

So this is one of those funny things where you ask for help, and structure your problem to a point that it finally clicks. I think rotation matrix is completely wrong now - I just used pythagorean theorem to fully solve this. It works for this example, but I figure it can be tweaked if there are any rotation offsets. Also I made the assumption that B is a right angle. If it isn’t it might be more obscure to solve but I think it can be done. Once the angles are solved it’s pretty easy to continue.

6426455--718535--pythag.PNG

I thought some more since I posted. Since it is a 2D question, I think it’s just law of sines, of which Pythagorean is a special case.

Sincerely thanks for the help Kurt!

I used a similar approach.

B’ is the rotated position of B.
d is the distance AB
h is the distance AC
triangle AB’C is right at B’, so s, the distance B’C is sqrt(h^2 - d^2).
Now you can locate B’ by solving for its coordinates via two simultaneous equations.
Then, (AB dot AB’)/d^2 is cos(theta).

This is a very elegant solution. Thank you so much.

I think there’s a simpler one:

d is the distance AB
h is the distance AC

If you rotate C around A by -theta, it intersects the line x = Bx (B’s x-coordinate).

C’ is the rotated position of C.
s is the distance BC’
Triangle ABC’ is right at B, so s = sqrt(h^2 - d^2).
This puts C’ at coordinates (0, s).
Now consider the mid-point of CC’, call it M.
Triangle AMC’ and triangle AMC are both right at M.
The angle MAC’ and the angle MAC are equal and each is theta / 2.
The distance C’M divided by h is sin(theta / 2). (As is the distance CM divided by h.)

Gets you out of the simultaneous equation part.

(Note that this also tells you early if you have an insoluble case where d > h.)

For the case where your cannon is angled other than at 90 degrees:

Call the angle of your cannon phi.
For some point D along AB, a cannon at 90 degrees has solution theta, which we know how to compute.
Where is D?
Triangle BDC’ is right at D.
So, DB / BC’ = cos(phi).
A, B, and D are all on the line y=0, so that makes it easy to figure the x-coordinate of D.
From there, solve for theta as before.

Now, I haven’t coded this, but there is some further math you could use that avoids angles entirely, and has a neat outcome at the very end, from a Unity gamedev point of view:

A is at (0, 0).
B is at (s, 0).
C is at (u, v).

B’ is at (x, y), the point where the rotated arm aims the cannon at C.

Triangle AB’C is right at B’.
Thus, AB’ dot B’C = 0.
The distance from A to B’ is the same as from A to B.
Thus, x^2 + y^2 = s^2 (which is the equation of a circle of radius s, centered at the origin).

AB’ dot B’C = (x - u)x + (y - v)y = 0.

By a little algebra, that dot product becomes the equation of a circle centered at (u/2, v/2):

(x - u/2)^2 + (y - v/2)^2 = (u^2 + v^2) / 4.

We want the points where these two circles intersect.

By using a method published by Paul Bourke (also written up on StackOverflow), we can find those intersections:

Here’s what we know:

The first circle is defined by:

x0 = 0.
y0 = 0.
r0 = s.

The second circle is defined by:

x1 = u/2.
y1 = v/2.
r1 = sqrt(u^2 + v^2) / 2

(Note that if r0 > r1, you can’t make the cannon point at C.)

Using Bourke’s method (which is generalized, making some of the next few steps unnecessary, but harmless), proceed as follows:

d = r1
a = (r0^2 - r1^2 + d^2) / (2d)
h = sqrt(r0^2 - a^2)

x2 = x0 + a(x1 - x0) / d.
y2 = y0 + a(y1 - y0) / d.

First solution at P3:

x3 = x2 + h(y1 - y0) / d.
y3 = y2 - h(x1 - x0) / d.

Second solution at P3’:

x3’ = x2 - h(y1 - y0) / d.
y3’ = y2 + h(x1 - x0) / d.

Now, only one solution points at C, the other points away. You can take a vector cross-product to know which one you want:

if |AP3 x P3C| > 0, P3 is your solution, otherwise you use P3’.

Now, here’s why this is cool: if the cannon were translated back down the arm to A, it would be pointing along a line that included a point C’, defined by translating C by the same amount you just translated the cannon. This point is simply C’ = C - B’ (remember that B’ is either P3 or P3’, depending on the cross-product).

This means you can make the cannon point at C by using the Transform.LookAt function and making A’s transform look at C’. You never need to calculate, nor even know, the angle of rotation.

Okay I was able to draft this up for anyone else who comes through here. I implemented this solution and it worked.

This covers the case when the cannon is 90 degrees very well. The other two situations are when it is not 90 degrees, and when it is not positioned at (d, 0) with respect to A (or a combination of both).

I will try to visualize your following reply as well for the case when the cannon is not 90 degrees

6428255--718868--Solution1.PNG

I am going to work on implementing this and will update when it is done, and everything that has been discussed will also be in this project.

https://github.com/ChristopherSharp/Offset-Articulations