2 / 2 / 0
Регистрация: 10.09.2023
Сообщений: 70

Пересечение трехмерной сетки точек движущейся сферой

29.02.2024, 16:47. Показов 4409. Ответов 46

Студворк — интернет-сервис помощи студентам
Дана трехмерная сетка из точек, выровненных по осям X, Y, Z с равномерным шагом ∆s начиная с заданной опорной точки O. Любая точка P в этой сетке может быть определена как: P = O + (ix, iy, iz)∆s, де ix, iy и iz - целочисленные индексы, принадлежащие открытым диапазонам [0, nx), [0, ny) и [0, nz) соответственно. Сетка пересекается движущейся сферой радиуса R. Движение центра сферы определяется 3d-кривой f(t), t ∈ [0, 1]. Для упрощения реализации дана выборка f(t) с шагом ∆t (0 < ∆t ≪ 1) и получаем последовательность 3d-точек f(0), f(∆t), ... , f(1). Каждая пара последовательных точек в этой последовательности может рассматриваться как начальная и конечная точки линейного движения сферы. Точки, пересекающиеся с движущейся сферой, считаются удаленными.
Задание: Реализовать функцию, которая принимает входные параметры (∆s, O, nx, ny, nz, R, f(t), ∆t), моделирует удаление точек сетки, которые пересекаются с линейными перемещениями сферы, и выводит все оставшиеся точки, видимые сверху.

Я пока мало знаю о компьютерной графике и алгоритмах, которые в ней используются. Вот что я пытался сделать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Bresenham's algorithm for drawing circle
std::vector<Point3> GetCircleBoundary(const Point3& center, double radius)
{
    std::vector<Point3> points;
 
    int x = 0;
    int y = radius;
    int delta = 1 - 2 * radius;
    int error = 0;
    while (y >= x)
    {
        points.emplace_back(center.x() + x, center.y() + y, center.z());
        points.emplace_back(center.x() + x, center.y() - y, center.z());
        points.emplace_back(center.x() - x, center.y() + y, center.z());
        points.emplace_back(center.x() - x, center.y() - y, center.z());
        points.emplace_back(center.x() + y, center.y() + x, center.z());
        points.emplace_back(center.x() + y, center.y() - x, center.z());
        points.emplace_back(center.x() - y, center.y() + x, center.z());
        points.emplace_back(center.x() - y, center.y() - x, center.z());
        error = 2 * (delta + y) - 1;
        if ((delta < 0) && (error <= 0))
        {
            delta += 2 * ++x + 1;
            continue;
        }
        if ((delta > 0) && (error > 0))
        {
            delta -= 2 * --y + 1;
            continue;
        }
        delta += 2 * (++x - --y);
    }
    return points;
}
 
 
/// @param refPoint reference point O of the cloud, which is a point with the minimum values along
/// all coordinate axes
/// @param nx number of points in cloud along x axis
/// @param ny number of points in cloud along y axis
/// @param nz number of points in cloud along z axis
/// @param deltaS distance between neighboring cloud points along x, y and z axis
/// @param sphereRadius radius R of the sphere
/// @param curve 3d curve that defines trajectory of the sphere
/// @param deltaT step size for 3d curve parameter
void Process(
    const Point3 refPoint,
    const int nx,
    const int ny,
    const int nz,
    const double deltaS,
    const double sphereRadius,
    const Curve& curve,
    const double deltaT)
{
    int maxZ = refPoint.z() + nz * deltaS;
    std::vector<std::vector<std::optional<Point3>>> topSkin(ny, std::vector<std::optional<Point3>>(nx));    
 
    for (int y = 0; y < ny; ++y)
        for (int x = 0; x < nx; ++x)
            topSkin[y][x] = Point3(refPoint.x() + x * deltaS, refPoint.y() + y * deltaS, maxZ);
 
    Point3 sphereCenter;
    for (double t = curve.GetBeginParameter(); t <= curve.GetEndParameter(); t += deltaT)
    {
        sphereCenter = curve.Evaluate(t);
 
        if (sphereCenter.z() + sphereRadius <= maxZ)
            continue;
 
        double r{};
        std::vector<Point3> points;
        for (double z = maxZ; z <= sphereCenter.z() + sphereRadius; z += deltaS)
        {
            r = std::sqrt(sphereRadius * sphereRadius - (z - sphereCenter.z()) * (z - sphereCenter.z()));
            points = GetCircleBoundary(Point3(sphereCenter.x(), sphereCenter.y(), z), r);
 
            for (const auto& point : points)
            {
                std::size_t y = (point.y() - refPoint.y()) / deltaS;
                std::size_t x = (point.x() - refPoint.x()) / deltaS;
                if (2 * sphereCenter.z() - point.z() > refPoint.z())
                    topSkin[y][x] = Point3(point.x(), point.y(), 2 * sphereCenter.z() - point.z());
                else
                    topSkin[y][x] = {};
            }
        }
    }
 
        // WriteToFile(topSkin);
}
Тут для каждого момента времени я нахожу каждую точку сферы, которая 'вылазит' выше верхней поверхности сетки, и говорю, что тогда сверху будет видна точка, симметричная этой относительно центра сферы.
Направьте на путь истинный, если можно, как это сделать получше?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.02.2024, 16:47
Ответы с готовыми решениями:

