|
|
|
Принадлежность точки области на плоскости |
|
|
cirus |
12.8.2021, 2:15
|
Elder
Сообщений: 3.480
Регистрация: 18.8.2014 Группа: Пользователи Наличность: 26703
Пользователь №: 16.971
Возраст: 29
|
Вот вам заняться нечем, когда существуют готовые функции. Код --lua local ffi = require("ffi") log 'clear' log 'mode compact'
local WINDING = 2 ffi.cdef[[ typedef long LONG; typedef int BOOL; typedef void *HGDIOBJ; typedef struct tagPOINT { LONG x; LONG y;} POINT, *PPOINT, *NPPOINT, *LPPOINT; struct HRGN__ { int unused; }; typedef struct HRGN__ *HRGN; BOOL PtInRegion(HRGN hrgn, int x, int y); HRGN CreatePolygonRgn(const POINT *pptl, int cPoint, int iMode); BOOL DeleteObject(HGDIOBJ ho); ]]
local rhomb = ffi.new('POINT[4]', {{50, 0}, {100, 50}, {50, 100}, {0, 50}}) -- координаты ромба
local region = ffi.C.CreatePolygonRgn(rhomb, 4, WINDING) -- создать регион из 4х точек if tonumber(ffi.cast('int', region)) ~= 0 then -- если регион создался local result = ffi.C.PtInRegion(region, 50, 70) -- входит ли точка в регион log (result) ffi.C.DeleteObject(ffi.cast('HGDIOBJ', region)) -- удалить регион else log ("Регион не создан") end
Собственно можно любую фигуру создать и проверить входит ли точка в неё.
|
|
|
|
DarkMaster |
12.8.2021, 5:20
|
Модератор UOPilot
Сообщений: 9.465
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 27681
Пользователь №: 11.279
|
Цитата Вот вам заняться нечем, когда существуют готовые функции. Вот для этого форум и существует. Знал ли я о регионах? Естественно да. А почему не использовал? Да потому, что занимаюсь анализом попиксельно уже несколько дней безвылазно и логика там мозговыносящая. Перестаешь видеть варианты, в т.ч. достаточно очевидные. А тут подскажут =) Пасип. Цитата Ну, если ромб строится, то тогда можем взять точки всех углов, так ? От этих точек найти уравнения прямых по 2м точкам, далее находить y(x) каждого уравнения и выполнять сравнение с заданными x и y. Ну или вот это вроде может быть: http://www.cleverstudents.ru/line_and_plan...on_of_line.htmlПасип. Еще один вариант натыкался (может кому-то в будущем пригодиться). Он для треугольников, соответственно фигуру просто разбить придется. https://planetcalc.ru/8108/?license=1Ща буду смотреть, что интереснее получается. Лень и разум говорят "возьми готвое", но не изучить варианты - это был бы не я. Сообщение отредактировал DarkMaster - 12.8.2021, 7:44
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
sutra |
13.8.2021, 15:53
|
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007
|
Я пока обходился без этого, но в принципе даже интересно стало. Решил "набросать" на вскидку, исходя из базовых школьных знаний тригонометрии (других увы нет). Не проверял толком как работает, чисто для логического примера. Можно работать абсолютно с любым многоугольником. Рисовать такую функцию - лень, да и нет необходимости пока. Код --lua local function AngleLine(xA,yA,xB,yB) -- функция определения угла произвольной прямой local katet=math.abs(xB-xA) local BasicAngle=math.deg(math.acos(katet/math.sqrt(katet^2+(yB-yA)^2))) -- катет делим на гипотенузу local FinalAngle=BasicAngle if xB<xA then FinalAngle=180-BasicAngle end -- зеркалируем угол if yB<yA then -- коррекция для 3-й и 4-й четверти if xB<xA then FinalAngle=FinalAngle+BasicAngle*2 else FinalAngle=360-BasicAngle end end return FinalAngle end
local dot={50,200} -- тут можно поиграться с координатами local romb={{100,100},{50,200},{300,300},{150,200}} -- да и тут можно, можно и не ромб --/\ снизу вверх по часовой, ординаты в плюс - на север (лень в нормальные координаты переводить) local angle1=AngleLine(romb[1][1],romb[1][2],dot[1],dot[2]) local angle2=AngleLine(romb[3][1],romb[3][2],dot[1],dot[2]) local result=true -- лень делать функцию - чисто пример if angle1 > AngleLine(romb[1][1],romb[1][2],romb[2][1],romb[2][2])then -- снизу влево вверх result=false elseif angle1 < AngleLine(romb[1][1],romb[1][2],romb[4][1],romb[4][2])then -- снизу вправо вверх result=false elseif angle2 < AngleLine(romb[3][1],romb[3][2],romb[2][1],romb[2][2])then -- сверху влево вниз result=false elseif angle2 > AngleLine(romb[3][1],romb[3][2],romb[4][1],romb[4][2])then -- сверху вправо вниз result=false end if result then log("Точка принадлежит ромбу") else log("Точка НЕ принадлежит ромбу") end
|
|
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|