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

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



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

Сейчас этот форум просматривают: kthxbye


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

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