Форум программистов, компьютерный форум, киберфорум
Геометрия
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
10 / 10 / 1
Регистрация: 04.11.2009
Сообщений: 147
1

Создание буфера линии

11.03.2014, 18:21. Показов 1091. Ответов 11
Метки нет (Все метки)

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

Буфер - это область, которая находится от всех точек линии на одинаковом расстоянии, называемом радиусом. (картинка прилагается, красными точками обозначены исходные данные)
Создание буфера линии


алгоритм построения в моей голове такой:
1) строим точки, перпендикулярные данным. По две штуки на каждую. Они будут отделять нашу полуокружность.
2)затем с помощью полярных координат проходим период от 0 до 180 радусов с неким промежутком и рисуем точки
3)повторяем тоже самое для другой точки.


context нужен для вывода. На данный момент проблема в начальных значениях угла поворота. Я не могу понять, каким он должен быть, как его рассчитать. Здесь для примера значится вспомогательный угол b, он рассчитывался для определения двух точек. Пробовала также вариант с atan(y/x) для точки, с которой начинается построение дуги - st.p1
Вот код:

Javascript
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
function createPolygon(start, end, radius){
    
    var polygon=[];
    //это рисуем две исходные точки
    var canv = document.getElementById("c");
    var context = canv.getContext('2d');
    context.fillRect(start[0], start[1], 2, 2);
    context.fillRect(end[0], end[1], 2, 2); 
    
    //здесь определяем две точки, перпендикулярные исходным
    var st={}; var en={};
    
    var tg = (end[1]-start[1])/(end[0]-start[0]);
    var l = Math.atan(tg);
    var b;
    
    if(l<0){
        b = 2*Math.PI-Math.PI/2-Math.abs(l);
    } else{
        b = 2*Math.PI-Math.PI/2+(l);
    }
    
    var xd = Math.cos(b)*radius;
    var yd = Math.sin(b)*radius;    
    
    st={p1:[start[0]+xd, start[1]+yd],p2:[start[0]-xd, start[1]-yd]};
    en={p1:[end[0]+xd, end[1]+yd],p2:[end[0]-xd, end[1]-yd]};
    
    polygon.push(st.p1);
    
//строим дугу с помощью полярных координат. Задаем начальный угол и правила обхода в 
//2-х вариантах *по часовой и против часовой стрелки
 
    if ((l>=0 && start[1]>=end[1])||(l<0 && start[1]<end[1])){
        for (var i=b; i<b+ Math.PI; i=i+Math.PI/4){
            xn  =   radius*Math.cos(i)+start[0];
            yn  = radius*Math.sin(i)+start[1];
            polygon.push([xn,yn]);
        }
    }else{
        for (var i=-b; i>-b-Math.PI; i=i-Math.PI/4){
            xn  =   -radius*Math.cos(i)+start[0];
            yn  = -radius*Math.sin(i)+start[1];
            polygon.push([xn,yn]);
        }
    }
//выводим окружность и найденные точки  
    context.fillRect(st.p1[0], st.p1[1],2,2);
    context.fillRect(st.p2[0], st.p2[1],2,2);
    context.fillRect(en.p1[0], en.p1[1],2,2);
    context.fillRect(en.p2[0], en.p2[1],2,2);
    
    context.fillStyle="red";
    for (var i=0; i<polygon.length; i++){
            context.fillRect(polygon[i][0],polygon[i][1],2,2);
    }
    
    
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.03.2014, 18:21
Ответы с готовыми решениями:

Создание бесконечно большого буфера
Подскажите как создать временный буфер для целых чисел. Размер буфера заранее не известен и...

Создание буфера хранения checkBox
Всем добра! Помогите пожалуйста. Перечитал всевозможные форумы, но так и не нашел адекватного...

Создание буфера обмена для Текстового редактора
делаю курсовик на qt пишу текстовый редактр, нужно создать буфер обмена, а я в этом вообще никак,...

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

11
Эксперт по математике/физике
3908 / 2899 / 880
Регистрация: 19.11.2012
Сообщений: 6,015
12.03.2014, 07:00 2
Цитата Сообщение от Sweet_Sleep Посмотреть сообщение
прямой линии, для которой известны точки начала и конца.
Цитата Сообщение от Sweet_Sleep Посмотреть сообщение
строим точки, перпендикулярные данным.
Кажется, это не совсем геометрия. Впрочем, настаивать не стану - может быть где-то такая терминология и используется.
0
5 / 0 / 0
Регистрация: 23.10.2013
Сообщений: 3
12.03.2014, 14:08 3
Ну, да. Терминология моя далека от идеала.
"Прямая линия, которая строится по двум точкам" Одна из точек является началом отрезка, вторая - концом отрезка прямой, вокруг которого необходимо построить буфер.
0
Диссидент
Эксперт C
26354 / 16360 / 3558
Регистрация: 24.12.2010
Сообщений: 36,230
12.03.2014, 14:36 4
Цитата Сообщение от sindzirarenai Посмотреть сообщение
Терминология моя далека от идеала.
Самокритика приветствуется.
Цитата Сообщение от Sweet_Sleep Посмотреть сообщение
Буфер - это область, которая находится от всех точек линии на одинаковом расстоянии, называемом радиусом.
Тут тоже много неточностей. Если "линия" - это множество точек вашего отрезка, то "буфер", если следовать данному определению, вся плоскость c выдолбленным "корытом".
Если ваша линия "вырождается" в точку, то "буфер" - все что лежит на и вне окружности радиуса R.
Я правильно понял ваши определения?
И понимаете ли вы, что такое расстояние от точки до области (множества)?
0
Модератор
Эксперт по математике/физике
6331 / 4046 / 1502
Регистрация: 09.10.2009
Сообщений: 7,541
Записей в блоге: 4
12.03.2014, 15:19 5
Лучший ответ Сообщение было отмечено Sweet_Sleep как решение

Решение

По вашему рисунку: пусть координаты нижней красной точки https://www.cyberforum.ru/cgi-bin/latex.cgi?\left(x_0;y_0 \right), верхней красной - https://www.cyberforum.ru/cgi-bin/latex.cgi?\left(x_1;y_1 \right) (не знаю Джава Скрипт, потому не разобрался, как эти точки у вас заданы в коде). Длину этого отрезка обозначим через L (она вычисляется по формуле https://www.cyberforum.ru/cgi-bin/latex.cgi?L=\sqrt{\left(x_1-x_0 \right)^2+\left(y_1-y_0 \right)^2}), а радиус вашей полуокружности r.
Тогда вектор с началом в https://www.cyberforum.ru/cgi-bin/latex.cgi?\left(x_1;y_1 \right), описывающий нужную вам полуокружность, будет иметь координаты https://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{r}{L}\left(\left(y_1-y_0 \right)\cos\alpha+\left(x_1-x_0 \right)\sin\alpha ;\; \left(y_1-y_0 \right)\sin\alpha-\left(x_1-x_0 \right)\cos\alpha \right). Угол https://www.cyberforum.ru/cgi-bin/latex.cgi?\alpha \in [0;\pi]. Значению 0 радиан соответствует правая-верхняя синяя точка, значению ПИ радиан - левая-нижняя точка. Обход этого вектора делается против часовой стрелки. Начальное положение (при угле 0) бралось так, чтобы направление вектора с концом в синей точке получалось от направления вектора вашего данного отрезка (из нижней точки в верхнюю) поворотом по часовой стрелке.... Если словами не поймете объяснения, я нарисую рисунок. Чтобы получить координаты самих синих точек (концов вектора), нужно к координатам вектора обхода прибавать координаты его начала (https://www.cyberforum.ru/cgi-bin/latex.cgi?\left(x_1;y_1 \right)).

Добавлено через 28 минут
Чтобы сделать то же самое для нижней красной точки, нужно везде поменять местами нижние индексы 0 и 1 координат х и у. Длина L остается той же, естественно. Обход вектора с началом в нижней красной точке и концами в синих точках будет тоже против часовой стрелки - от левой-нижней синей точки до правой-верхней.
2
Эксперт по математике/физике
3908 / 2899 / 880
Регистрация: 19.11.2012
Сообщений: 6,015
12.03.2014, 16:46 6
Пока автор молчит - еще догадка. Эту ли область он имеет ввиду:
Создание буфера линии
0
10 / 10 / 1
Регистрация: 04.11.2009
Сообщений: 147
12.03.2014, 19:25  [ТС] 7
Буфер - это фигура, вершины которой находятся на одинаковом расстоянии от рассматриваемой линии (если иметь в виду кратчайшее расстояние до линии). Данное расстояние называется радиусом. Так лучше?

Добавлено через 26 секунд
Все совершенно правильно вы дорисовали. Это искомая фигура.

Добавлено через 2 минуты
jogano, Огромное спасибо! Бегу реализовывать и смотреть результаты! Если будут возникать вопросы, то я, надеюсь, могу к Вам обратиться?
0
2657 / 1348 / 226
Регистрация: 26.02.2009
Сообщений: 6,379
Записей в блоге: 5
12.03.2014, 19:52 8
Вот поупражнялся и вспомнил немного JS:
Кликните здесь для просмотра всего текста
Javascript
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
Line.prototype.DrawBuf = function(ctx, radius)
{
    var pR = this.Dir().Perp().Normalize().Mul(radius);
    var pL = pR.Perp().Perp();
    
    var pRA = pR.Add(this.A);
    var pRB = pR.Add(this.B);
    var pLA = pL.Add(this.A);
    var pLB = pL.Add(this.B);
    
    ctx.strokeStyle = this.bufcolor;
    ctx.beginPath();
    ctx.moveTo( pRA.x, pRA.y );
    ctx.lineTo( pRB.x, pRB.y );
    ctx.moveTo( pLA.x, pLA.y );
    ctx.lineTo( pLB.x, pLB.y );
    ctx.stroke();
    
    var xAxis = new vec2( 1, 0 );
    var startR = xAxis.Dot( pR.Normalize() );
    var sk = xAxis.Skew( pR.Normalize() );
    var angleR = Math.acos( startR );
    if( sk < 0 ){
        angleR = 2.0*Math.PI - angleR;
    }
    ctx.beginPath();
    ctx.arc( this.A.x, this.A.y, radius, angleR, angleR+Math.PI, false );
    ctx.stroke();
    
    ctx.beginPath();
    ctx.arc( this.B.x, this.B.y, radius, angleR, angleR+Math.PI, true );
    ctx.stroke();
}
Миниатюры
Создание буфера линии  
Вложения
Тип файла: rar bufline.rar (1.2 Кб, 3 просмотров)
1
Модератор
Эксперт по математике/физике
6331 / 4046 / 1502
Регистрация: 09.10.2009
Сообщений: 7,541
Записей в блоге: 4
12.03.2014, 20:01 9
Sweet_Sleep, можете.
Вот еще ловите уравнения параллельных прямых:
https://www.cyberforum.ru/cgi-bin/latex.cgi?y=\frac{y_1-y_0}{x_1-x_0}\left(x-x_0-\frac{r}{L}\left(y_1-y_0 \right) \right)+y_0-\frac{r}{L}\left(x_1-x_0 \right),\; x \in [x_0+\frac{r}{L}\left(y_1-y_0 \right);\; x_1+\frac{r}{L}\left(y_1-y_0 \right)]
и
https://www.cyberforum.ru/cgi-bin/latex.cgi?y=\frac{y_1-y_0}{x_1-x_0}\left(x-x_0+\frac{r}{L}\left(y_1-y_0 \right) \right)+y_0+\frac{r}{L}\left(x_1-x_0 \right),\; x \in [x_0-\frac{r}{L}\left(y_1-y_0 \right);\; x_1-\frac{r}{L}\left(y_1-y_0 \right)]
Это если https://www.cyberforum.ru/cgi-bin/latex.cgi?x_1>x_0, а если меньше, то концы отрезков по х поменять местами. Если https://www.cyberforum.ru/cgi-bin/latex.cgi?x_1=x_0 (ваш отрезок вертикальный), то уравнения этих прямых сильно упрощаются:
https://www.cyberforum.ru/cgi-bin/latex.cgi?x=x_0\pm r,\; y\in [min\left(y_0;y_1 \right);\; max\left(y_0;y_1 \right) ]
1
10 / 10 / 1
Регистрация: 04.11.2009
Сообщений: 147
12.03.2014, 20:28  [ТС] 10
Цитата Сообщение от snake32 Посмотреть сообщение
Вот поупражнялся и вспомнил немного JS:
Спасибо за труды, но мне нужны конкретно точки, а не рисунок. В дальнейшем эти точки отправятся в запрос.
В вашем, если я правильно поняла, случае, вы используете функцию arc для рисования дуги.
0
2657 / 1348 / 226
Регистрация: 26.02.2009
Сообщений: 6,379
Записей в блоге: 5
12.03.2014, 21:37 11
Цитата Сообщение от Sweet_Sleep Посмотреть сообщение
В вашем, если я правильно поняла, случае, вы используете функцию arc для рисования дуги.
Да. Правильно поняли. Надеюсь вам не составить труда переписать код заменив arc своей ф-ией заполнения массива координатами.
0
10 / 10 / 1
Регистрация: 04.11.2009
Сообщений: 147
13.03.2014, 14:33  [ТС] 12
jogano , еще раз большое спасибо) все получилось=)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.03.2014, 14:33

Создание 2 линии
Имеется 2 линии на которых бригады используют единственный кран штабелер . Но и другая бригада...

Создание линии на фотографии
Добрый вечер, форумчане! Появилась необходимость нарисовать линию в чёрно-белой фотографии с ...

создание линии тренда
Всем доброго времени суток! подскажите пожалуйста, в общем проект импортирует таблицу из Exsel и по...

Создание произвольной линии
Здравствуйте. У меня возникла проблема: Требуется на квадратном поле (скорее всего буду...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru