Проверка на проходимость

Anything and all.

Moderators: Murderator+, Murderator

Mirage
Posts: 2802
Joined: 2009-05-28 09:58:28
Location: Иваново
Contact:

Re: Проверка на проходимость

Post by Mirage »

Ну я бы вообще не стал браться. Но у тебя уже существенные продвижения по теме. Глядишь родится интелектуальный бот на инжекте. ;)
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Проверка на проходимость

Post by ZeroDX »

Странное дело вот такая конструкция

Code: Select all

sub test()
  var String = VectorPoints(UO.GetX('self'), UO.GetY('self'), UO.GetX('self') - 3, UO.GetY('self') - 4), i
  var Count = val(GetWord(String, 1))
  UO.Print(String)
  UO.Print(str(uo.getz()))
  For i = 2 to Count * 2 + 1 step 2
    UO.MFGI('add', '1339', GetWord(String, i), GetWord(String, i + 1), UO.GetZ(), '0x0025', 'cave floor')
  Next
Endsub

sub deltile()
    var MaxRange = 18
    var X, Y, Z, Tiles
    var mX, mY, mZ
    mX = UO.GetX('self')
    mY = UO.GetY('self')
    mZ = UO.GetZ('self')
    for Y = MaxRange - ( MaxRange * 2 ) to MaxRange
        for X = MaxRange - ( MaxRange * 2 ) to MaxRange
            UO.MFGI('clear', '1339', mX+X, mY+Y, UO.GetZ('self'))
        next
    next
end sub

Sub VectorPoints(startx, starty, endx, endy)
  var x = startx, y = starty, Coordinates = ' ' + str(x) + ' ' + str(y) + ' ', Amount = 1
  While x <> endx and y <> endy
    If x == endx and y < endy then
      y = y + 1
    Endif
    If x > endx and y < endy then
      x = x - 1
      y = y + 1
    Endif
    If x > endx and y == endy then
      x = x - 1
    Endif
    If x > endx and y > endy then
      x = x - 1
      y = y - 1
    Endif
    If x == endx and y > endy then
      y = y - 1
    Endif
    If x < endx and y > endy then
      x = x + 1
      y = y - 1
    Endif
    If x < endx and y == endy then
      x = x + 1
    Endif
    If x < endx and y < endy then
      x = x + 1
      y = y + 1
    Endif
    Coordinates = (Coordinates + str(x) + ' ' + str(y) + ' ')
    Amount = Amount + 1
  Wend
  Return str(Amount) + Coordinates
Endsub

Sub GetWord(st, nom)
  var tmpst, i, dlin, kol = 0, start = 0
  dlin = len(st)
  For i = 0 to dlin - 1
    If mid(st, i, 1) == ' ' or i == dlin - 1 then
      kol = kol + 1
      If kol == nom then
        tmpst = mid(st, start, i - start)
        Return tmpst
       else
        While mid(st, i, 1) == ' '
          i = i + 1
        Wend
        If kol == nom - 1 then
          start = i
        Endif
      Endif
    Endif
  Next
  tmpst = ''
  Return tmpst
Endsub
пропускает тайлы, направление вроде стоят правельные. Ни как не пойму в чем дело
Tiger1989
Posts: 35
Joined: 2010-06-19 22:59:51

Re: Проверка на проходимость

Post by Tiger1989 »

Молодцы ребята :!: :!: :D
Irina E
Posts: 240
Joined: 2009-06-12 20:10:00
Location: Vasa Smerti(RASToMAN) DRW

Re: Проверка на проходимость

Post by Irina E »

я пян и не хера не понел :mrgreen:
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Проверка на проходимость

Post by ZeroDX »

Скачал сферу 56, провёл пару тестов...
Итак. Вот так стреляет.
ImageImageImage

Так и не смог добиться от формулы, чтобы скрипт выдавал 1-ый вариант. Выдавать может только 2-ой и 3-ий. Узнал, что между 2-мя точками, может быть несколько траекторий.
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Проверка на проходимость

Post by ZeroDX »

Прошу помощи с синусом

Code: Select all

Sub GetAngle(startx, starty, endx, endy)
  var a, c = GetVectorLenght(startx, starty, endx, endy), i
  If Absolute(endx - startx) < Absolute(endy - starty) then
    a = Absolute(endx - startx)
   else
    a = Absolute(endy - starty)
  Endif
  For i = 0 to 90
    If IsInRange(Sin(i), a / c - 0.005, a / c + 0.005) then
      Return i
    Endif
  Next
