8

There are the planet and a few satellites in 3d space. I need to calculate axis of rotation for every satellite. They should rotate around planet center.

I calculated the vector from satellite to the center of the planet.

vec1 = planetCenter - sputnikCenter;

With vec1 and planetCenter I can calculate the equation of plane, that perpendicular to vec1.

equation like that:

A.x + B.y + C.z + D = 0

Now, I should get random vector on this plane. This vector will be axis of rotation. But how can I get this random vector?

Spektre
  • 49,595
  • 11
  • 110
  • 380
Yuri
  • 209
  • 2
  • 12
  • So in general you want to rotate objects at random distance around another object? – Hamza Hasan Dec 25 '15 at 09:30
  • @HamzaHasan There is a method object.Rotate(axis, angle); So, I have to calculate that axis and call this method. – Yuri Dec 25 '15 at 09:34
  • @HamzaHasan the distance of rotation equal the current distance between planet and sputnik – Yuri Dec 25 '15 at 09:35
  • So in your case it would be `Vector3.up` so it will rotate in x-z axes. But I think you want rotation like moon around earth. Right? – Hamza Hasan Dec 25 '15 at 09:54
  • 1
    Actually your question is not that clear, can you please edit it with some examples? – Hamza Hasan Dec 25 '15 at 09:56
  • @HamzaHasan yep, I want to rotate around center of planet. – Yuri Dec 25 '15 at 09:56
  • @Yuri if you want to rotate around the planet, the plane you've calculated doesn't really help you. Its normal is a vector in the plane in which you want to rotate. You actually need a vector that is perpendicular to it – Zachi Shtain Dec 31 '15 at 15:55

3 Answers3

3

well if you got the plane A.x + B.y + C.z + D = 0 then n(A,B,C) is the normal vector. So I think the easiest approach to your task is to use basis vectors. So you need 2 perpendicular vectors on this plane. For that you can exploit cross product. first some definitions:

knowns:

  • p planet center position (or the center point of your rotations or any point on the plane so in worst case you can try p=0,0,-D/C or any other combinationn...)
  • n normal vector
  • q= (1,0,0) or (0,1,0) chose the one that has lesser |dot(n,q)|

operations:

  • vector = cross(a,b) = a x b - cross product returns perpendicular vector to a,b
  • scalar = dot(a,b) = (a.b) - dot product returns 0 if a,b are perpendicular
  • |a| = abs(a) - absolute value (both scalar and vector)
  • scalar = Rand() - float pseudo random value on interval <0.0,1.0>

unknowns:

  • u,v - basis vectors
  • r - your pseudo-random point

So first get u,v by exploiting cross product:

u=cross(n,q)
v=cross(n,u)

And now the point:

r = p + u*(2.0*Rand()-1.0) + v*(2.0*Rand()-1.0)

If you want just random vector then ignore the start position p

r' = u*(2.0*Rand()-1.0) + v*(2.0*Rand()-1.0)

That is all ... so you can compute u,v once (per normal vector change) and generate the r as often as you need. If u,v are unit vectors then this will generate points inside 2x2 square ... if you want more or less just add scales to them ...

see Is it possible to make realistic n-body solar system simulation? and generate random orbital parameters for Kepler's equation instead ...

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
0

Now your question is clear. You want to rotate object around another, like Earth and Sun. May be some other solutions may available but I would do it through LookAt and parametric equation of circle.

x = r * cos(theta) + displacementX

z = r * sin(theta) + displacementZ

where r is radius, distance in your case displacementX and displacementZ are the distance from origin. If both (displacementX and displacementZ) is 0 then it will rotate around origin (0,0)

In Object(Earth) script, do it as follow

public Transform _sun;
float _theta = 0;

void Start ()
{
    StartCoroutine ("ChangeAngle");
}

void Update ()
{
    transform.LookAt (_sun);
    float newX = (5 * Mathf.Cos (_theta)) + _sun.position.x;
    float newZ = (5 * Mathf.Sin (_theta)) + _sun.position.z;

    transform.position = new Vector3 (newX, _sun.position.y, newZ);
}

IEnumerator ChangeAngle ()
{
    while (true) {
        yield return new WaitForSeconds (0.01f);
        _theta += 0.1f;
        if (_theta >= 360)
            _theta = 0;
    }
}

You can further play with it

Hamza Hasan
  • 1,368
  • 9
  • 17
0

It seems your rotation axis might be random vector that is independent from vec1. You can generate random unit vector with uniform distribution using methods for Sphere Point Picking.

Marsaglia method (eq. 9-11) is convenient to generate this vector:
Generate x1 and x2 in range -1..1 such as p = x1^2 +x2^2 <= 1 (rejecting bad pairs).
Then

x = 2 * x1 * Sqrt(1 - p)
y = 2 * x2 * Sqrt(1 - p)
z = 1 - 2 * p
MBo
  • 77,366
  • 5
  • 53
  • 86