Russian Qt Forum
Март 29, 2024, 16:42 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 ... 13 14 [15] 16 17 ... 24   Вниз
  Печать  
Автор Тема: Геометрия (задачки)  (Прочитано 206397 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #210 : Январь 10, 2017, 16:12 »

Да, верно, только не на 9, а на 15 нужно делить.
Хммм... я подумаю почему
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #211 : Январь 11, 2017, 16:34 »

Да, верно, только не на 9, а на 15 нужно делить.
В упор не вижу откуда 15. Ладно, зайдем с др стороны
Код
C++ (Qt)
#include <QtWidgets>
 
inline float RandF( void )
{
return float(qrand()) / RAND_MAX - 0.5f;
}
 
int main(int argc, char *argv[])
{
qsrand(0);
const int num = 1000 * 1024;
double sum[5] = { 0.0 };
for (int i = 0; i < num; ++i) {
QVector3D vec(RandF(), RandF(), RandF());
vec.normalize();
double x2 = vec.x() * vec.x();
double y2 = vec.y() * vec.y();
double z2 = vec.z() * vec.z();
sum[0] += x2;
sum[1] += x2 * x2;
sum[2] += x2 * y2;
sum[3] += x2 * z2;
}
for (int i = 0; i < 4; ++i)
qDebug() << (sum[i] / num) << "/" << (num / sum[i]);
 
return 0;
}
 
Печатает
Цитировать
0.333066 / 3.00241    // x2
0.180041 / 5.55429    // x2 * x2
0.0765195 / 13.0686  // x2 * y2
0.0765056 / 13.0709  // x2 * z2
Т.е. не 9 и не 15, а какое-то левое 13.07. Предполагаю потому что x, y, z зависимы (хотя и равноправны). Также среднее x2 * x2 совершенно другое, и простые соображения говорят что это верно. Тогда "один делитель на всех" неверно. Выходит методика не обобщается на 4 и более степеней? Или я где-то насвистел в тесте?
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #212 : Январь 11, 2017, 17:45 »

Цитировать
Или я где-то насвистел в тесте?
Дело в тесте, точнее в
Код
C++ (Qt)
QVector3D vec(RandF(), RandF(), RandF());
vec.normalize();
 
Это не даёт честного равновероятного распределения по направлениям, поэтому и результаты плывут..
Должно быть, конечно:
1/3
1/5
1/15
1/15

Это легко проверить прямым счётом (интегрируя по телесному углу): см. аттач. Хотя можно посчитать для произвольной размерности и без всяких интегралов, исходя из свойств орт. преобразования и симметрии. 


« Последнее редактирование: Январь 11, 2017, 17:48 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #213 : Январь 12, 2017, 09:32 »

Генерация случайного вектора в сферической СК - популярные грабли, она не дает равномерного распределения
Код
C++ (Qt)
QVector3D RandomVec( void )
{
float theta = float(qrand()) / RAND_MAX * M_PI;   // случайный "угол возвышения"
float phi = float(qrand()) / RAND_MAX * M_PI * 2;   // случайный "азимут"
return QVector3D(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
}
"На пальцах" - компонента Z выбрасывается как будто в 2D, а X и Y "придавлены" ее синусом. Поэтому

среднее(x * x) = 1/4
среднее(y * y) = 1/4
среднее(z * z) = 1/2

Впрочем часто нужно не равномерное, а именно такое распределение, такая задачка здесь была

Хотя можно посчитать для произвольной размерности и без всяких интегралов, исходя из свойств орт. преобразования и симметрии.  
Прошу исполнить. Спасибо
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #214 : Январь 12, 2017, 11:09 »

Ага, а вот при таком генераторе векторов
Код
C++ (Qt)
inline float RandF( void )
{
return float(qrand()) / RAND_MAX * 2 - 1;
}
 
QVector3D RandVec( void )
{
while (true) {
QVector3D vec(RandF(), RandF(), RandF());
float len = vec.length();
if (len <= 1.0f) return vec / len;
}
}
Четко получается 1/5 и 1/15. Да, все верно
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #215 : Январь 12, 2017, 14:56 »

Цитировать
Генерация случайного вектора в сферической СК - популярные грабли, она не дает равномерного распределения
Ну с этим никто не спорит..

Однако если выбрать параметризацию, в которой случайной величиной является проекция ед. вектора на ось z и угол phi:
Код
C++ (Qt)
static const double pi = 4.0*atan(1.0);
 
inline double sign(const double & x) { return (x >= 0.0) ? 1 : -1; }
 
 
int main()
{
   random_device rd;
   mt19937 gen(rd());
 
   uniform_real_distribution<double> phi_dist(0.0, 2.0*pi); // распределение для угла phi
   uniform_real_distribution<double> z_dist(-1.0, 1.0); // распределение для проекции вектора на ось z
 
 
   const int num = 1000 * 1024;
   double sum[5] = { 0.0 };
   for (int i = 0; i < num; ++i)
   {
       double z = z_dist(gen);
       double phi = phi_dist(gen);
 
       double x = sign(z)*sqrt(1.0 - z*z)*cos(phi);
       double y = sign(z)*sqrt(1.0 - z*z)*sin(phi);
 
 
       double x2 = x*x;
       double y2 = y*y;
       double z2 = z*z;
       sum[0] += x2;
       sum[1] += x2 * x2;
       sum[2] += x2 * y2;
       sum[3] += x2 * z2;
   }
   for (int i = 0; i < 4; ++i)
       cout << (sum[i] / num) << endl;
 
   return 0;
}
 

то всё будет корректно. Такое усреднение будет соответствовать интегрированию по телесному углу.

Выкладываю pdf с выводом формулы для среднего от произведения ni nj nk nl


« Последнее редактирование: Январь 12, 2017, 15:30 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #216 : Январь 12, 2017, 15:23 »

Код
C++ (Qt)
static constexpr double pi = 4.0*atan(1.0);
На всякий случай, atan не constexpr по стандарту. Clang не скомпилирует.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #217 : Январь 12, 2017, 15:30 »

Цитировать
На всякий случай, atan не constexpr по стандарту. Clang не скомпилирует.
Ну да, там просто const должен быть, конечно)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #218 : Январь 12, 2017, 16:49 »

Код
C++ (Qt)
static constexpr double pi = 4.0*atan(1.0);
На всякий случай, atan не constexpr по стандарту. Clang не скомпилирует.

Хотя странно, честно говоря - ведь в данном примере агрумент atan это константа, а не переменная.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #219 : Январь 12, 2017, 17:08 »

Цитировать
Хотя странно, честно говоря - ведь в данном примере агрумент atan это константа, а не переменная.
Надо посмотреть, что там по этому поводу стандарт говорит)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #220 : Январь 12, 2017, 19:17 »