Endsub

Sub GetVectorLenght(startx, starty, endx, endy)
  Return SQRT(Exponent(endx - startx, 2) + Exponent(endy - starty, 2))
Endsub
Функция должна вернуть угол прямоугольного треугольника. а - катет, с - гипотенуза. формула такая

Code: Select all

а = с * sin A
что-то не то взвращает. Катет а определяется как катет, который короче. IsInRange(val, val1, val2) - где val это проверяемое число, val1 и val2 - диапазон.

Пока писал пост, вспомнил, что тригонометрические функции работают с радиальной мерой угла. Как перевести в градусы?
П.С. Если бы автор топа спросил бы на sphereserver.net формулу, которую я пытаюсь придумать, было бы видно, что он не только морально поддерживает, но и заинтересован в развитии проекта :twisted:
Last edited by ZeroDX on 2011-11-12 00:30:04, edited 1 time in total.
Mirage
Posts: 2802
Joined: 2009-05-28 09:58:28
Location: Иваново
Contact:

Re: Проверка на проходимость

Post by Mirage »

КО подсказывает что 1 градус равен 0,0175 радиана :roll:

Интересно задумывался ли вообще автор топа задавая вопрос какой последует ответ :mrgreen:
Grin
Expert!
Posts: 2580
Joined: 2005-05-04 14:05:19
Location: Москва

Re: Проверка на проходимость

Post by Grin »

Как все запущено:)
Mirage
Posts: 2802
Joined: 2009-05-28 09:58:28
Location: Иваново
Contact:

Re: Проверка на проходимость

Post by Mirage »

Лучше бы помог. ZeroDX вон старается.
А я старый двоечник. :roll:
Grin
Expert!
Posts: 2580
Joined: 2005-05-04 14:05:19
Location: Москва

Re: Проверка на проходимость

Post by Grin »

А ZeroDX тогда колышник?:)
Я вроде вам рассказал что да как, а вы в декартову тригонометрию полезли... там другое пространство и это учитывать надо... Да и опять таки дело не в этом, ни Сфера, ни РанУО, ни ПОЛ не используют для расчетов видимости синусы и тд...
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Проверка на проходимость

Post by ZeroDX »

Grin wrote:С каждым шагом заново вычисляется направление, и делается 1 шаг в этом направлении. вот и все:)


Ну вот где тут помощь?
Grin
Expert!
Posts: 2580
Joined: 2005-05-04 14:05:19
Location: Москва

Re: Проверка на проходимость

Post by Grin »

Написано же... Что сфера выбирает путь еще проще...

Определяет направление до цели из 8 возможных, делает шаг в этом направлении, опять определяет направление до цели, опять шаг ...

Как определить направление?:) разбейте круг на 8 частей где на основные части света приходится по 60 градусов, а на промежуточные только 30.

Ну и выбирайте, делайте шаг, опять выбирайте:)
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Проверка на проходимость

Post by ZeroDX »

Это как по 60 градусов? 360 / 8 = 45. Даже если так, то как оно выбирает направление?

Code: Select all

Sub VectorPoints(startx, starty, endx, endy)
  var x = startx, y = starty, Coordinates = ' ' + str(x) + ' ' + str(y) + ' ', Amount = 1
  While x <> endx and y <> endy
    If x < endx then
      x = x + 1
    Endif
    If x > endx then
      x = x - 1
    Endif
    If y < endy then
      y = y + 1
    Endif
    If y > endy then
      y = y - 1
    Endif
    Coordinates = (Coordinates + str(x) + ' ' + str(y) + ' ')
    Amount = Amount + 1
  Wend
  Return str(Amount) + Coordinates
Endsub
Если так, то получается чуть ли не буква Г. Так не стрелеяет. А ещё через углы не стреляет на 56-ой, так что навправлений должно быть 4
Grin
Expert!
Posts: 2580
Joined: 2005-05-04 14:05:19
Location: Москва

Re: Проверка на проходимость

Post by Grin »

О ужас:)

так вот ctg(a) = dx/dy = 2

