2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки


Правила форума


Посмотреть правила форума



Начать новую тему Ответить на тему На страницу Пред.  1, 2
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение13.06.2019, 22:15 
Аватара пользователя


26/05/12
1534
приходит весна?
Rusich в сообщении #1399172 писал(а):
Так это тоже сделано

Нет, того, что я предложил у вас и в помине нет. Иначе бы у вас было одно уравнение относительно одной неизвестной. Перечитайте мою рекомендацию по-внимательней. Ну, или прислушайтесь к другим. Мой способ, если что, самый что ни на есть изящный метод "в лоб".

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение13.06.2019, 22:43 
Заслуженный участник


26/05/14
981
Я присоединяюсь к варианту, который предложил B@R5uk.

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение13.06.2019, 23:10 


13/06/19
13
B@R5uk в сообщении #1399174 писал(а):
Rusich в сообщении #1399172 писал(а):
Так это тоже сделано

Нет, того, что я предложил у вас и в помине нет. Иначе бы у вас было одно уравнение относительно одной неизвестной. Перечитайте мою рекомендацию по-внимательней. Ну, или прислушайтесь к другим. Мой способ, если что, самый что ни на есть изящный метод "в лоб".


Ну я понял, что "в лоб":
B@R5uk в сообщении #1399174 писал(а):
Получилась система относительно угла $\alpha$. Находим его численно


Действительно, из одного угла легко вывести всё остальное. Но какой смысл?

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение13.06.2019, 23:19 
Заслуженный участник


27/04/09
28128
Ну раз в элементарных функциях не получится, а численно не хочется, то в каком виде вы хотели бы получить ответ?

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение13.06.2019, 23:26 


18/05/15
680
Rusich, меня вот смущает условие $\alpha=s\beta$?
Может к комплексным числам стоит перейти?

-- 14.06.2019, 00:45 --

$s$ случайно не натуральное число? Тогда бы получилсяя полином с вещественными коэффициентами.. степени так эдак пять..шесть
:lol:

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение14.06.2019, 11:42 


13/06/19
13
В общем, как я понял, эти уравнения можно решить только численно. Ладно, что ж делать, будем вычислять так.

ihq.pl в сообщении #1399188 писал(а):
$s$ случайно не натуральное число? Тогда бы получилсяя полином с вещественными коэффициентами.. степени так эдак пять..шесть
:lol:

К сожалению, нет: -1,2 и 0,8.

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение14.06.2019, 13:03 


18/05/15
680
Rusich, есть еще одна сумасшедшая идея:) Но вдруг вам понравится. Можно представить, что ваша ломаная - это кривошип, т.е. в точках $A,B,C,D$ шарниры, при этом точки $A,D$ фиксированные. Уравнение отностительно $\beta$: $$k=k_1\cos\alpha+k_2\cos(\beta-\alpha)+k_3\cos\beta,$$где $k,k_i$ - постоянные, не зависящие от $\beta$. Если его продифференцировать, получим $$0 = -\alpha' k_1\sin\alpha - (1-\alpha')k_2\sin(\beta-\alpha) - k_3\sin\beta,$$откуда $$\frac{d\alpha}{d\beta}  = \frac{k_2\sin(\beta-\alpha) + k_3\sin\beta}{k_2\sin(\beta-\alpha) - k_1\sin\alpha }.$$ Ужас, конечно. Но вдруг.

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение16.06.2019, 12:24 


13/06/19
13
ihq.pl в сообщении #1399237 писал(а):
Можно представить, что ваша ломаная - это кривошип, т.е. в точках $A,B,C,D$ шарниры, при этом точки $A,D$ фиксированные.

