Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
56 / 56 / 26
Регистрация: 13.11.2013
Сообщений: 234
Записей в блоге: 1

Получение точек неявной функции

12.07.2018, 18:16. Показов 1428. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Моя цель - написание трёхмерного графического калькулятора. На вход подаётся функция и её границы программа же визуализирует введённые данные. Соответственно, необходимо сделать разбор введённого выражения и построить синтаксическое дерево но с этим я справился. Проблема заключается именно в построение поверхностей, которые задаются неявными функциями (f(x,y,z)==0). Как я понимаю, после получения точек функции можно применить алгоритм MarchingCubes, но трудность вызывает именно процесс получения этих точек. Я пробовал самый простой способ: тремя циклами обходить x,y,z с константным шагом и получаемые значения подставлять в функцию и если результат нуль(с некой погрешностью) то считать что найдена очередная точка. Но данный подход неточен и я уверен в существовании более корректного метода.
Надеюсь на точное объяснение, в качестве примера простейший, неявной функции можно взять: x2+y2+z2-9=0
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.07.2018, 18:16
Ответы с готовыми решениями:

Табулирование неявной функции
Помогите Решить задачу Люди добрые ;( Запрещено размещать задания в виде картинок и других файлов с их текстом.

Производная неявной функции
Как в Mathcad определить производную неявно заданной функции, например x*sin(y)-y*cos(x)+y^2=0?

Производная неявной функции
Функция у (х) задана неявно уравнением 3x-2y+ ln (x^2 * y^2) = 1. Известно, что у(1) =1. Найти у'(1). Помогите пожалуйста))

9
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
13.07.2018, 01:26
Цитата Сообщение от pavelDev Посмотреть сообщение
Я пробовал самый простой способ: тремя циклами обходить x,y,z с константным шагом и получаемые значения подставлять в функцию и если результат нуль(с некой погрешностью) то считать что найдена очередная точка. Но данный подход неточен и я уверен в существовании более корректного метода.
Градиентный спуск.
1) Берете какую-то точку (x,y,z).
2) Считаете градиент функции, то есть, вектор G образованный тремя частными производными функции.
3) Осторожными шажками смещаетесь в направлении G (если нужно чтоб функция возрастала) или обратном G (если нужно чтоб убывала), проверяя приблизилась ли функция к нулю.
4) Если приблизилась - goto 2 с новым значением (x,y,z). Если осторожные шажки ничего не дают или просто надоело - конец алгоритма.
0
 Аватар для COKPOWEHEU
4079 / 2677 / 432
Регистрация: 09.09.2017
Сообщений: 11,893
13.07.2018, 10:39
Renji, ему же нужна поверхность, а не одно какое-то решение.
Можно построить сетку XY с произвольным шагом, для каждой точки подбирая значение Z. Проблема в том, что их может быть несколько, как в вашем примере.
В принципе, если это нужно только для визуализации, можно, как вы изначально и хотели, ограничиться просто разбиением оси Z на равные отрезки, достаточно малые чтобы не портить картинку.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
13.07.2018, 15:09
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Renji, ему же нужна поверхность, а не одно какое-то решение.
Искомая поверхность в эпсилон окрестности частного решения, это плоскость перпендикулярная градиенту. В предположении что эта поверхность там вообще есть (x^2+y^2+z^2==0 только одну точку и даст). Так что сначала найти набор частных решений, а потом аппроксимировать нужную поверхность кучей мелких. Ну или какую-то более продвинутую аппроксимацию замутить.
0
 Аватар для COKPOWEHEU
4079 / 2677 / 432
Регистрация: 09.09.2017
Сообщений: 11,893
13.07.2018, 18:23
Цитата Сообщение от Renji Посмотреть сообщение
x^2+y^2+z^2==0
Вы забыли -9. Искомая поверхность - сфера радиусом 3, то есть 0-2 точки (z) для любой точки (x,y)
Цитата Сообщение от Renji Посмотреть сообщение
Искомая поверхность в эпсилон окрестности частного решения, это плоскость перпендикулярная градиенту
Чтобы построить поверхность хорошо бы иметь равномерную сетку. Конечно, лучше всего когда она равномерная по расстоянию между точками, но частенько обходятся и равномерной по плоскости.
Цитата Сообщение от Renji Посмотреть сообщение
Так что сначала найти набор частных решений, а потом аппроксимировать нужную поверхность кучей мелких
С ходу не представляю простого способа разбиения на сетку рандомного набора точек.
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
13.07.2018, 18:37
Имхо, надо делать параметрирование через x,y. Задавать сетку двух параметров и для каждого значения, если оно существует, выводить точку.
0
56 / 56 / 26
Регистрация: 13.11.2013
Сообщений: 234
Записей в блоге: 1
13.07.2018, 21:38  [ТС]
Изобрёл простой, не математический алгоритм. Суть заключается, в последовательном переборе точек и ожидании смены знака, привожу упрощенный двухмерный вариант:
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
double circle(const double &x, const double &y) {
    return x * x + y * y - 1.0;
}
 
void draw(const double &x, const double &y) {
    std::cout <<x<<" "<<y<<std::endl;
}
 
