EaBIM一直以来积极响应国家“十二五”推进建筑业信息化的号召,对建筑领域的信息技术开展深入技术交流和探讨!致力于打造“BIM-建筑师-生态技术”三位一体综合资源交流共享平台,希望为BIM与可持续设计理念及技术的普及做出微小的贡献!!!

EaBIM

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
查看: 4140|回复: 48
打印 上一主题 下一主题

判段点是否在多边形内

[复制链接]

1514

主题

7465

帖子

1万

积分

admin

Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10

积分
12404

社区QQ达人

跳转到指定楼层
楼主
发表于 2014-1-9 14:27:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
点在多边形内是几何,图形学,游戏领域经常用到的算法,算法的描述网上有很多,就是经过这点和多边形内一点连线,然后根据线与多边形的交点数目来判断,多的就不说了,直接来个源代码,大家用着方便

bool   IsPtInArea(AcGePoint3d pt, AcGePoint3dArray& pt3dArr)
{
    int iLen = pt3dArr.length();
    if (iLen < 3)
        return false;
    // 首先构造最小包络面并得到最大 x 坐标
    int i;
    double dblMaxX = pt3dArr[0].x;
    double dblMinX = pt3dArr[0].x;
    double dblMaxY = pt3dArr[0].y;
    double dblMinY = pt3dArr[0].y;
    for (i = 1; i < iLen; i++)
    {
        if (pt3dArr.x > dblMaxX)
            dblMaxX = pt3dArr.x;
        if (pt3dArr.x < dblMinX)
            dblMinX = pt3dArr.x;
        if (pt3dArr.y > dblMaxY)
            dblMaxY = pt3dArr.y;
        if (pt3dArr.y < dblMinY)
            dblMinY = pt3dArr.y;
    }
    // 如果点位于最小包络面之外,则肯定不在区域内,直接返回 false
    if (( pt.x > dblMaxX) ||
        ( pt.x < dblMinX) ||
        ( pt.y > dblMaxY) ||
        ( pt.y < dblMinY)
        )
        return false;

    // 循环求取交点
    pt.z = 0.0;
    AcGePoint3d xpt, ipt;
    xpt = pt;
    xpt.x = dblMaxX + 10.0;
    //xpt.x = 1.7e208;
    AcGeLineSeg3d lineseg3d(pt, xpt);
    AcGePoint3d p1 = pt3dArr.first();

    p1.z = 0.0;
    bool bAdd = false;
    if (!pt3dArr[iLen - 1].isEqualTo(p1)){
        pt3dArr.append(p1);
        iLen++;
        bAdd = true;
    }

    AcGePoint3d p2;
    int nCount = 0;
    for (i=1; i < iLen; i++)
    {
        p2 = pt3dArr;
        p2.z = 0.0;
        // 如果所给点与顶点相等,直接返回
        if (pt.isEqualTo(p1))
        {
            if (bAdd)
                pt3dArr.removeLast();
            return true;
        }
        AcGeLineSeg3d xlineseg3d(p1, p2);
        // 如果所给点在某一条边上,直接返回
        if (xlineseg3d.isOn(pt) == Adesk::kTrue)
        {
            if (bAdd)
                pt3dArr.removeLast();
            return true;
        }
        // 如果构造线段与交点存在,加入交点表
        if (lineseg3d.intersectWith(xlineseg3d, ipt) == Adesk::kTrue)
        {
            //bool bAdd = true;
            // 如果交点正好为顶点,判断另外的端点在哪一侧
            if (ipt.isEqualTo(p1))
            {
                if (p2.y > ipt.y)
                    nCount++;
            }
            else if(ipt.isEqualTo(p2))
            {
                if (p1.y > ipt.y)
                    nCount++;
            }
            else
                nCount++;
        }
        p1 = p2;
    }

    if (bAdd)
        pt3dArr.removeLast();
   
    if ((nCount % 2) == 0)
        return false; // 交点数为偶数,不在区域内
    else
        return true; // 交点数为奇数,在区域内
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 转播转播 分享分享 分享淘帖 支持支持 反对反对
工作时间:工作日的9:00-12:00/13:30-18:00,节假日不在线,请勿留言
推荐
发表于 2017-6-1 10:16:16 | 只看该作者
好东西大家共享,一起进步,

7

主题

896

帖子

1515

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1515
推荐
发表于 2014-6-12 09:47:57 | 只看该作者
路过!!!
不发表意见……

12

主题

221

帖子

549

积分

BIM专业负责人

Rank: 4Rank: 4Rank: 4Rank: 4

积分
549

社区QQ达人

6F
发表于 2014-3-13 14:59:33 | 只看该作者

好强大啊,谢谢哈

4

主题

864

帖子

1390

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1390
7F
发表于 2014-3-26 16:09:27 | 只看该作者
路过!!!
不发表意见……

8

主题

767

帖子

1383

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1383
14F
发表于 2014-4-11 11:26:37 | 只看该作者
顶......
楼下跟上.....
*滑块验证:
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|EaBIM网 ( 苏ICP备2020058923号-1  苏公网安备32011502011255号

GMT+8, 2024-11-23 10:47

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表