Тоже интересная идея. Кстати, именно как шарнирная система эта нога изначально и представлена в задаче, приведённые условия - ограничения степеней свободы.
В общем, пока сделал так (код на JS):
код: [ скачать ] [ спрятать ]
Используется синтаксис Javascript
        function Нога(дл_отр_1, дл_отр_2, дл_отр_3, нач, кон, соотношение_углов) {
                const расстояние = Math.sqrt((нач[0] - кон[0]) ** 2 + (нач[1] - кон[1]) ** 2);
                let угол = 0, шаг = Math.PI * 2/3, ош = 1, ломаная;
                let i = 0;
                while (Math.abs(ош) > 1e-10) {
                        if (i++ > 50) { alert("Невозможно построить ногу."); return; }
                        const значения = [];
                        for (let сч = -1; сч <= 1; сч++) {
                                const
                                        уг = угол + шаг * сч,
                                        x_1 = Math.cos(уг) * дл_отр_1,
                                        y_1 = Math.sin(уг) * дл_отр_1,
                                        x_2 = дл_отр_2 - Math.cos((Math.PI + уг) * соотношение_углов - Math.PI) * дл_отр_3,
                                        y_2 = -Math.sin((Math.PI + уг) * соотношение_углов - Math.PI) * дл_отр_3;
                                значения.push([
                                        уг, Math.abs(Math.sqrt((x_1 - x_2) ** 2 + (y_1 - y_2) ** 2) - расстояние), [x_1, y_1], [x_2, y_2]
                                ]);
                        }
                        ломаная = значения.reduce((пр, зн) => зн[1] < пр[1] ? зн : пр);
                        угол = ломаная[0], ош = ломаная[1];
                        шаг /= 2;
                }
                if (ломаная[2][1] < 0 && ломаная[3][1] > 0) {
                        ломаная[2][1] = -ломаная[2][1]; ломаная[3][1] = -ломаная[3][1];
                }
                ломаная.splice(0, 2), ломаная.splice(1, 0, [0, 0], [дл_отр_2, 0]);
                const Вращение = (т, ц, sin, cos) => [
                        ц[0] + (т[0] - ц[0]) * cos - (т[1] - ц[1]) * sin,
                        ц[1] + (т[1] - ц[1]) * cos + (т[0] - ц[0]) * sin
                ];
                const
                        разница_углов = Math.asin((ломаная[0][1] - ломаная[3][1]) / расстояние) - Math.asin((нач[1] - кон[1]) / расстояние),
                        sin_р = Math.sin(разница_углов), cos_р = Math.cos(разница_углов);
                for (let сч = 0; сч < 3; сч++)
                        ломаная[сч] = Вращение(ломаная[сч], ломаная[3], sin_р, cos_р);
                const сдвиг_x = ломаная[0][0] - нач[0], сдвиг_y = ломаная[0][1] - нач[1];
                ломаная = ломаная.map(отр => (отр[0] -= сдвиг_x, отр[1] -= сдвиг_y, отр));
                return ломаная;
        }
 

Небольшое отличие: сравниваются смежные представленным выше углы, как подразумевается в оригинале.
Спасибо всем за помощь и с праздником!

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение17.06.2019, 21:07 


13/06/19
13
Получилось красиво. Почти. Если не ошибаюсь, функция эта непрерывной должна быть. Однако при таком подходе к нахождению угла иногда получается примерно так: http://rusprog.xenn.xyz/noga.html
Как бы это обойти? На практике такие "скачки" совсем некстати.

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение17.06.2019, 22:02 
Заслуженный участник


27/04/09
28128
Возможно, проблема в этом:

разница_углов = Math.asin((ломаная[0][1] - ломаная[3][1]) / расстояние) - Math.asin((нач[1] - кон[1]) / расстояние)

Есть же Math.atan2, именно его и надо использовать для нахождения угла поворота. Арксинус и арккосинус некоторых выражений дадут углы в уполовиненном диапазоне, часто полезные, но не в таких случаях. Разность арксинусов и арккосинусов может иметь свойства ещё хуже.

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение17.06.2019, 23:16 


13/06/19
13
arseniiv в сообщении #1399823 писал(а):
Возможно, проблема в этом:

