Получить случайный vector3 на плоскости

есть планета и несколько спутников в 3d-пространстве. Мне нужно вычислить ось вращения для каждого сателлита. Они должны вращаться вокруг центра планеты.

Я рассчитал вектор от спутника до центра планеты.

vec1 = planetCenter - sputnikCenter;

С помощью vec1 и planetCenter я могу вычислить уравнение плоскости, перпендикулярной vec1.

уравнение так:

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

теперь, я должен получить случайный вектор на этой плоскости. Этот вектор будет ось вращения. Но как я могу получить этот случайный вектор?

3 ответов


ну если у тебя есть самолет A.x + B.y + C.z + D = 0 затем n(A,B,C) нормальный вектор. Поэтому я думаю, что самый простой подход к вашей задаче-использовать векторов базиса. Так что вам нужно 2 перпендикулярность векторов на этой плоскости. Для этого вы можете использовать векторное произведение. сначала несколько определений:

knowns:

  • p положение центра планеты (или центральная точка ваших вращений или любая точка на плоскости, поэтому в худшем случае вы можете попробовать p=0,0,-D/C или любая другая комбинацияn...)
  • n нормальный вектор
  • q= (1,0,0) or (0,1,0) выбрал тот, у которого меньше |dot(n,q)|

операции:

  • vector = cross(a,b) = a x b - крест продукт возвращает перпендикулярный вектор в a,b
  • scalar = dot(a,b) = (a.b) - точка возврат товара 0 если a,b есть перпендикулярно!--39-->
  • |a| = abs(a) - absзначение olute (как скаляр и вектор)
  • scalar = Rand() - плавание псевдослучайное значение на интервале <0.0,1.0>

неизвестными:

  • u,v - векторов базиса
  • r - код псевдослучайных точка

так что сначала получить u,v by эксплуатируя перекрестный продукт:

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

а теперь по существу:

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

если вы хотите просто случайный вектор, то игнорируйте начальную позицию p

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

вот и все ... таким образом, вы можете вычислить u,v один раз (за нормальное изменение вектора) и генерировать r как часто, как вам нужно. Если u,v являются единичными векторами, то это будет генерировать точки внутри 2x2 площади ... если вы хотите больше или меньше, просто добавьте к ним весы ...

посмотреть можно ли сделать реалистичное моделирование Солнечной системы n-body? и генерировать случайные параметры орбиты для Кеплера уравнение вместо ...


Кажется, что ваша ось вращения может быть случайным вектором, независимым от vec1. Вы можете генерировать случайный единичный вектор с равномерным распределением использованием методов Выбор Точки Сферы.

метод Марсалья (эквалайзер. 9-11) удобно генерировать этот вектор:
Генерировать x1 и x2 в диапазоне -1..1 например p = x1^2 +x2^2 <= 1 (отклонение плохих пар).
Тогда

x = 2 * x1 * Sqrt(1 - p)
y = 2 * x2 * Sqrt(1 - p)
z = 1 - 2 * p

теперь ваш вопрос понятен. Вы хотите вращать объект вокруг другого, как Земля и Солнце. Может быть, некоторые другие решения могут быть доступны, но я бы сделал это через LookAt и параметрическое уравнение круга.

x = r * cos(theta) + displacementX

z = r * sin(theta) + displacementZ

здесь r - радиус, расстояние в вашем случае displacementX и displacementZ расстояние от начала координат. Если оба (displacementX и displacementZ) равно 0, тогда он будет вращаться вокруг origin (0,0)

в сценарии объекта(Земли) , сделайте это, как следовать

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;
    }
}

вы можете и дальше играть с ним