Аппроксимация точек сферой
Добрый день! Написал программу для аппроксимации точек сферой. Перейдя по ссылке най сайт уважаемого Prografix можно увидеть...

Смоделировать движение трехмерной рыбацкой сетки на экране (MFC)
Доброго времени суток. Передо мной поставили задачу: смоделировать движение трехмерной рыбацкой сетки на экране. То есть: висит сеть,...

Отрисовать набор точек в трехмерной системе координат (с возможностью вращения)
Подскажите, как отрисовать набор точек в трехмерной системе координат с возможностью вращения.

46
 Аватар для zayats80888
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.03.2024, 23:00
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Igor3D Посмотреть сообщение
Сначала дырки может не быть, потом она появляется и заканчивается. А у Вас предполагается что дырка идет от самого верхнего слоя.
Цикл верхнего уровня (по isChanged) гарантирует, что она появится рано или поздно, если вообще должна.
Цитата Сообщение от MeXaL Посмотреть сообщение
Видны точки самого верхнего слоя сферы (у которых координата nz - 1)
Т.е. у вас при расчетах трактория ни разу не пересекает верхний слой, хотя в теории входные данные гарантирут это?
Ставьте брикпойнты и смотрите, почему не меняется массив topView.

Добавлено через 9 минут
MeXaL, кстати, я не вижу так же выставление параметра t в начальное значение перед циклом по t.

Добавлено через 3 минуты
Короче, вы обязательно должны инициализировать точку a и параметр t в начальное состояние перед этим циклом по сегментам внутри цикла по isChanged.
0
1977 / 833 / 115
Регистрация: 01.10.2012
Сообщений: 5,149
Записей в блоге: 2
19.03.2024, 23:03
Цитата Сообщение от zayats80888 Посмотреть сообщение
Цикл верхнего уровня (по isChanged) гарантирует, что она появится рано или поздно, если вообще должна.
Может и появится, но из цикла уже выскочили и точку завершили (судя по коду в #35)
0
 Аватар для zayats80888
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.03.2024, 23:11
Цитата Сообщение от Igor3D Посмотреть сообщение
судя по коду в #35
Да, у него там "детские" ошибки, но мы их вроде нашли
0
2 / 2 / 0
Регистрация: 10.09.2023
Сообщений: 70
19.03.2024, 23:52  [ТС]
Это есть все, просто я не привел.
0
 Аватар для zayats80888
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
20.03.2024, 00:12
Цитата Сообщение от MeXaL Посмотреть сообщение
Это есть все, просто я не привел.
В таком случае все должно работать.
Если не в состоянии сами смоделировать простые входные данные(например, один сегмент, который "пропахивает" борозду в верхнем слое) и отладчиком найти причину, по которой в коде этого не присходит, то приведите весь код, который не работает, посмотрим.
1
2 / 2 / 0
Регистрация: 10.09.2023
Сообщений: 70
20.03.2024, 19:12  [ТС]
Спасибо Вам огромное за помощь, у меня уже все получилось, я разобрался.
0
21.03.2024, 12:21

Не по теме:

Надо будет тимлиду сказать про адаптивную сетку :)

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.03.2024, 12:21

Нахождение прямоугольников, задаваемых множеством точек, расположенных в узлах сетки
Не совсем уверен, правильный ли раздел. Если не тот — прошу подсказать, куда нужно переместить тему. Теперь, собственно, задача: Есть...

Рассчитать количество all всех точек сетки лежащий внутри этого круга
Данные - это круг с центром в системе координат и радиусом 𝑟. Рассчитать количество all всех точек сетки лежащий внутри этого круга. ...

Найти пересечение точек
Помогите, пожалуйста ! Никак не могу решить задачу, мозг уже кипит, а последние нервные клетки держатся на волоске. На числовой прямой...

Пересечение точек с прямой
Петя нарисовал замкнутую кривую (полилинию) на листе бумаги, используя синие чернила. Он оставил этот лист на столе, а его младший брат...

Определение точек пересечение окружностей
Возникла вновь проблема с окружностями, но немного более глубокого характера... В общем есть две геоточки (latitude longitude) и их...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
47
Ответ Создать тему
Опции темы

Новые блоги и статьи
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru