|
2D-программирование Вопросы, касающиеся двумерного программирования |
31.05.2014, 13:44
|
#1
|
ПроЭктировщик
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений (для 71 пользователей)
|
простой ray casting 2d array hit
Думаю и этот код будет полезен ...
Код в Offtop :
ttt = CreateTimer(60)
;SeedRnd(MilliSecs())
Const numT=10 , sizeT = 20
Dim AA(numT*numT,numT*numT)
Graphics 640,480
SetBuffer BackBuffer()
x2#=130 :y2#=130
x1 =x2 : y1=y2
For b =0 To numT
For a =0 To numT
AA(a,b) = Rnd (1 )
Next
Next
While Not KeyHit(1)
Cls ; Сначала очищаем экран
x2 =MouseX() : y2=MouseY()
CamFOV#= (180+ATan2(x1-x2,y1-y2))
If MouseHit(1) Then x1 =MouseX() : y1=MouseY()
WaitTimer(ttt)
For angle#= 0 To 360 Step 2
x3# = 40+200*Sin#(angle)
y3# = 150+200*Cos#(angle)
line2(40,150,x3,y3,25,25,125)
Next
For angle#= 30 To -30 Step -0.09
x2# = x1+200*Sin#(CamFOV-angle)
y2# = y1+200*Cos#(CamFOV-angle)
line2(x1,y1,x2,y2,255,25,25)
Next
For b =0 To numT
For a =0 To numT
If AA(a,b) = 1 Then Rect a*sizeT ,b*sizeT ,sizeT ,sizeT ,0
If AA(a,b) = 2 Then Rect a*sizeT ,b*sizeT ,sizeT ,sizeT ,1
If AA(a,b) = 2 Then AA(a,b) = 1
Next
Next
Line x1,y1,x2,y2
Line x1,y1,x1+200*Sin(CamFOV-30),y1+200*Cos(CamFOV-30)
Line x1,y1,x1+200*Sin(CamFOV),y1+200*Cos(CamFOV)
Flip ; Меняем буфер
Wend
FreeTimer(tttt)
End
Function line2(x1#,y1#,x2#,y2#,red=-1,green=-1,blue=-1)
Local StopLine = 0
If red>0 And green=-1
rgb=red
Else If red=-1
rgb = ColorBlue() Or ( ColorGreen() Shl 8) Or ( ColorRed() Shl 16)
Else
rgb=blue Or (green Shl 8) Or (red Shl 16)
EndIf
xd#=x2-x1
yd#=y2-y1
If Abs(xd)>Abs(yd) steps=Abs(xd) Else steps=Abs(yd)
x2=xd/Float(steps)
y2=yd/Float(steps)
; For Stepr=steps To 1 Step -1
While Not (x1=x2 And y1=y2) Or ( (StopLine = 1)) Or (Not ( x1 <=( numT*sizeT+sizeT) And y1 <=(numT*sizeT+sizeT) And x1>-2 And y1>-2))
WritePixel x1,y1,rgb
x = Floor(x1/sizeT) : y= Floor(y1/sizeT)
If ( x <=numT And y <=numT And x >=0 And y >=0)
If AA(x,y) =1 Or AA(x,y) =2 Then
AA(x,y) =2
StopLine = 1
Exit
EndIf
EndIf
x1=x1+x2
y1=y1+y2
; Next
Wend
End Function
Другой вариант :
;
ttt = CreateTimer(120)
;SeedRnd(MilliSecs())
Const numT=10 , sizeT = 20
Dim AA(numT*numT,numT*numT)
Graphics 800,600,32,2
SetBuffer BackBuffer()
x2#=130 :y2#=130
x1# =x2 : y1#=y2
For b =0 To numT
For a =0 To numT
AA(a,b) = Rnd (1 )
Next
Next
While Not KeyHit(1)
Cls
x2 =MouseX() : y2=MouseY()
If MouseDown(1) Then x1 =MouseX() : y1=MouseY()
WaitTimer(ttt)
RayCast2d(x1,y1,x2,y2)
For b =0 To numT
For a =0 To numT
If AA(a,b) = 1 Then Rect a*sizeT ,b*sizeT ,sizeT ,sizeT ,0
If AA(a,b) = 2 Then Rect a*sizeT ,b*sizeT ,sizeT ,sizeT ,1
If AA(a,b) = 2 Then AA(a,b) = 1
Next
Next
Flip
Wend
FreeTimer(tttt)
End
Function RayCast2d(x1#,y1#,x2,y2)
Local count,StopLine,angle#
dx# = x1-x2
dy#= y1-y2
a# = 180+ATan2(dy,dx) ;
For angle#= 30 To -30 Step -0.5
vx# = Cos(a+angle)
vy#= Sin(a+angle)
x0#= x1
y0#=y1
count=0 : StopLine =0
While (count<100) Or (StopLine = 1 )
WritePixel x0,y0,$00ffff
x = Floor(x0/sizeT) : y= Floor(y0/sizeT)
If ( x <=numT And y <=numT And x >=0 And y >=0)
If AA(x,y) =1 Or AA(x,y) =2 Then
AA(x,y) =2
StopLine = 1
Exit
EndIf
EndIf
x0# = (x0#+vx)
y0# =(y0#+vy)
count=count+1
Wend
Next
End Function
__________________
Мой проект здесь
Последний раз редактировалось polopok, 31.05.2014 в 15:25.
Причина: дополнение
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо polopok за это полезное сообщение:
|
|
31.05.2014, 18:27
|
#2
|
Мастер
Регистрация: 24.06.2009
Адрес: Набережные Челны
Сообщений: 930
Написано 292 полезных сообщений (для 504 пользователей)
|
Ответ: простой ray casting 2d array hit
Приложу картинки:
1 пример: синие лучи - обзор 360*, красные лучи - направляющий обзор, белые кубики - попадающие в препятствие перед лучами.
2 пример: лучи - с ограниченной дистанцией дальности обзора
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
02.06.2014, 21:10
|
#3
|
ПроЭктировщик
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений (для 71 пользователей)
|
Ответ: простой ray casting 2d array hit
Ну типо камера обзора 2д
Const RotateSpeed# = 5 , MoveSpeed# = 1
Global angleViewX# , angleViewY#
ttt = CreateTimer(120)
;SeedRnd(MilliSecs())
Const numT=10 , sizeT = 20
Dim AA(numT*numT,numT*numT)
Graphics 800,600,32,2
SetBuffer BackBuffer()
camPosX#=300
camPosY#=200
angleView#= 180
For b =0 To numT
For a =0 To numT
AA(a,b) = Rnd (1 )
Next
Next
While Not KeyHit(1)
Cls
;x2 =MouseX() : y2=MouseY()
If KeyDown(205) Then angleView# = angleView# +RotateSpeed ; RIGHT
If KeyDown(203) Then angleView# = angleView# -RotateSpeed ; LEFT
If KeyDown(200) Then camPosX# = camPosX# +MoveSpeed*angleViewX : camPosY# = camPosY# +MoveSpeed*angleViewY ; DOWN
If KeyDown(208) Then camPosY# = camPosY# +MoveSpeed* -angleViewY : camPosX# = camPosX# +MoveSpeed* -angleViewX ; UP
WaitTimer(ttt)
View2D(camPosX#,camPosY#,angleView#,offset=4)
For b =0 To numT
For a =0 To numT
If AA(a,b) = 1 Then Rect a*sizeT ,b*sizeT ,sizeT ,sizeT ,0
If AA(a,b) = 2 Then Rect a*sizeT ,b*sizeT ,sizeT ,sizeT ,1
If AA(a,b) = 2 Then AA(a,b) = 1
Next
Next
text 500,50,"Управляем стрелками клавитуры "
Flip
Wend
FreeTimer(tttt)
End
Function View2D#(camPosX#,camPosY#,angleView#,direction = 100)
IangleView =angleView Mod 360
newDirection# = direction *0.6
angleViewX# =Cos(angleView )
angleViewY#= Sin(angleView )
For CV# = 30 To -30 Step -1
camDirX# =camPosX
camDirY# =camPosY
vd =0
While vd < (direction)
angleViewX1# =Cos(angleView-CV )
angleViewY1#= Sin(angleView-CV )
x = Floor(camDirX/sizeT) : y= Floor(camDirY/sizeT)
If ( x <=numT And y <=numT And x >=0 And y >=0)
If AA(x,y) =1 Or AA(x,y) =2 Then
AA(x,y) =2
StopLine = 1
Exit
EndIf
EndIf
WritePixel camDirX ,camDirY,$666600
camDirX# =camDirX+offset*angleViewX1
camDirY# =camDirY+offset*angleViewY1
vd = vd +offset
Wend
Next
Line camPosX,camPosY,camPosX+direction*Cos(angleView ),camPosY+direction*Sin(angleView )
Line camPosX,camPosY,camPosX+direction*Cos(angleView-30 ),camPosY+direction*Sin(angleView-30 )
Line camPosX,camPosY,camPosX+direction*Cos(angleView- -30 ),camPosY+direction*Sin(angleView- -30 )
End Function
__________________
Мой проект здесь
Последний раз редактировалось polopok, 02.06.2014 в 21:17.
Причина: дополнение
|
(Offline)
|
|
02.06.2014, 21:28
|
#4
|
Мастер
Регистрация: 24.06.2009
Адрес: Набережные Челны
Сообщений: 930
Написано 292 полезных сообщений (для 504 пользователей)
|
Ответ: простой ray casting 2d array hit
линии направления не отображаются
попробовал так Line 0,0,camPosX+direction*Cos(angleView ),camPosY+direction*Sin(angleView )
и точка направлена в точку позиции камеры (а не куда должна глядеть камера)
надо вычисления концов линий починить
(я делал на Delphi подобное, но сейчас могу заняться поправкой)
в общем приписал
direction=100
Line camPosX,camPosY,camPosX+direction*Cos(angleView ),camPosY+direction*Sin(angleView )
и норм
для чего тогда newDirection ? и тут же View2D(offset) и View2D(direction)
|
(Offline)
|
|
02.06.2014, 21:59
|
#5
|
ПроЭктировщик
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений (для 71 пользователей)
|
Ответ: простой ray casting 2d array hit
newDirection просто не удалил из кода ,а offset - это смещение шага луча
__________________
Мой проект здесь
|
(Offline)
|
|
02.06.2014, 23:01
|
#6
|
.
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений (для 6,863 пользователей)
|
Ответ: простой ray casting 2d array hit
Делал давно, используя тригонометрию а не raycast. Тут 800+ отрезков, никаких оптимизаций.
http://moka.co/shadows/
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо moka за это полезное сообщение:
|
|
02.06.2014, 23:07
|
#7
|
ПроЭктировщик
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений (для 71 пользователей)
|
Ответ: простой ray casting 2d array hit
что -то вроде пересечения отрезка с отрезком или нормаи? Или проекцией на вектор?
__________________
Мой проект здесь
|
(Offline)
|
|
02.06.2014, 23:52
|
#8
|
.
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений (для 6,863 пользователей)
|
Ответ: простой ray casting 2d array hit
Находим отрезки в радиусе, кастуем два отрезка к концам кастера, продолжаем два отрезка до квадрата который описывает радиус источника света, и добовляем вершин чтобы прилегал массив вершин к прямоугольнику. Для оптимизации можно объединять стрипы от каждого кастера, и проверять если кастер вообще попал в видимость.
Также мягкие тени не сложно сделать с таким подходом.
|
(Offline)
|
|
03.06.2014, 11:03
|
#9
|
Мастер
Регистрация: 24.06.2009
Адрес: Набережные Челны
Сообщений: 930
Написано 292 полезных сообщений (для 504 пользователей)
|
Ответ: простой ray casting 2d array hit
Сообщение от polopok
newDirection просто не удалил из кода ,а offset - это смещение шага луча
|
просто хочу сказать-показать, что не отображается желаемое
|
(Offline)
|
|
03.06.2014, 21:22
|
#10
|
ПроЭктировщик
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений (для 71 пользователей)
|
Ответ: простой ray casting 2d array hit
Сообщение от moka
Находим отрезки в радиусе, кастуем два отрезка к концам кастера, продолжаем два отрезка до квадрата который описывает радиус источника света, и добовляем вершин чтобы прилегал массив вершин к прямоугольнику. Для оптимизации можно объединять стрипы от каждого кастера, и проверять если кастер вообще попал в видимость.
Также мягкие тени не сложно сделать с таким подходом.
|
Нашёл пример 2d light & shadow
__________________
Мой проект здесь
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
03.06.2014, 23:03
|
#11
|
.
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений (для 6,863 пользователей)
|
Ответ: простой ray casting 2d array hit
Сообщение от polopok
|
Очень похожий подход, эту демку видел тоже, но она поновее будет. Отличие в том что тут нужно отсортировать все вершины по градусу к источнику и бить их поочередно. Как бы тут есть экономия за счет проверки если не попал по отрезку, но и в моем подходе это реализуемо.
Оба подхода очень быстрые и качественные результаты производят.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 23:40.
|