Esempio n. 1
0
        public int median3(int low, int high)
        {
            int l = low;
            int c = (high + low) >> 1;
            int h = high - 2;

            SortItem lv = g_items[l];
            SortItem cv = g_items[c];
            SortItem hv = g_items[h];

            if (hv.v < lv.v || (hv.v == lv.v && hv.iptr < lv.iptr))
            {
                swap(ref l, ref h); swap(lv, hv);
            }
            if (cv.v < lv.v || (cv.v == lv.v && cv.iptr < lv.iptr))
            {
                swap(ref l, ref c); swap(lv, cv);
            }
            if (hv.v < cv.v || (hv.v == cv.v && hv.iptr < cv.iptr))
            {
                swap(ref c, ref h); swap(cv, hv);
            }

            return(c);
        }
Esempio n. 2
0
        void swap(SortItem a, SortItem b)
        {
            SortItem tmp = new SortItem(ref a);

            a.polygon = b.polygon; a.v = b.v; a.iptr = b.iptr;
            b.polygon = tmp.polygon; b.v = tmp.v; b.iptr = tmp.iptr;
        }
Esempio n. 3
0
        int getPartition(int i, int j)
        {
            SortItem pivot = g_items[i];

            while (i < j)
            {
                while (i < j && g_items[i].v < pivot.v || (g_items[i].v == pivot.v && g_items[i].iptr < pivot.iptr))
                {
                    i++;
                }
                while (i < j && j >= 0 && pivot.v < g_items[j].v || (pivot.v == g_items[j].v && pivot.iptr < g_items[j].iptr))
                {
                    j--;
                }
                swap(g_items[i], g_items[j]);
            }
            swap(g_items[i], pivot);
            return(i);
        }
Esempio n. 4
0
 public SortItem(SortItem s)
 {
     v       = s.v;
     iptr    = s.iptr;
     polygon = new Polygon(ref s.polygon);
 }
Esempio n. 5
0
        // 选则最好分割面
        int getOptimalSplitPlane(ref List <Polygon> polygons, int numPolygons, ref float bestSplitPos, ref AABB aabb)
        {
            int   bestSplitAxis = -1;
            float bestCost      = 0;

            for (int axis = 0; axis < 3; axis++)
            {
                int[] nextAxis = new int[] { 1, 2, 0, 1 };

                // 构建 item 数组
                int k = 0;
                for (int i = 0; i < numPolygons; i++)
                {
                    Polygon poly = polygons[i];
                    float   mn   = poly[0][axis];
                    float   mx   = mn;
                    for (int j = 1; j < poly.numPoints(); j++)  // 得到每个多边形的包围盒
                    {
                        mn = Math.Min(mn, poly[j][axis]);
                        mx = Math.Max(mx, poly[j][axis]);
                    }

                    g_items[k].v        = mn;
                    g_items[k].polygon  = polygons[i];
                    g_items[k].iptr     = (uint)k;
                    g_items[k + 1].v    = mx;
                    g_items[k + 1].iptr = (uint)k + 1;;
                    k += 2;
                }

                //for (int i = 0; i < numPolygons * 2; i++)
                //{
                //    Console.WriteLine("{0},{1},{2}", i, g_items[i].v, g_items[i].iptr);
                //}
                //Console.WriteLine();

                // 排序
                quickSort(0, numPolygons * 2);

                //for (int i = 0; i < numPolygons * 2; i++)
                //{
                //    Console.WriteLine("{0},{1},{2}", i, g_items[i].v, g_items[i].iptr);
                //}
                //Console.WriteLine();
                //Console.WriteLine();

                // 区域
                int   c1         = nextAxis[axis];
                int   c2         = nextAxis[axis + 1];
                float areaConst  = 2 * (aabb.m_mx[c1] - aabb.m_mn[c1]) * (aabb.m_mx[c2] - aabb.m_mn[c2]);
                float areaFactor = 2 * ((aabb.m_mx[c1] - aabb.m_mn[c1]) + (aabb.m_mx[c2] - aabb.m_mn[c2]));
                float boundLeft  = aabb.m_mn[axis];
                float boundRight = aabb.m_mx[axis];

                // 遍历,寻找最小代价分割面
                float bestAxisCost  = 0;
                float bestAxisSplit = 0;
                int   leftPolys     = 0;
                int   rightPolys    = numPolygons;
                int   bothPolys     = 0;
                for (int i = 0; i < numPolygons * 2; i++)
                {
                    SortItem it = g_items[i];

                    if (it.iptr % 2 == 0)
                    {
                        leftPolys++;
                        bothPolys++;
                    }

                    if (it.v >= boundRight)
                    {
                        break;
                    }

                    if (it.v > boundLeft)
                    {
                        float split  = it.v;
                        float aLeft  = areaConst + areaFactor * (split - boundLeft);
                        float aRight = areaConst + areaFactor * (boundRight - split);
                        float cost   = aLeft * leftPolys + aRight * rightPolys;
                        if (cost < bestAxisCost || bestAxisCost == 0)
                        {
                            bestAxisCost  = cost;
                            bestAxisSplit = split;
                        }
                    }
                    if (it.iptr % 2 == 1)
                    {
                        rightPolys--;
                        bothPolys--;
                    }
                }

                if ((bestAxisCost < bestCost || bestCost == 0) && bestAxisCost > 0)
                {
                    bestCost      = bestAxisCost;
                    bestSplitPos  = bestAxisSplit;
                    bestSplitAxis = axis;
                }
            }

            return(bestSplitAxis);
        }