Центральный угол (бэта) основных 4 сторон света, больше промежуточных...
Attachments
UO_sides.jpg
UO_sides.jpg (126.35 KiB) Viewed 4349 times
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Проверка на проходимость

Post by ZeroDX »

Image

А если по делу, то я не понимаю, что ты хочешь сказать. Как мне поможет знание того, что центральный угол больше промежуточных? Если есть готовое решение - просим... зачем изобретать велосипед 2 раза. Если нет, то можно попонятней?
Grin
Expert!
Posts: 2580
Joined: 2005-05-04 14:05:19
Location: Москва

Re: Проверка на проходимость

Post by Grin »

Если ты не догоняешь, то кто в этом виноват? :roll:

Я уже не раз повторяюсь... есть исходные коды всех серверов...

Code: Select all

bool CChar::CanSeeLOS( const CPointMap & ptDst, CPointMap * pptBlock, int iMaxDist ) const
    {
        // Max distance of iMaxDist
        // Line of sight check
        // NOTE: if not blocked. pptBlock is undefined.
        if ( IsPriv( PRIV_GM ))
                return( true );
   
        CPointMap ptSrc = GetTopPoint();
        ptSrc.m_z += PLAYER_HEIGHT/2;
   
        int iDist = ptSrc.GetDist( ptDst );
   
        // Walk towards the object. If any spot is too far above our heads
        // then we can not see what's behind it.
   
        int iDistTry = 0;
        while ( --iDist > 0 )
        {
                DIR_TYPE dir = ptSrc.GetDir( ptDst );
                ptSrc.Move( dir );      // NOTE: The dir is very coarse and can change slightly.
   
                WORD wBlockFlags = CAN_C_SWIM | CAN_C_WALK | CAN_C_FLY;
                signed char z = g_World.GetHeightPoint( ptSrc, wBlockFlags, ptSrc.GetRegion( REGION_TYPE_MULTI ));
                if ( wBlockFlags & ( CAN_I_BLOCK | CAN_I_DOOR ))
                {
    blocked:
                        if ( pptBlock != NULL )
                                * pptBlock = ptSrc;
                        return false; // blocked
                }
                if ( iDistTry > iMaxDist )
                {
                        // just went too far.
                        goto blocked;
                }
                iDistTry ++;
        }
   
        return true; // made it all the way to the object with no obstructions.
    }

    DIR_TYPE CPointBase::GetDir( const CPointBase & pt, DIR_TYPE DirDefault ) const // Direction to point pt
    {
       // Get the 2D direction between points.
       int dx = (m_x-pt.m_x);
       int dy = (m_y-pt.m_y);
   
       int ax = abs(dx);
       int ay = abs(dy);
   
       if ( ay > ax )
       {
          if ( ! ax )
          {
             return(( dy > 0 ) ? DIR_N : DIR_S );
          }
          int slope = ay / ax;
          if ( slope > 2 )
             return(( dy > 0 ) ? DIR_N : DIR_S );
          if ( dx > 0 )   // westish
          {
             return(( dy > 0 ) ? DIR_NW : DIR_SW );
          }
          return(( dy > 0 ) ? DIR_NE : DIR_SE );
       }
       else
       {
          if ( ! ay )
          {
             if ( ! dx )
                return( DirDefault );   // here ?
             return(( dx > 0 ) ? DIR_W : DIR_E );
          }
          int slope = ax / ay;
          if ( slope > 2 )
             return(( dx > 0 ) ? DIR_W : DIR_E );
          if ( dy > 0 )
          {
             return(( dx > 0 ) ? DIR_NW : DIR_NE );
          }
          return(( dx > 0 ) ? DIR_SW : DIR_SE );
       }
    }


Только не говори "и Чё?" :mrgreen: Да и потом геометрическая визуализация куда наглядней... "И чё" тебе там не понятно, для меня загадка:)
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Проверка на проходимость

Post by ZeroDX »

на каком это языке?
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Проверка на проходимость

Post by ZeroDX »

в визуализалиции не понятно что есть что, кроме W N E S
Grin
Expert!
Posts: 2580
Joined: 2005-05-04 14:05:19
Location: Москва

Re: Проверка на проходимость

Post by Grin »

кстати исходя из алгоритма, траектория очень забавная выходит:)
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Проверка на проходимость

Post by ZeroDX »

