Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   принадлежит ли точка треугольнику (http://www.flasher.ru/forum/showthread.php?t=85390)

scourge ' kangaroo 21.09.2006 12:40

принадлежит ли точка треугольнику
 
нужно узнать, принадлежит ли точка треугольнику.
написал код, он он работает не точно. т.е. функция не возвращает истину, когда точка рядом со стороной треугольника.
Подскажите пожалуйста, в чём ошибка...

Код:

aX = 120; aY = 100;
bX = 100; bY = 130;
cX = 140; cY = 130;

_root.lineStyle(0, 0xFFFFFF);
_root.moveTo(aX,aY);
_root.lineTo(bX,bY);
_root.lineTo(cX,cY);
_root.lineTo(aX,aY);

function onEnterFrame(){
hitTest(aX, aY, bX, bY, cX, cY, _xmouse, _ymouse)
}

// Проверяем, принадлежит ли точка треугольнику
function hitTest(aX, aY, bX, bY, cX, cY, fX, fY){
// Находим площадь главного треугольника
s0 = square(aX, aY, bX, bY, cX, cY)
// Соединяем вершины треугольника с точкой и находим площади маленьких треугольников
s1 = square(fX, fY, aX, aY, bX, bY)
s2 = square(fX, fY, aX, aY, cX, cY)
s3 = square(fX, fY, bX, bY, cX, cY)
// Принадлежит?
if(s0 >= (s1+s2+s3))trace("курсор в треугольнике!")
}

// Узнаём площадь треугольника
function square(aX, aY, bX, bY, cX, cY){
// 1. Находим длины сторон
aD = Math.abs(aX - bX) + Math.abs(aY - bY)
bD = Math.abs(bX - cX) + Math.abs(bY - cY)
cD = Math.abs(cX - aX) + Math.abs(cY - aY)
// 2. Находим полупериметр
p = (aD + bD + cD)/2
// 3. Находим площадь
S = Math.sqrt(p * (p - aD) * (p - bD) * (p - cD))
return(S)
}


etc 21.09.2006 13:10

А зачем ты переопределяешь hitTest?

scourge ' kangaroo 21.09.2006 13:12

т.е.?

whiteRed 21.09.2006 13:33

интересно ты длины сторон вычисляешь

miramax 21.09.2006 13:39

Цитата:

Сообщение от scourge ' kangaroo
нужно узнать, принадлежит ли точка треугольнику.
написал код, он он работает не точно. т.е. функция не возвращает истину, когда точка рядом со стороной треугольника.
Подскажите пожалуйста, в чём ошибка...

Алгоритм у тебя оригинальный, но не верный.
Могу подсказать, код писать долго придётся скажу сразу Сейчас вот, нарисовал треугольник и теоремку придумал :)
"Если точка принадлежит треугольнику, то все лучи соединяющие точку и проходящие через вершины треугольника, пересекают только две прямые , которым принадлежат стороны треугольника, из трёх. Причём точка пересечения лежит в точке пересечения этих дву прямых. Короче вершина там и две прямые с лучом из точки пересекаются. Если луч ,кроме одной вершины треугольника, пересекает ещё хотя бы одну прямую, которой принадлежит любая сторона треугольника или другую вершину. Тогда точка лежит вне треугольника."
Помоему через углы можно решить ещё. А ещё через стороны. Ведь с данными сторонами существует лишь один 1 треугольник :)
З.Ы. - это применимо ТОЛЬКО к треугольнику

etc 21.09.2006 14:18

Цитата:

Сообщение от scourge ' kangaroo
т.е.?

hitTest — метод MovieClip. Ты его переопределяешь. Назови функцию по-другому.

iNils 21.09.2006 14:19

Точка пренадлежит треугольнику, если она лежит слева от всех векторов составляющих этот треугольник (при соответствующем обходе его)

scourge ' kangaroo 21.09.2006 14:49