void generatePoints(const double &startX, const double &startY, const double &endX,const double &endY, const double &step,
    double(*f)(const double &,const double &), void(*callBack)(const double &, const double &)) {
 
    for (double y = startY; y <= endY; y += step)
    {
        bool mode = false;
        for (double x = startX; x <= endX; x += step)
        {
            if (f(x, y) <= 0)
            {
                if (!mode)
                {
                    callBack(x, y);
                    mode = true;
                }
            }
            else
            {
                if (mode)
                {
                    callBack(x, y);
                    mode = false;
                }
            }
        }
    }
}
 
int main()
{
    generatePoints(-1.1, -1.1, 1.1, 1.1, 0.1, circle, draw);
    std::cin.get();
    return 0;
}
Но какие недостатки у такого подхода ? И как вычислить шаг ?
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В принципе, если это нужно только для визуализации, можно, как вы изначально и хотели, ограничиться просто разбиением оси Z на равные отрезки, достаточно малые чтобы не портить картинку.
Не только для визуализации, но также для экспорта в трёхмерный формат(.obj)
Цитата Сообщение от Mirmik Посмотреть сообщение
Имхо, надо делать параметрирование через x,y. Задавать сетку двух параметров и для каждого значения, если оно существует, выводить точку.
Не совсем понял, имеется ввиду преобразование исходный неявной функции в параметрический вид, но это не всегда возможно ?
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
14.07.2018, 01:19
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вы забыли -9. Искомая поверхность - сфера радиусом 3, то есть 0-2 точки (z) для любой точки (x,y)
ТС вроде хотел работу с произвольной функцией. Там -9 может и не быть.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Чтобы построить поверхность хорошо бы иметь равномерную сетку. Конечно, лучше всего когда она равномерная по расстоянию между точками, но частенько обходятся и равномерной по плоскости.
Вот узлы этой сетки мы и возьмем за начальные точки для градиентного спуска.
Цитата Сообщение от pavelDev Посмотреть сообщение
Но какие недостатки у такого подхода ? И как вычислить шаг ?
1) Вбиваете в Гугл "метод секущих".
2) Открываете учебник алгебры на разделе "нахождение производной сложной функции".
3) Открываете синтаксическое дерево функции.
4) Складываете пункт три с пунктом два.
3) Вбиваете в Гугл "градиентный спуск".
0
 Аватар для COKPOWEHEU
4079 / 2677 / 432
Регистрация: 09.09.2017
Сообщений: 11,893
14.07.2018, 09:14
Цитата Сообщение от Renji Посмотреть сообщение
ТС вроде хотел работу с произвольной функцией. Там -9 может и не быть.
Вот именно, с произвольной. Значит, и точек может быть больше 2, а найти надо все.
Цитата Сообщение от Renji Посмотреть сообщение
Вот узлы этой сетки мы и возьмем за начальные точки для градиентного спуска.
Равномерная плоская сетка может свернуться чуть ли не в точку. А объемная содержит слишком много точек.
Если уж применять ваш метод, можно попробовать найти одну точку и выпустить из нее несколько лучей в разные стороны по касательным, на каждом луче на равном расстоянии выбрать точку и "притянуть" к поверхности, оттуда еще лучи и так далее
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
14.07.2018, 19:05
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вот именно, с произвольной. Значит, и точек может быть больше 2, а найти надо все.
Я не про это. Уравнение F(x,y,z)=0 в общем случае задает не конечное множество точек, а поверхность на которой этих точек бесконечное количество. Тривиальный пример - x*a+y*b+z*c==0, дающее плоскость перпендикулярную вектору (a,b,c). В этом случае все что мы можем сделать - найти отдельные точки поверхности и нормаль к ним (а для нормали все равно придется считать градиент). Но разумеется, если F(x,y,z)==0 дает нам именно что конечное множество точек, то искать нормали в этих точках бессмысленно. Нет поверхности - нет нормали.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Если уж применять ваш метод, можно попробовать найти одну точку и выпустить из нее несколько лучей в разные стороны по касательным, на каждом луче на равном расстоянии выбрать точку и "притянуть" к поверхности, оттуда еще лучи и так далее
Сработает только если поверхность у нас одна. Подадим на вход что-то вроде x^2-4==0 и получится что одна плоскость (x==2, y и z любые) найдена, вторая потерялась.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.07.2018, 19:05
Помогаю со студенческими работами здесь

Производная неявной функции
Помогите разобраться, нужно найти вторую производную неявной функции вида: x^3+y^3-3axy=0 нахожу первую производную: ...

производная неявной функции
помогите мне, пожалуйста, решить задание... я возилась, но ответ меня несколько смущает:(

Исследование неявной функции
Не могу исследовать функцию x^2 + y^2 = x^4 + y^4 Помогите хотябы с литературой, статьями или чем-нибудь. Уже неделю строю и...

Производная неявной функции
Здравствуйте, очень нужна помощь! есть задание по среде матлаб: Вычислить производную при помощи функции (с использованием символьных...

График неявной функции
Не получается сделать что-то подобное такому 6(cos(x+y-1)+1)^2(x+sin(x+y-1))-3sin(x+y-1)(x+sin(x+y-1))^2+2&gt;0 Сравниваю с...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru