找回密码
 点一下
查看: 3764|回复: 6

多边形区域生成及点在多边形区域内计算判断

[复制链接]
发表于 2011-9-20 23:12:57 | 显示全部楼层 |阅读模式
因为工作的原因,现在才写完……
先是代码:
[jass]

//Globals
int g_MaxPolygonNum = 0;
const int g_MaxVerTex = 10;
const string g_PolygonDataTableName = "PolygonDataTableName";
const string g_VertexDataTableName = "VertexDataTableName";
//Struct
struct Vertex
{
    point VertexPoint;
    fixed X;
    fixed Y;
};
struct Edge
{
    fixed MaxX;
    fixed MinX;
    fixed MaxY;
    fixed MinY;
};
struct ContentRegion
{
    fixed MaxX;
    fixed MinX;
    fixed MaxY;
    fixed MinY;
};
int PRC_PolygonInitialization ()
{
    g_MaxPolygonNum = g_MaxPolygonNum + 1;
    return g_MaxPolygonNum;
}
void PRC_PolygonAddVertex(int p_PolygonNum , point p_PolygonVertex)
{
    string l_PolygonNumName = g_PolygonDataTableName + IntToString(p_PolygonNum);
    int l_TempVertexIndex = DataTableGetInt(true , l_PolygonNumName);
   
    DataTableSetPoint(true , l_PolygonNumName + g_VertexDataTableName + IntToString(l_TempVertexIndex) , p_PolygonVertex);
    DataTableSetInt(true , l_PolygonNumName , l_TempVertexIndex + 1);
}
fixed PRC_BeelineOperation (fixed p_Y , point p_P0 , point p_P1)
{
    fixed l_X0 = PointGetX(p_P0);
    fixed l_Y0 = PointGetY(p_P0);
    fixed l_X1 = PointGetX(p_P1);
    fixed l_Y1 = PointGetY(p_P1);
   
    if (l_Y0 == l_Y1)
    {
        return -1;
    }
   
    return (l_X1 - l_X0) * (p_Y - l_Y0) / (l_Y1 - l_Y0) + l_X0;
}
fixed PRC_RegionEdgeSet (fixed p_RegionPrecision , fixed p_MinX , fixed p_LoopX)
{
    return Trunc((p_LoopX - p_MinX) / p_RegionPrecision) * p_RegionPrecision + p_MinX;
}
bool PRC_InsidePolygonRegionCheck (int p_PolygonNum , point p_CheckPoint)
{
    string l_PolygonNumName = g_PolygonDataTableName + IntToString(p_PolygonNum);
    int l_TempVertexIndex = DataTableGetInt(true , l_PolygonNumName);
    //Vertex [g_MaxVerTex + 1] l_Vertex;
    Vertex [11] l_Vertex;
    fixed l_X = PointGetX(p_CheckPoint);
    fixed l_Y = PointGetY(p_CheckPoint);
    int l_I = 0;
    int l_TempIndex = 0;
   
    while (l_I < l_TempVertexIndex)
    {
        l_Vertex[l_I].VertexPoint = DataTableGetPoint(true , l_PolygonNumName + g_VertexDataTableName + IntToString(l_I));
        l_Vertex[l_I].X = PointGetX(l_Vertex[l_I].VertexPoint);
        l_Vertex[l_I].Y = PointGetY(l_Vertex[l_I].VertexPoint);
        l_I = l_I + 1;
    }
    l_Vertex[l_I].VertexPoint = l_Vertex[0].VertexPoint;
    l_Vertex[l_I].X = l_Vertex[0].X;
    l_Vertex[l_I].Y = l_Vertex[0].Y;
   
    l_I = 0;
    while (l_I < l_TempVertexIndex)
    {
        if ((l_Y < l_Vertex[l_I].Y && l_Y > l_Vertex[l_I + 1].Y) || (l_Y > l_Vertex[l_I].Y && l_Y < l_Vertex[l_I + 1].Y))
        {
            if (PRC_BeelineOperation(l_Y , l_Vertex[l_I].VertexPoint , l_Vertex[l_I + 1].VertexPoint) < l_X)
            {
                l_TempIndex = l_TempIndex + 1;
            }
        }
        l_I = l_I + 1;
    }
    if (ModI(l_TempIndex , 2) == 1)
    {
        return true;
    }
    else
    {
        return false;
    }
}
region PRC_PolygonRegionCreate (int p_PolygonNum , fixed p_RegionPrecision)
{
    string l_PolygonNumName = g_PolygonDataTableName + IntToString(p_PolygonNum);
    region l_ReturnRegion = RegionEmpty();
    int l_TempVertexIndex = DataTableGetInt(true , l_PolygonNumName);
    int l_I = 0;
    int l_J = 0;
    int l_TempIndex = 0;
    //fixed [g_MaxVerTex + 1] l_TempX;Vertex [g_MaxVerTex + 1] l_Vertex;Edge [g_MaxVerTex + 1] l_Edge;
    fixed [11] l_TempX;
    Vertex [11] l_Vertex;
    Edge [11] l_Edge;
    ContentRegion l_ContentRegion;
    fixed l_LoopX = 0;
    fixed l_LoopY = 0;
    fixed l_TempChangeValue = 0;
   
   
    if (l_TempVertexIndex < 3 || l_TempVertexIndex > g_MaxVerTex)
    {
        return null;
    }
   
    l_ContentRegion.MinX = 257;
    l_ContentRegion.MinY = 257;
   
    while (l_I < l_TempVertexIndex)
    {
        l_Vertex[l_I].VertexPoint = DataTableGetPoint(true , l_PolygonNumName + g_VertexDataTableName + IntToString(l_I));
        l_Vertex[l_I].X = PointGetX(l_Vertex[l_I].VertexPoint);
        l_Vertex[l_I].Y = PointGetY(l_Vertex[l_I].VertexPoint);
        
        l_ContentRegion.MaxX = MaxF(l_ContentRegion.MaxX , l_Vertex[l_I].X);
        l_ContentRegion.MinX = MinF(l_ContentRegion.MinX , l_Vertex[l_I].X);
        l_ContentRegion.MaxY = MaxF(l_ContentRegion.MaxY , l_Vertex[l_I].Y);
        l_ContentRegion.MinY = MinF(l_ContentRegion.MinY , l_Vertex[l_I].Y);
        
        if (l_I > 0)
        {
            l_Edge[l_I - 1].MaxX = MaxF(l_Vertex[l_I - 1].X , l_Vertex[l_I].X);
            l_Edge[l_I - 1].MinX = MinF(l_Vertex[l_I - 1].X , l_Vertex[l_I].X);
            l_Edge[l_I - 1].MaxY = MaxF(l_Vertex[l_I - 1].Y , l_Vertex[l_I].Y);
            l_Edge[l_I - 1].MinY = MinF(l_Vertex[l_I - 1].Y , l_Vertex[l_I].Y);
        }
        l_I = l_I + 1;
    }
   
    l_Vertex[l_I].VertexPoint = l_Vertex[0].VertexPoint;
    l_Vertex[l_I].X = l_Vertex[0].X;
    l_Vertex[l_I].Y = l_Vertex[0].Y;
   
    l_I = l_I - 1;
    l_Edge[l_I].MaxX = MaxF(l_Vertex[l_I].X , l_Vertex[0].X);
    l_Edge[l_I].MinX = MinF(l_Vertex[l_I].X , l_Vertex[0].X);
    l_Edge[l_I].MaxY = MaxF(l_Vertex[l_I].Y , l_Vertex[0].Y);
    l_Edge[l_I].MinY = MinF(l_Vertex[l_I].Y , l_Vertex[0].Y);
   
    l_LoopY = l_ContentRegion.MinY;
   
    while (l_LoopY < l_ContentRegion.MaxY)
    {
        l_I = 0;
        l_TempIndex = 0;
        while (l_I < l_TempVertexIndex)
        {
            if (l_LoopY < l_Edge[l_I].MaxY && l_LoopY > l_Edge[l_I].MinY)
            {
                l_TempX[l_TempIndex] = PRC_BeelineOperation(l_LoopY , l_Vertex[l_I].VertexPoint , l_Vertex[l_I + 1].VertexPoint);
                if (l_TempX[l_TempIndex] != -1)
                {
                    l_TempIndex = l_TempIndex + 1;
                }
            }
            l_I = l_I + 1;
        }
        
        l_TempIndex = l_TempIndex - 1;
        if (l_TempIndex != -1)
        {
            l_I = 0;
            while (l_I < l_TempIndex)
            {
                l_J = 0;
                while (l_J < l_TempIndex)
                {
                    l_TempChangeValue = MaxF(l_TempX[l_J] , l_TempX[l_J + 1]);
                    l_TempX[l_J] = MinF(l_TempX[l_J] , l_TempX[l_J + 1]);
                    l_TempX[l_J + 1] = l_TempChangeValue;
                    l_J = l_J + 1;
                }
                l_I = l_I + 1;
            }
            
            l_I = 1;
            l_LoopX = PRC_RegionEdgeSet(p_RegionPrecision , l_ContentRegion.MinX , l_TempX[0]);
            while (l_LoopX < l_TempX[l_TempIndex])
            {
                if (l_LoopX > l_TempX[l_I])
                {
                    l_LoopX = PRC_RegionEdgeSet(p_RegionPrecision , l_ContentRegion.MinX , l_TempX[l_I + 1]);
                    l_I = l_I + 2;
                }            
                else
                {
                    RegionAddRect(l_ReturnRegion , true , l_LoopX - p_RegionPrecision * 0.51 , l_LoopY - p_RegionPrecision * 0.51 , l_LoopX + p_PolygonNum * 0.51 , l_LoopY + p_RegionPrecision * 0.51);
                }
                l_LoopX = l_LoopX + p_RegionPrecision;
            }
        }
        l_LoopY = l_LoopY + p_RegionPrecision;
    }
    return l_ReturnRegion;
}

[/jass]
两处注释处是修改最大顶点数量的位置。

具体效果看演示吧,不多说了。
只是提一句,生成区域的性价比不见得笔挨个计算判断的运行效率高,所以一般情况下还是用计算方法吧。
PRC.SC2Map (33 KB, 下载次数: 42)

评分

参与人数 1威望 +3 收起 理由
oneonestar + 3 原创奖励

查看全部评分

 楼主| 发表于 2011-9-20 23:25:44 | 显示全部楼层
为了某勋章,自己吃掉沙发……
回复

使用道具 举报

发表于 2012-1-28 18:53:10 | 显示全部楼层
虽不明但觉厉!

好想看懂但却无能为力啊。。。
回复

使用道具 举报

发表于 2012-1-28 21:49:51 | 显示全部楼层
回复

使用道具 举报

发表于 2012-2-8 17:59:11 | 显示全部楼层
[s:166]
回复

使用道具 举报

发表于 2012-2-10 00:52:01 | 显示全部楼层
SC2么,上面怎么标注的是jass啊·····我现在迷糊了·····
回复

使用道具 举报

发表于 2012-2-10 01:05:50 | 显示全部楼层
因為論壇只有JASS高亮插件
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-4-27 02:05 , Processed in 0.212493 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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