Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Программирование игр для компьютеров > Blitz3D > 2D-программирование

2D-программирование Вопросы, касающиеся двумерного программирования

Ответ
 
Опции темы
Старый 03.10.2015, 23:58   #1
DarkInside
Разработчик
 
Аватар для DarkInside
 
Регистрация: 07.08.2011
Сообщений: 504
Написано 190 полезных сообщений
(для 368 пользователей)
Пунктирная окружность

Приветствую, форумчане!

Появилась необходимость рисовать пунктирную окружность. При этом она должна состоять не из точек, а из линий длиной 4 пикселя и промежуток между ними 2 пикселя.
Поиск ничего не дал. Четыре часа ломал голову, вспоминал формулы окружности. Либо я туплю, либо что-то не учитываю, но если просто рисовать точками (а потом разделить их на отрезки) по функции y = +-Sqr (r^2-x^2), то при y, приближающемся к нулю, точки почему-то не все прорисовываются. В итоге пришлось разбить окружность на 4 части и рисовать по-отдельности. Второй момент: длина окружности ведь 2*Пи*r, если разделить на 4 части и еще на 2 (отрицательные и положительные значения), то цикл должен выглядеть так: For x = -Пи*r/4 To Пи*r/4. То есть получаем Пи/4 = 0,7854*r. Но при таком значении части окружности почему-то накладываются друг на друга. Подобрал экспериментально число 0.7067. Откуда оно взялось непонятно. В математике такого нет.
В общем, вот то, на что меня хватило:
Проблемы следующие:
1) вроде делаю шаг 4 пикселя (целочисленное деление), а получаются линии по 8 пикселей. Промежуток 5 пикселей (хотя при 8 должен быть 4, если в 2 раза меньше).
2) при радиусе 100 вроде окружность выглядит нормально, а вот при радиусе 200 и более стыки между четырьмя её частями сливаются.
Может кто подскажет решение попроще и поэлегантнее?
Ну или может кто заметит косяк, а то я совсем запутался, уже на бумаге всё разрисовал, а в коде не получается

Graphics 800,600,32

Dim kr_x 
(1)
Dim kr_y (1)

