Проверка видимости

Работа с 2D и 3D графикой, видео, звуком.

Модератор: Mikle

Bazilius
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 87
Зарегистрирован: 14.11.2003 (Пт) 16:07
Откуда: Пермь

Проверка видимости

Сообщение Bazilius » 14.11.2003 (Пт) 16:21

В общем, проблема в следующем:

Организован 2d-массив (10х10), на котором находятся препятствия и юниты противоборствующей стороны. Необходимо выстрелить по юниту врага, но нам неизвестно - видим он или нет.
Мне необходимо узнать, видим данный (выбранный как цель) юнит врага или нет, т.е. закрывают его припятствия или нет. Как это можно проверить? Простой алгоритм обхода препятствий здесь не действует - его волны в любом случае находят интересующий нас юнит, даже если он стоит за стенкой... Понятно, что по простым диагоналям и прямым найти его легко (если он находиться на их точках), а если он смещен... Для меня это проблема, помогите, plz... :roll:

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 17.11.2003 (Пн) 18:41

Если препятствия занимают всю клетку, то задача остается простой, стоит юнит на узле или не стоит.

Bazilius
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 87
Зарегистрирован: 14.11.2003 (Пт) 16:07
Откуда: Пермь

Сообщение Bazilius » 18.11.2003 (Вт) 17:03

Mikle писал(а):Если препятствия занимают всю клетку, то задача остается простой, стоит юнит на узле или не стоит.


Немного не понял... :oops: что такое узел?

Если не трудно, распишите весь алгоритм... А то я че-то не врублюсь...

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 19.11.2003 (Ср) 16:03

Код: Выделить всё
Option Explicit
Dim posX As Integer, posY As Integer, Alfa As Single
Dim SinA As Single, CosA As Single

Private Sub Form_Load()
  Me.ScaleMode = vbPixels
  Me.Width = 400 * Screen.TwipsPerPixelX
  Me.Height = 400 * Screen.TwipsPerPixelY
  posX = 200
  posY = 180
  Alfa = -2
  Me.Show
  RePaint
End Sub

Private Sub RePaint()
  Me.Cls
  SinA = Sin(Alfa)
  CosA = Cos(Alfa)
  Me.Circle (posX, posY), 5, 0
  Me.Line (posX, posY)-(posX + SinA * 640, posY - CosA * 640), 0
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  If Button = 1 Then
    posX = X
    posY = Y
  ElseIf Button = 2 Then
    Select Case Y - posY
      Case Is > 0: Alfa = 3.1415 - Atn((X - posX) / (Y - posY))
      Case Is < 0: Alfa = -Atn((X - posX) / (Y - posY))
      Case 0: If X > posX Then Alfa = 3.1415 / 2 Else Alfa = -3.1415 / 2
    End Select
  End If
  RePaint
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Static RL As Single, FB As Single
  Me.Caption = "FB:" & Str$(difFB(X, Y)) & "   RL:" & Str$(difRL(X, Y))
End Sub

Private Function difRL(X As Single, Y As Single) As Single
  difRL = SinA * (Y - posY) + CosA * (X - posX)
End Function

Private Function difFB(X As Single, Y As Single) As Single
  difFB = SinA * (X - posX) - CosA * (Y - posY)
End Function


Создай новый проект, вставь в форму этот код. Левой кнопкой мыши ставишь стрелка, правой указываешь направление. Код содержит две функции difRL(x,y) и difFB(x,y), возвращающие для точки с координатами (x,y) информацию, на какое расстояние точка смещена относительно вектора выстрела вправо\влево (влево - минус) и соответственно вперед\назад. На MouseMove в заголовок выводятся эти величины для курсора мыши. С помощью difFB можно отсеить все пряпятствия, что сзади. Из тех, что впереди, если все вершины n-угольника (мишени, препятствия) находятся слева (или справа) от вектора - значит в него не попадаем, иначе - попадаем. Для окружности еще проще - если модуль difRL для центра окружности меньше ее радиуса - в нее попали.
Естественно из тех объектов, в которые попали, нужно выбрать ближний.

Bazilius
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 87
Зарегистрирован: 14.11.2003 (Пт) 16:07
Откуда: Пермь

Сообщение Bazilius » 19.11.2003 (Ср) 17:01

ОГРОМНОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО!!!

Bazilius
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 87
Зарегистрирован: 14.11.2003 (Пт) 16:07
Откуда: Пермь

Сообщение Bazilius » 20.11.2003 (Чт) 10:03

И снова я :oops: с вопросом (задолбал наверное?)

Изображение

Мы имеем вот такой тайловый массив где зеленая точка - юнит, красная - враг. Между ними линия - она определяет видит ли юнит врага, или нет - в зависимости от препятствий...

