Получить случайный 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
xb
- крест продукт возвращает перпендикулярный вектор в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;
}
}
вы можете и дальше играть с ним