http://stackoverflow.com/questions/17347935/constexpr-math-functions
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #221 : Январь 12, 2017, 19:34 »

Я так понимаю, gcc все же умеет constexpr для этих древних legacy функций Улыбающийся

А для остальных, я так понял причину - типа так как функции очень старые и раньше не были constexpr, то и не будем мы это менять, как бы чего не вышло? Но что может измениться, косинусы углов вдруг станет модно считать по другому Непонимающий Имхо, надуманная причина "оставить как есть"...
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #222 : Январь 12, 2017, 20:19 »

По ссылке 2 причины:
Изменение глобальной переменной errno
constexpr функция не должна быть сложной (содержать циклы, например).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #223 : Январь 25, 2017, 08:03 »

20) Есть 2 шарика одинакового размера и материала (напр бильярдных)
Код
C++ (Qt)
struct Ball {
QVector3D m_position;
QVector3D m_speed;
static float radius;
};
Написать ф-цию
Код
C++ (Qt)
bool BallsCollided( Ball & ball1, Ball & ball2 )
{
// Если шарики столкнулись то вернуть true
// и рассчитать новые скорости шариков
}
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #224 : Январь 25, 2017, 17:45 »

Цитировать
20) Есть 2 шарика одинакового размера
Ну это просто решается в системе центра масс..
Код
C++ (Qt)
bool BallsCollided( Ball & ball1, Ball & ball2 )
{
   QVector3D r0 = ball1.pos - ball2.pos;
   QVector3D u = ball1.speed - ball2.speed;
 
   float u2 = u.lengthSquared();
   float r0u = QVector3D::dotProduct(r0, u);
 
   float rho2 = r0.lengthSquared() - r0u*r0u/u2;
 
   return (rho2 < 4*Ball::radius * Ball::radius);
}
 
« Последнее редактирование: Январь 25, 2017, 18:04 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Страниц: 1 ... 13 14 [15] 16 17 ... 24   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.567 секунд. Запросов: 23.