всем спасибо за помомощь! (:

Цитата:

Сообщение от whiteRed
интересно ты длины сторон вычисляешь

проверил, ошибка именно в этом...
подскажите, как узнать длину отрезка зная его точки?

etc 21.09.2006 14:52

Цитата:

Сообщение от scourge ' kangaroo
подскажите, как узнать длину отрезка зная его точки?

Код:

xd = x1-x2;
yd = y1-y2;
l = Math.sqrt(xd*xd+yd*yd);

5-ый класс.

scourge ' kangaroo 21.09.2006 14:56

спасибо! Теперь всё как часы работает...
в школе я двоечником был...

miramax 21.09.2006 14:58

Вообщем у тебя два выхода:
1 простой и не понятный см. пост №5. Я плохо пояснил. Суть в том что луч соединяющий точку и вершину не может пересекать ни одну из сторон треугольника. Исключая вершины. Для этого тебе нуно написать функцию для определения пересечения двух отрезков по координатам их ограничивающих точек (кстати не тривиальная задача)
2. Понятный, но сложный:
Точка принадлежит выпуклой фигуре в том случае если каждая проекция точки на каждую сторону фигуры, лежит между вершинами принадлижащими этой стороне. Для этого нужно строить перпендикуляры.
Кстати у INils'а без перпендикуляров то же не обойтись.

iNils 21.09.2006 15:05

Цитата:

Сообщение от miramax
Кстати у INils'а без перпендикуляров то же не обойтись.

Если я не ошибаюсь, достаточно знать порядок обхода точек треугольника и тогда по углу между точк-точка1_вектора и точка1_вектора-точка2_вектора можно узнать слева или справа от вектора точка.

whiteRed 21.09.2006 15:10

а чем вас не устраивает метод scourge ' kangaroo?

miramax 21.09.2006 15:16

Цитата:

а чем вас не устраивает метод scourge ' kangaroo?
s0 >= (s1+s2+s3)??
эта формула не сработает если представить себе маленький треугольничек от которого оттащили мышку на километр

scourge ' kangaroo 21.09.2006 15:59

наверное было бы логично предположить, что я переделал код...


Код:

aX = 120; aY = 100;
bX = 100; bY = 130;
cX = 140; cY = 130;

function onEnterFrame(){
_root.clear()
getlocation(aX, aY, bX, bY, cX, cY, _xmouse, _ymouse)
}

// Проверяем, принадлежит ли точка треугольнику
function getlocation(aX, aY, bX, bY, cX, cY, fX, fY){
// Находим площадь главного треугольника
s0 = getsquare(aX, aY, bX, bY, cX, cY)
// Соединяем вершины треугольника с точкой и находим площади маленьких треугольников
s1 = getsquare(fX, fY, aX, aY, bX, bY)
s2 = getsquare(fX, fY, aX, aY, cX, cY)
s3 = getsquare(fX, fY, bX, bY, cX, cY)
// Принадлежит?
if(Math.round(s0) == Math.round((s1+s2+s3))){
        _root.beginFill(0x6794A7);
}else{
        _root.beginFill(0x000000);
}
_root.lineStyle(0, 0xFFFFFF);
_root.moveTo(aX,aY);
_root.lineTo(bX,bY);
_root.lineTo(cX,cY);
_root.lineTo(aX,aY);
}

// Узнаём площадь треугольника
function getsquare(aX, aY, bX, bY, cX, cY){
// 1. Находим длины сторон
aD = getlength(aX, aY, bX, bY)
bD = getlength(bX, bY, cX, cY)
cD = getlength(cX, cY, aX, aY)
// 2. Находим полупериметр
p = (aD + bD + cD)/2
// 3. Находим площадь
S = Math.sqrt(p * (p - aD) * (p - bD) * (p - cD))
return(S)
}

function getlength(aX, aY, bX, bY){
xd = aX - bX
yd = aY - bY
return(Math.sqrt(xd*xd+yd*yd));
}


iNils 21.09.2006 16:09

Вложений: 1
Вроде все верно...
Только надо добавить проверку на порядок обхода, то есть точка в треугольник если у каждой линии false либо у всех true.

iNils 21.09.2006 16:42

Вложений: 1
Вот теперь все в полном виде.

goarcade 22.09.2006 12:03

Код:

//px,py- координаты точки
//ax,ay,bx,by,cx,cy -треугольник abc
_hitTest = function (px, py, ax, ay, bx, by, cx, cy) {
        var ab=(px-bx)*(ay-by)+(py-by)*(bx-ax)
        var bc=(px-cx)*(by-cy)+(py-cy)*(cx-bx)
        var ca=(px-ax)*(cy-ay)+(py-ay)*(ax-cx)
        if ((ab<0 && bc<0 && ca<0)||(ab>0 && bc>0 && ca>0)) {
                return true;
        } else {
                return false;
        }
};


whiteRed 22.09.2006 12:38

вроде работает


Часовой пояс GMT +4, время: 12:58.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.