Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как строить равномерно спираль? казалось бы просто, ан нет! 
:(
    Опции темы
Proger10
Дата 19.6.2009, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 16.12.2008

Репутация: нет
Всего: нет



Цель такая - построить спираль. Но не просто построить, а равномерным шагом и равным расстоянием между витками.

Обычно спираль ведь строится по радианам, т.о. получается на ближних витках спирали расстояние от точки до точки меньше, чем далее от центра. 
А вот как сделать так, чтобы спираль строилась равномерными отрезками?

Алгоритм такой:
1. Знаем длину дуги (наш равномерный отрезок), получаем угол: alpha = ( L * 180 ) / ( PI * R ); // угол в градусах, L - длина дуги
Терь мы знаем на каждой точке нужный угол в градусах.
2. Переводим в радианы
3. Строим в полярных координатах.
4. Смотрим результат - спираль получается не с равными расстояниями между витками, но зато она строится ровным шагом. Это уже пол победы.
Но как сделать так, чтобы и расстояние между витками было всегда равное?

Смотрите, что сейчас получается: http://s50.radikal.ru/i129/0906/51/08c18a30c2a3.png

при вот таких параметрах: 
R += 0.0001; // картинка слева 
R += 0.001; // картинка справа (на скриншоте)

Есть идеи?

Вот код на OpenGL:
Код
double L = 0.01;
double R = 0.01; 

for( int i = 0; i < currSliderValue; i += 1 ) { // количество витков

    double gradusAngle = ( L * 180 ) / ( M_PI * R );
    double radianAngle = gradusAngle * ( M_PI / 180 );

    printf( "%i: radianAngle = %f, gradusAngle = %f\n", i, radianAngle, gradusAngle );

    for( double i2 = 0; i2 < 2 * M_PI; i2 += radianAngle ) {

        double x = R * cos( i2 );
        double y = R * sin( i2 );

        int rnd1 = int( ( double( rand() ) / RAND_MAX ) * 255 );
        int rnd2 = int( ( double( rand() ) / RAND_MAX ) * 255 );
        int rnd3 = int( ( double( rand() ) / RAND_MAX ) * 255 );

        glColor3ub( rnd1, rnd2, rnd3 );
        glVertex2f( x, y );

        // R += 0.0001; // картинка слева
        R += 0.001; // картинка справа (на скриншоте)

    }

}



Это сообщение отредактировал(а) Proger10 - 19.6.2009, 23:25
PM MAIL   Вверх
DRUID3
Дата 20.6.2009, 04:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 463
Регистрация: 20.6.2005
Где: Kyyiv

Репутация: 2
Всего: 9



Цитата(Proger10 @  19.6.2009,  16:53 Найти цитируемый пост)
Но как сделать так, чтобы и расстояние между витками было всегда равное?

Спираль можно представавить как материальную точку прямолинейно(и с постоянной скоростью, для Вашего случая) движущуюся на плоскости которая вращается.



Это сообщение отредактировал(а) DRUID3 - 20.6.2009, 04:45


--------------------
Every time if you use Linux, you are joined to the communism...
практика - критерий истины ... отделенной от нас пропастью субъективного восприятия...
PM MAIL WWW Skype   Вверх
Proger10
Дата 20.6.2009, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 16.12.2008

Репутация: нет
Всего: нет



Не понял.. что значит с постоянной скоростью? С постоянным радиусом? Тогда получится окружность.. smile
Проблема в том, что я не знаю в какой именно момент нужно увеличивать радиус-расстояние R..
PM MAIL   Вверх
DRUID3
  Дата 20.6.2009, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 463
Регистрация: 20.6.2005
Где: Kyyiv

Репутация: 2
Всего: 9



Цитата(Proger10 @  20.6.2009,  12:14 Найти цитируемый пост)
Не понял.. что значит с постоянной скоростью? С постоянным радиусом? Тогда получится окружность..

Вы еще школьник? smile 


--------------------
Every time if you use Linux, you are joined to the communism...
практика - критерий истины ... отделенной от нас пропастью субъективного восприятия...
PM MAIL WWW Skype   Вверх
Proger10
Дата 20.6.2009, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 16.12.2008

Репутация: нет
Всего: нет



К сожалению, нет smile

Ну так подсказать можете?
PM MAIL   Вверх
DRUID3
  Дата 20.6.2009, 18:25 (ссылка) |  (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 463
Регистрация: 20.6.2005
Где: Kyyiv

Репутация: 2
Всего: 9



Вообще-то подсказал. И радиус там не постоянен(неужели скорость, по-вашему, равна абсолютной длинне радиус-вектора? smile ) - а постоянно линейно растет. Или Вы хотите исходный код? Заранее говорю - я очень ленивый...  smile 


--------------------
Every time if you use Linux, you are joined to the communism...
практика - критерий истины ... отделенной от нас пропастью субъективного восприятия...
PM MAIL WWW Skype   Вверх
AVA12
Дата 20.6.2009, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 4.5.2008

Репутация: 1
Всего: 4



Proger10, попробуй вместо 0.001 прибавлять 1/1024 и посмотри, что получится.
PM ICQ Jabber   Вверх
Proger10
Дата 20.6.2009, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 16.12.2008

Репутация: нет
Всего: нет



Цитата(DRUID3 @ 20.6.2009,  18:25)
И радиус там не постоянен(неужели скорость, по-вашему, равна абсолютной длинне радиус-вектора? smile ) - а постоянно линейно растет.

В этом у меня проблема - в том, что он постоянно растёт. А мне этого не нужно, т.к. я хочу получить равные расстояния между двумя витками.. т.е. чтобы в спирали все витки были бы параллельными друг другу.

AVA12, а что должно-то произойти? Какая разница какую именно константу приращивать?
Вообще с: 
R += 1 / 1024;
у меня получилась окружность smile потому как R почему-то не приращивается.. кстати, не пойму почему так происходит smile
Это свойство как-то можно заюзать для решения такой задачи?

А принудительно заменив на:
R += 0.0009765625;
я получил тоже, что и на картинках у меня в первом посте..
PM MAIL   Вверх
Soah
Дата 20.6.2009, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 5
Всего: 54



Цитата(Proger10 @  20.6.2009,  18:52 Найти цитируемый пост)
 кстати, не пойму почему так происходит

Результат деления целых — целое, с округлением к нулю.
R += 1.0 / 1024;

Как нарисовать сходящуюся спираль в OpenGL
Архимедова спираль
PM MAIL   Вверх
Proger10
Дата 20.6.2009, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 16.12.2008

Репутация: нет
Всего: нет



Цитата(Soah @ 20.6.2009,  19:08)
Цитата(Proger10 @  20.6.2009,  18:52 Найти цитируемый пост)
 кстати, не пойму почему так происходит

Результат деления целых — целое, с округлением к нулю.
R += 1.0 / 1024;

Как нарисовать сходящуюся спираль в OpenGL
Архимедова спираль

Вы про вот эту формулу? http://upload.wikimedia.org/math/1/3/3/133...d92329d92fc.png
А что здесь phi? Угол ведь..? Как он вычисляется? А если не вычисляется, а задаётся - тогда совершенно не ясно, что означает шаг спирали smile
Покуда, если мы задаём фиксированно угол - тогда шаг (длина очередной прирощенной дуги) будет постоянно увеличиваться с ростом угла phi..

Добавлено через 9 минут и 20 секунд
Вот здесь какая-то ошибка:
Код
for( double i2 = 0; i2 < 2 * M_PI; i2 += radianAngle ) {
//for( double i2 = 0; i2 < 2 * M_PI; i2 += 0.1 ) {

Первая строчка рисует расходящуюся спираль, но одинаковым шагом.
Вторая сточка рисует сходящуюся (с одинаковыми расстояниями между спиралями), но с разным шагом..

Как же учесть оба условия?
PM MAIL   Вверх
Soah
Дата 20.6.2009, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 5
Всего: 54



PM MAIL   Вверх
Proger10
Дата 20.6.2009, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 16.12.2008

Репутация: нет
Всего: нет



Похоже внутри цикла радиус нужно инкрементировать не на постоянную величину, а на какую-то переменную.. вот только на какую..

Добавлено через 8 минут и 8 секунд

Глянул мельком.. а разве это то?
Мне нужно не просто ровную спираль, но и чтобы она одинаковым шагом шла. Т.е. угол нужно постоянно перевычислять... Да и не только угол, но и радиус..

Добавлено через 9 минут и 44 секунды
Обычные спирали, с равными расстояниями между витками - рисуются просто. Но у них по ходу построения точки изначально скачут медленно, а потом так ускоряются, что мало не кажется smile У меня задача не в рисовании заключается, а в построении..
PM MAIL   Вверх
Proger10
Дата 20.6.2009, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 16.12.2008

Репутация: нет
Всего: нет



Пробовал вот так:
R += ( L / ( 2 * M_PI ) ) * i2;
Но витки расходятся ещё быстрее..
PM MAIL   Вверх
Proger10
Дата 20.6.2009, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 16.12.2008

Репутация: нет
Всего: нет



В общем, у меня получилось.

Формула такая:
R = ( L / ( 2 * M_PI ) ) * i * 5 + ( i2 * ( L / 4.4 ) );

4.4 - не понял как у меня получилось. Подобрал перебирая числа и сравнивая результат.
5 - ширина между витками.

Теперь соблюдены два условия:
- одинаковый шаг дуги: L
- одинаковая ширина между витками

Кто-нибудь прокомментирует? smile
PM MAIL   Вверх
Dims
Дата 24.7.2009, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 1
Всего: 11



Вы прочитали в Википедии статью "Спираль"? Спиралей существует несколько видов и у каждой существует своя формула в полярных координатах. 

Ваша спираль называется "архимедова", её формула такая

r = k * fi

где k -- сдвиг на 1 радиан.

Если хотите указывать сдвиг на один оборот, то формула такая

r = a * fi / (2 * pi)

Разница несущественна.

Везде fi -- это полярный угол. В радианах. Про градусы вообще забудьте. 

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

Код


double step = 0.1; // в радианах
double n = 10; // количество оборотов, в штуках
double a = 10; // сдвиг по радиусу на один оборот, в пикселях

double R; // радиус -- зависимая переменная, меняется в зависимости от угла

// пробегаем независимую переменную (угол) в радианах
// один оборот -- это два-пи радиан, поэтому пробегаем до 2*M_PI*n -- сколько надо оборотов
for( double ugol=0; ugol<2*M_PI*n; ugol+=step) {

        // для текущего значения независимой вычисляем зависмую
       R = a*ugol/2/M_PI;

      // всё! точка (ugol, R) вычислена
     // переводим в декартовы
        double x = R * cos( ugol );
        double y = R * sin( ugol );

/// рисуем
}



Это сообщение отредактировал(а) Dims - 24.7.2009, 14:51
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0511 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.