разница_углов = Math.asin((ломаная[0][1] - ломаная[3][1]) / расстояние) - Math.asin((нач[1] - кон[1]) / расстояние)

Есть же Math.atan2, именно его и надо использовать для нахождения угла поворота. Арксинус и арккосинус некоторых выражений дадут углы в уполовиненном диапазоне, часто полезные, но не в таких случаях. Разность арксинусов и арккосинусов может иметь свойства ещё хуже.

Арксинус здесь не так уж плох, кроме одного нюанса: он учитывает только ось Oy, а в какую сторону угол направлен по Ox - ему не интересно. Я это учёл, немного усложнив код, но Math.atan2 здесь действительно лучше смотрится, исправил. Но дело, к сожалению, не в этом: поворот и перенос работают без нареканий. Их можно убрать, тогда средний отрезок будет лежать на Ox, начиная от нуля, но скачки так и останутся.

Нужный угол у меня ищется так: на окружности выбираются три точки на равном расстоянии друг от друга (т. е. шаг = 2/3 пи, а точки - 0, -2/3 пи и +2/3 пи), для каждого выбранного угла считается соответствующее ему расстояние между началом и концом ломаной и сравнивается с данным в условии. На следующей итерации выбирается точка, где разница с данным расстоянием наименьшая, величина шага уменьшается вдвое, проставляются точки и т. д. И так до достижения нужной точности. Однако в момент "скачка" разница оказывается меньше у другой точки, нежели до этого, хотя по анимации видно, что ломаная ещё легко может растягиваться далее. Т. е. решений у уравнения несколько, но вот преобразовать одно в другое и просто выбрать нужное - проблема.

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение18.06.2019, 02:28 
Заслуженный участник


27/04/09
28128
Ага, спасибо, теперь понятно! Да, так просто не исправить…

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение18.06.2019, 22:51 
Аватара пользователя


26/05/12
1534
приходит весна?
Rusich в сообщении #1399845 писал(а):
Т. е. решений у уравнения несколько, но вот преобразовать одно в другое и просто выбрать нужное - проблема.


У вас есть неявная функция, которая зависит от параметров уравнения (они являются её аргументами). Изучите поведение этой функции, тогда вы сможете правильно выбрать интересующие вас корни. А так поиск корней в лоб даст гладкое решение только в случае однозначной функции. Там ещё может быть такая проблема: при варьировании параметра два решения схлопываются и исчезают (функция меняет свою "значность").

 Профиль  
                  
 
 Re: Построить ломаную (задача о кошачьей ноге)
Сообщение03.09.2019, 19:04 


13/06/19
13
В общем, исхожу из того, что программка строит отрезки правильно, значит, формула скорее всего верная. Если собрать это до кучи, то выглядит эта функция так:

$f(\alpha) = \sqrt{(\cos(\alpha) \cdot L1 - (L2 - \cos(\pi - (\pi - \alpha) \cdot C) \cdot L3)) ^ 2 + (\sin(\alpha) \cdot L1 + \sin(\pi - (\pi - \alpha) \cdot C) \cdot L3) ^ 2}$,

где Lx - длины отрезков по порядку, C - соотношение углов. Здесь нужно найти значения угла, когда функция равна расстоянию от начала до конца ломаной (в коде - отнимаем это расстояние и берём модуль, ищем, когда будет как можно ближе к 0). Т. е. нужно найти, когда $f(\alpha)=R$, где $R=\sqrt{(x1 - x2) ^ 2 + (y1 - y2) ^ 2}$.

Ну, значит, смотрим, как это выглядит визуально, пусть параметры будут 1, 1, 1 и -1,5 соответственно, а R = 1,2:

Изображение

Красными линиями выделен интервал угла $-\pi:\pi$, зелёной - условное значение R, пересечения её с синей - решения. Пока не очень представляю, как их искать (кроме как наитупейшим перебором, что неприменимо на практике). Да и сама функция интересная - у неё период равен $4\pi$.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 29 ]  На страницу Пред.  1, 2

Модераторы: Модераторы Математики, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group