Траектория действительно интресная, и не подходит.
На 56-ой сфере не стреляет через углы... Выше я постил 3 картинки, на которых желтым цветом выделены простреливаемые тайлы. На картинках видно, что между точками могут пролегать несколько разных траекторий.

Вот переделка под инжу. Можно сделать короче, но я путаюсь в else'ах

Code: Select all

sub test()
  var String = VectorPoints(UO.GetX('self'), UO.GetY('self'), UO.GetX('self') + 2, UO.GetY('self') + 7), i
  var Count = val(GetWord(String, 1))
  UO.Print(String)
  For i = 2 to Count * 2 step 2
    UO.MFGI('add', '1339', GetWord(String, i), GetWord(String, i + 1), 20, '0x0025', 'cave floor')
  Next
Endsub

sub deltile()
    var MaxRange = 18
    var X, Y, Z, Tiles
    var mX, mY, mZ
    mX = UO.GetX('self')
    mY = UO.GetY('self')
    mZ = UO.GetZ('self')
    for Y = MaxRange - ( MaxRange * 2 ) to MaxRange
        for X = MaxRange - ( MaxRange * 2 ) to MaxRange
            UO.MFGI('clear', '1339', mX+X, mY+Y, UO.GetZ('self'))
        next
    next
end sub

Sub VectorPoints(startx, starty, endx, endy)
  var Coordinates = ' ' + str(startx) + ' ' + str(starty) + ' ', Amount = 1, dx, dy, ax, ay
  While startx <> endx or starty <> endy
    dx = startx - endx
    dy = starty - endy
    ax = Absolute(dx)
    ay = Absolute(dy)
    If ax > ay then
      If ay == 0 then
        If dx > 0 then
          startx = startx - 1
         else
          startx = startx + 1
        Endif
       else
        If ax / ay > 2 then
          If dx > 0 then
            startx = startx - 1
           else
            startx = startx + 1
          Endif
         else
          If dy > 0 then
            If dx > 0 then
              startx = startx - 1
              starty = starty - 1
             else
              startx = startx + 1
              starty = starty - 1
            Endif
           else
            If dx > 0 then
              startx = startx - 1
              starty = starty + 1
             else
              startx = startx + 1
              starty = starty + 1
            Endif
          Endif
        Endif
      Endif
    Endif
    If ax < ay then
      If ax == 0 then
        If dy > 0 then
          starty = starty - 1
         else
          starty = starty + 1
        Endif
       else
        If ay / ax > 2 then
          If dy > 0 then
            starty = starty - 1
           else
            starty = starty + 1
          Endif
         else
          If dx > 0 then
            If dy > 0 then
              starty = starty - 1
              startx = startx - 1
             else
              starty = starty + 1
              startx = startx - 1
            Endif
           else
            If dy > 0 then
              starty = starty - 1
              startx = startx + 1
             else
              starty = starty + 1
              startx = startx + 1
            Endif
          Endif
        Endif
      Endif
    Endif
    If ax == ay then
      If dx > 0 then
        If dy > 0 then
          startx = startx - 1
          starty = starty - 1
         else
          startx = startx - 1
          starty = starty + 1
        Endif
       else
        If dy > 0 then
          startx = startx + 1
          starty = starty - 1
         else
          startx = startx + 1
          starty = starty + 1
        Endif
      Endif
    Endif
    Coordinates = Coordinates + str(startx) + ' ' + str(starty) + ' '
    Amount = Amount + 1
  Wend
  Return str(Amount) + Coordinates
Endsub

Sub GetWord(st, nom)
  var tmpst, i, dlin, kol = 0, start = 0
  dlin = len(st)
  For i = 0 to dlin - 1
    If mid(st, i, 1) == ' ' or i == dlin - 1 then
      kol = kol + 1
      If kol == nom then
        tmpst = mid(st, start, i - start)
        Return tmpst
       else
        While mid(st, i, 1) == ' '
          i = i + 1
        Wend
        If kol == nom - 1 then
          start = i
        Endif
      Endif
    Endif
  Next
  tmpst = ''
  Return tmpst
Endsub

Sub Absolute(val)
  If val < 0 then
    Return -val
   else
    Return val
  Endif
Endsub
Last edited by ZeroDX on 2011-07-13 14:59:38, edited 1 time in total.
Post Reply