While 
Not KeyHit(1
    
    
Color 255255255
    
    
If KeyHit (57Then dotted_circle (400300100)
    
Wend  

Function dotted_circle (dxdyr)
    
For 
= -0.7067*r To 0.7067*r
    y 
Sqr (r^x^2)
    If 
x Mod 4 0 Then 
        rf 
rf 1
    
EndIf
Next

Dim kr_x 
(rf)
Dim kr_y (rf)

For 
= -0.7067*r To 0.7067*r
    y 
Sqr (r^x^2)
    If 
x Mod 4 0 Then 
        kr_x 
(i) = x
        kr_y 
(i) = y
        i 
1
    
EndIf
Next

For 0 To rf Step 4
    Line kr_x 
(i) + dxkr_y (i) + dykr_x (i+2) + dxkr_y (i+2) + dy
    Line kr_x 
(i) + dx, -kr_y (i) + dykr_x (i+2) + dx, -kr_y (i+2) + dy
    Line kr_y 
(i) + dxkr_x (i) + dykr_y (i+2) + dxkr_x (i+2) + dy
    Line 
-kr_y (i) + dxkr_x (i) + dy, -kr_y (i+2) + dxkr_x (i+2) + dy
Next

rf 
00

End 
Function 
(Offline)
 
Ответить с цитированием
Старый 04.10.2015, 00:10   #2
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 03.09.2005
Сообщений: 14,014
Написано 6,795 полезных сообщений
(для 20,914 пользователей)
Ответ: Пунктирная окружность

y=r*sin(q)
x=r*cos(q)
При известном r оцениваешь значение шага для q. Генерируешь набор точек. Соединяешь линиями. всё
Блитца под рукой нет
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
DarkInside (04.10.2015)
Старый 04.10.2015, 00:27   #3
DarkInside
Разработчик
 
Аватар для DarkInside
 
Регистрация: 07.08.2011
Сообщений: 504
Написано 190 полезных сообщений
(для 368 пользователей)
Ответ: Пунктирная окружность

Спасибо! Проверил, работает.
Всё проще, оказывается. Обидно, что 4 часа провозился с разбиением окружности на части.
Хреново, когда не помнишь геометрию. Я даже не подумал про синусы косинусы, потому что их графики мне представляются в виде волны, а не окружности.

Graphics 800,600,32

While Not KeyHit(1
    
    
Color 255255255
    
    
For 1 To 1000 Step 4
        Plot 400
+200*Cos(q), 300+200*Sin(q)
    
Next
    
Wend 
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
impersonalis (04.10.2015)
Старый 04.10.2015, 04:02   #4
polopok
ПроЭктировщик
 
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений
(для 71 пользователей)
Ответ: Пунктирная окружность

Кстати , если кому надо , то ...
Функция Пунктирная линия с регулируемым шагом
- - - - - - - - - - - - - - - - - - - - - - - - -
шаг задаёт переменная offsete
Код под спойлером :
Function Interpolate#(stepInterpolate#, Pt_1#, Pt_2#)
    Return ((1.0-stepInterpolate)*Pt_1 + stepInterpolate *Pt_2)
End Function

Function StepLine#(sPt_x# ,sPt_y#, ePt_x# ,ePt_y# , R_ = 255,G_ = 255,B_ = 255 , offsete = 4)
offsete = Int(offsete )
If offsete <1 Then offsete =1
step_line# = 1.0 /((sPt_x- ePt_x)*(sPt_x- ePt_x) + (sPt_y- ePt_y)*(sPt_y- ePt_y))^0.5 *offsete 
local_step_line# = 0.0
local_step_line_2# = local_step_line# - step_line 
While local_step_line<1.0
    local_x# = Interpolate#(local_step_line, sPt_x, ePt_x)
    local_y# = Interpolate#(local_step_line, sPt_y, ePt_y)
    
    local_step_line_2 = local_step_line + step_line    
    If local_step_line_2 < 0.0 local_step_line_2 = local_step_line
    
    local_x2# = Interpolate#(local_step_line_2, sPt_x, ePt_x)
    local_y2# = Interpolate#(local_step_line_2, sPt_y, ePt_y)    
    switch = Not switch 
    If switch     
                Color R_ ,G_ ,B_
                Line local_x , local_y ,local_x2 , local_y2
    EndIf 
    local_step_line = local_step_line + step_line
    
Wend     
End Function
__________________
Мой проект здесь
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
DarkInside (04.10.2015)
Старый 04.10.2015, 20:42   #5
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 03.09.2005
Сообщений: 14,014
Написано 6,795 полезных сообщений
(для 20,914 пользователей)
Ответ: Пунктирная окружность

Сообщение от DarkInside Посмотреть сообщение
Спасибо! Проверил, работает.
Пожалуйста. Зашёл в тред - думал будет не довольный коммент про лапидарность моего ответа. Уже думал набросать код именно с линиями (т.е. аппроксимацию окружности отрезками, а не кривыми [образованными точками] как сейчас) - а тут оказывается уже всё решилось. Обращайся.

По коду:


For q = 1 To 360 Step 4

upd: правомочное уравнение r^2=x^2+y^2 (упомянутое тобой) удобно использовать для определения принадлежности заданной точки указанной кривой (окружности). Само по себе оно корректно, просто, для данной задачи неудобно. Надо будет перебрать значения от 0 до r => получить два y => отражением получить из каждого ещё по точке -т.о. получить 4 точки. Проблема в том, что двигаться по х надо неравномерно (т.к. производная от sin, по которой изменяется прирост y - cos, а не прямая) если тебе нужно выдерживать постоянную длину штриха.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
DarkInside (04.10.2015)
Старый 05.10.2015, 03:03   #6
polopok
ПроЭктировщик
 
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений
(для 71 пользователей)
Ответ: Пунктирная окружность

Функция окружность пунктиром с регулируемым шагом .
DarkInside , если у тебя не получилось , то посмотри этот

Код под спойлером :

Function StepCircle(Point_X# ,Point_Y# ,Radius# = 1,Offset = 4 , rr% = 255 ,gg% = 255 ,bb% = 255)
    Local angle = 0 , trigger
    If Offset < 1 Offset = 1
    While  angle  < 360 
        If trigger
            For thisAngle# = angle  To angle  +Offset  Step 0.1
                x# = Radius * Cos (thisAngle) + Point_X# 
                y# = Radius * Sin (thisAngle) + Point_Y#     
                WritePixel x,y, (rr*$10000+gg*$100+bb)
            Next
        EndIf
        angle  = angle  + Offset  
        trigger = Not trigger
    Wend
End Function
__________________
Мой проект здесь
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
DarkInside (06.10.2015)
Старый 06.10.2015, 07:17   #7
DarkInside
Разработчик
 
Аватар для DarkInside
 
Регистрация: 07.08.2011
Сообщений: 504
Написано 190 полезных сообщений
(для 368 пользователей)
Ответ: Пунктирная окружность

polopok, да я уже вроде как написал самопальную функцию. Но спасибо, посмотрю.
(Offline)
 
Ответить с цитированием
Старый 06.10.2015, 20:22   #8
moka
.
 
Регистрация: 04.08.2006
Сообщений: 10,429
Написано 3,453 полезных сообщений
(для 6,859 пользователей)
Ответ: Пунктирная окружность

Вот смотри, код доступен, рендер есть (ничего не нужно запускать, 1 клик по ссылке), кто хочет сейчас может код обновить и выложить ссылку на его ввариант. Удобно же!

Пунктирная окружность с регулируемым градусом дуги:
http://jsfiddle.net/bq6vvqch/

И еще версия с гарантированной последовательностью отступ > дуга, и чтобы не было где-то одного мелкого/большого отступа.
Также анимировано: http://jsfiddle.net/o8xkde88/1/

Можно еще сделать чтобы дуга могла удлиняться/укорачиваться, но гарантированно иметь одной длины отступы и другой единой длины дуги. Таким образом переход между разным числом дуг будет более плавный.

var canvas document.getElementById('render');
var 
ctx canvas.getContext('2d');

// step of 15 degrees in radians
var step / (180 Math.PI);

for(var 
0Math.PI step+= 2) {
    var 
step;
    
ctx.beginPath();
    
ctx.arc(canvas.width 2canvas.height 2canvas.width 8astepfalse);
    
ctx.stroke();

(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
DarkInside (07.10.2015)
Старый 07.10.2015, 01:30   #9
polopok
ПроЭктировщик
 
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений
(для 71 пользователей)
Ответ: Пунктирная окружность

ага ,нормально ...
Да ,вот что, в приведённой мною функции ,переменную offset проверить ,что она меньше длины круга (2 * Pi * Radius ).
__________________
Мой проект здесь
(Offline)
 
Ответить с цитированием
Старый 07.10.2015, 07:41   #10
DarkInside
Разработчик
 
Аватар для DarkInside
 
Регистрация: 07.08.2011
Сообщений: 504
Написано 190 полезных сообщений
(для 368 пользователей)
Ответ: Пунктирная окружность

Всем спасибо за примеры. За ссылку на сервис отдельное спасибо, удобная вещь.

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

Последний раз редактировалось DarkInside, 12.10.2015 в 15:45.
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +1, время: 03:02.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com