extends Node

## Простые часто используемые функции


## Возвращает округлённое значение [param v] с точностью [param a]
func round_to(v: float, a: float) -> float: return snappedf(v, -a if v < 0 else a)


## Возвращает [b]true[/b], если [param val] число, [b]false[/b] - если иначе.
func type_is_num(val) -> bool: return (typeof(val) == TYPE_INT) or (typeof(val) == typeof(0.0))


## Возвращае значение в радианах для угла в градусах [param val].
func radians(val: float): return (val * PI) / 180.0


## Возвращает значение из байтового массива в 16 битном слове[br]
## [i]Следует использовать встроенные в[/i] [b]PackedByteArray[/b] [i]методы вместо этой функции.[/i]
func ibytes_to_word(buf: PackedByteArray, i: int) -> int: return buf[i] + (buf[i + 1] * 256)


## Возвращает расстояние от центра координат до точки
func hypot(x: float, y: float) -> float: return sqrt(x * x + y * y)


## Проверяет пересечение диапазона [param x1], [param x2] с диапазоном [param y1], [param y2]
func is_overlap(x1, x2, y1, y2): return max(x1, y1) <= min(x2, y2)


## Производит преобразование из декартовой в полярную систему координат
func pos_calc(freq: float, aoa: float, pos0: Vector2, r0: float, r1: float, f0: float, f1: float):
    var r = ((freq - f0) / (f1 - f0)) * r1 + r0
    var aoa_rad = radians(aoa) - PI / 2.0
    return Vector2(cos(aoa_rad), sin(aoa_rad)) * r + pos0


## Отсекает значение до заданного диапазона
func clip_value(val, val_min, val_max):
    if val < val_min: val = val_min
    if val > val_max: val = val_max
    return val


## Возвращает массив с именами членов [param obj]
func get_members_names(obj: Object) -> Array:
    var pl = obj.get_property_list()
    var names: = Array()
    for item in pl: names.append(item.name)
    return names


## Проверяет, что заданный массив [param val] похож на ip-адрес
func is_array_ipaddr(val: Array):
    return  (val.size() == 2)  \
        and (val[0] is String) \
        and (val[1] is int)    \
        and (0 < val[1])       \
        and (val[1] < 65536)


## Преобразует декартовые координаты в полярные.[br]
## [param pos0] - координаты центра.[br]
## [param pos] - координаты точки.[br]
func map_dec_to_rad(pos0: Vector2, pos: Vector2) -> Vector2:
    var x1:  float = pos.x - pos0.x
    var y1:  float = pos.y - pos0.y
    var ang: float = (atan2(y1, x1) * 180.0) / PI
    return Vector2(ang + 360.0 * float(ang < 0.0), hypot(x1, y1))


## Переводит значение val из диапазона a0...a1 в диапазон b0...b1
func map_range(val: float, a0: float, a1: float, b0: float, b1: float) -> float:
    return (((val - a0) * (b1 - b0)) / (a1 - a0)) + b0


## Возвращает [b]true[/b], если точка внутри заданного полигона
func is_point_in_polygon(pos: Vector2, p: PackedVector2Array) -> bool:
    var sz: = p.size()
    assert(sz)
    var j: int = sz - 1
    var odd_nodes: int = 0
    for i in sz:
        if ((p[i].y < pos.y and p[j].y >= pos.y or p[j].y < pos.y and p[i].y >= pos.y) and (p[i].x <= pos.x or p[j].x <= pos.x)):
            odd_nodes ^= int((p[i].x + (pos.y - p[i].y) / (p[j].y - p[i].y) * (p[j].x - p[i].x) < pos.x))
        j = i
    return odd_nodes > 0


## Записывает слово [param val] в элемент байтовго массива [param buf]
## расположенный по индексу [param index] (младшее слово).[br]
## [i]Следует использовать встроенные в[/i] [b]PackedByteArray[/b] [i]методы вместо этой функции.[/i]
func set_wordi(buf: PackedByteArray, index: int, val: int) -> void:
    buf[index] = val & 0xff
    buf[index + 1] = (val >> 8) & 0xff