И собственно вопрос - как построить такую линию по точкам через цикл.
--------
цикл
юнит (x1, y1)
враг (x2, x2)
ставим точку по направлению к врагу (x1+?, y1+?)
проверяем: если стена то выход - враг не виден
проверяем: если враг то врга виден - стреляем
конец цикла
--------
Знаки вопроса означают, что я не знаю какие суммы прибавить, они зависят от координат врага (но как?) - я запутался :oops:
Должно ведь по идее быть следующее: если у этой линии на пути нет препятствий - юнит видит врага, можно стрелять. А если есть - значит не видит. Собственно у меня с этим проблема и возникла, т.к. геометрию в школе не учил :oops:

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 20.11.2003 (Чт) 16:08

Код: Выделить всё
Option Explicit
Dim x1 As Integer, x2 As Integer, y1 As Integer, y2 As Integer

Private Sub Form_Click()
Dim x As Integer, y As Integer, k As Single, kk As Single
  x1 = Rnd * 390
  y1 = Rnd * 370
  x2 = Rnd * 390
  y2 = Rnd * 370
  Me.Cls
  Circle (x1, y1), 5, RGB(0, 0, 255)
  Circle (x2, y2), 5, RGB(255, 0, 0)
  If Abs(y2 - y1) > Abs(x2 - x1) Then
    k = (x2 - x1) / Abs(y2 - y1)
    kk = x1
    For y = y1 To y2 Step Sgn(y2 - y1)
      kk = kk + k
      x = kk
      DrawPoint x, y
    Next y
  Else
    If x1 = x2 Then k = 1 Else k = (y2 - y1) / Abs(x2 - x1)
    kk = y1
    For x = x1 To x2 Step Sgn(x2 - x1)
      kk = kk + k
      y = kk
      DrawPoint x, y
    Next x
  End If
End Sub

Private Sub DrawPoint(x As Integer, y As Integer)
  Me.PSet (x, y), RGB(0, 255, 0)
End Sub

Private Sub Form_Load()
  Me.ScaleMode = vbPixels
  Me.Width = Screen.TwipsPerPixelX * 400
  Me.Height = Screen.TwipsPerPixelY * 400
End Sub

' *        #
'  *      #
'   *    #
'    *  #
'     *#
'     #*
'    #  *
'   #    *
'  #      *
' #        *

' Внутрь DrawPoint поставь свою проверку на стену.
' А теперь представь, что # - это стенка,
'                       а * - это выстрел.
' И твоя пуля пройдет сквозь стену...
' Разберись лучше с первым алгоритмом.
' Хотя если все стенки прямые, как на рисунке, - покатит.

Bazilius
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 87
Зарегистрирован: 14.11.2003 (Пт) 16:07
Откуда: Пермь

Сообщение Bazilius » 20.11.2003 (Чт) 16:56

Спасибо!

Стены будут только под прямым углом. Если вообще будут - слишком много проблем возникает... А разрешать их не умею...
Я выложил исходник проекта здесь -> www.wh40kdev.nm.ru <-, там архив RAR весом 300 кб. Можете оценить. Пишу на VB6, пока недалеко продвинулся из-за таких вот проблем :oops:

Bazilius
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 87
Зарегистрирован: 14.11.2003 (Пт) 16:07
Откуда: Пермь

Сообщение Bazilius » 20.11.2003 (Чт) 16:59

2Mikle: если можете, посмотрите мое творение, и выскажете свое мнение по поводу всех косяков (код, интерфейс и т.д.). Мне очень важно стороннее мнение, коего я не имею :(

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 20.11.2003 (Чт) 17:52

На сайт я вышел с пятого раза, когда скопировал ссылку из твоего поста и вставил ее непосредственно в адресную строку эксплорера. На сайте заметил две ссылки "скачать" - демо движка и алгоритм нахождения... Сколько ни кликал - не грузится. Какой из них хоть исходник проекта?
Вообще у меня и-нет глючный - FTP совсем не пашет. Так что лучше выложи проект прямо сюда, на форум.
Кстати, можно на "ты". :wink:

Bazilius
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 87
Зарегистрирован: 14.11.2003 (Пт) 16:07
Откуда: Пермь

Сообщение Bazilius » 21.11.2003 (Пт) 6:47

Ок. Качать http://www.wh40kdev.nm.ru/download/engine.rar. 350 кб.

Bazilius
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 87
Зарегистрирован: 14.11.2003 (Пт) 16:07
Откуда: Пермь

Сообщение Bazilius » 21.11.2003 (Пт) 8:27

Приаттачил проект в архиве RAR. Написан на VB6, DX7, WinXP.
У вас нет доступа для просмотра вложений в этом сообщении.


Вернуться в Мультимедиа

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6

    TopList