Debug.output("DD, filled!");
if (DEBUG) Debug.output("DD, filled!");
    protected ArrayList _forwardPoly(float[] rawllpts, int ltype, int nsegs,                                     boolean isFilled) {        // Idea:        //      The azimuthal projection family (mostly) shows one        //      hemisphere only.        //      A Poly can be projected in 3 ways:        //              1) fully inside hemisphere        //              2) fully outside hemisphere        //              3) partially inside/outside hemisphere        //      Case 3 is the hard one to deal with. A Poly which is        //      partially inside will be projected into 1 or more        //      subsections. If the poly isn't filled, we can just        //      return the subsections. If the poly is filled, then        //      we need to add points that lie on the hemisphere edge        //      in order to complete the polygon.        //        // Algorithm:        //      * Iterate through rawllpts, projecting as we go. If        //      we see any inside->outside and outside->inside        //      transitions, mark them and save them.        //        //      * Return all projected points if case 1, or nothing        //      if case 2.        //              //      * For case 3:        //        //              * If poly isn't filled, just return the        //              subsections determined while iterating. For        //              example return four projected subsections in        //              the following ways:        //        //        //                                  AA        //              /--------------------------------------------\        //              |  1  |xx|     2     |xxxx|   3    |xx|  4   |        //              \--------------------------------------------/        //               ^---^    ^---------^      ^------^    ^----^        //        //                                  BB        //              /--------------------------------------------\        //              |xx| 1  |x|   2    |xxxxx|   3   |xx|   4  |x|        //              \--------------------------------------------/        //                  ^--^  ^-------^       ^-----^    ^----^        //        //                                  CC        //              /--------------------------------------------\        //              |x| 1  |xx|   2    |xxxx|   3   |xxxx|   4   |        //              \--------------------------------------------/        //                 ^--^    ^-------^     ^-----^      ^-----^        //        //                                  DD        //              /--------------------------------------------\        //              |  1  |xxx|   2    |xxxxx|   3   |xx|   4  |x|        //              \--------------------------------------------/        //               ^---^    ^-------^       ^-----^    ^----^        //        //              * Otherwise poly is filled.  There is a        //              special case of AA above where we need to wrap        //              the vertices so that the coloring is done        //              correctly for 3 subsections:        //        //                             AA with wrap        //              /--------------------------------------------\        //              |  1b |xx|      2    |xxxx|   3    |xx|  1a  |        //              \--------------------------------------------/        //               ----^    ^---------^      ^------^    ^-----        //        //              We wrap by copying the finishing 1b section to        //              the back:        //        //              /--------------------------------------------+-----\        //              |  1b |xx|      2    |xxxx|   3    |xx|  1a  | 1b  |        //              \--------------------------------------------+-----/        //                        ^---------^      ^------^    ^----------^        //        //      * For filled polys, we also need to add vertices along        //      the horizon edge in order to make sure the rendering        //      is done properly along the horizon edge. The        //      interested hacker (the one who's still reading this        //      comment at this point!) should refer to the method        //      following this one for a description of the caveats        //      and the extra processing needed for filled polys.        //        int len = rawllpts.length >>> 1;        if (len < 2)            return new ArrayList(0);        // handle complicated line in specific routines        if (isComplicatedLineType(ltype))            return doPolyDispatch(rawllpts, ltype, nsegs, isFilled);        int invalid_count = 0;//number of invalid points        boolean curr_invalid, prev_invalid = false;//previous invalid                                                   // forward        Point temp = new Point();        AzimuthVar az_first = null, az_save = null, azVar = new AzimuthVar();        ArrayList sections = new ArrayList(128);        int[] x_, xs = new int[len];        int[] y_, ys = new int[len];        // handle first point        _forward(rawllpts[0], rawllpts[1], temp, azVar);        xs[0] = temp.x;        ys[0] = temp.y;        prev_invalid = azVar.invalid_forward;        if (prev_invalid) {            ++invalid_count;        } else {            // save beginning of subsection if not filled            azVar.index = 0;            azVar.current_azimuth = GreatCircle.spherical_azimuth(ctrLat,                    ctrLon,                    rawllpts[0],                    rawllpts[1]);            //          Debug.output("marker0="+azVar.index+            //                  " az="+ProjMath.radToDeg(azVar.current_azimuth));            if (!isFilled) {                sections.add(azVar);            } else {                az_first = azVar;            }            azVar = new AzimuthVar();        }        // iterate through all rawllpts        int i = 0, j = 0;        for (i = 1, j = 2; i < len; i++, j += 2) {            azVar.invalid_forward = false;//reset forward flag            _forward(rawllpts[j], rawllpts[j + 1], temp, azVar);            curr_invalid = azVar.invalid_forward;            xs[i] = temp.x;            ys[i] = temp.y;            if (!curr_invalid && prev_invalid) {                // record transition (outside -> inside)                azVar.index = i - 1;//include outside point                azVar.current_azimuth = GreatCircle.spherical_azimuth(ctrLat,                        ctrLon,                        rawllpts[j - 2],                        rawllpts[j - 1]);                //              Debug.output("marker oi="+azVar.index+                //                      " az="+ProjMath.radToDeg(azVar.current_azimuth));                sections.add(azVar);                azVar = new AzimuthVar();            } else if (curr_invalid) {                if (!prev_invalid) {                    // record transition (inside -> outside)                    azVar.index = i;//include outside point                    if (isFilled && (invalid_count == 0)) {                        az_save = azVar;//save wrap-end                    } else {                        //                      Debug.output("marker io="+azVar.index+                        //                              "                        // az="+ProjMath.radToDeg(azVar.current_azimuth));                        sections.add(azVar);                    }                    azVar = new AzimuthVar();                }                ++invalid_count;            }            prev_invalid = curr_invalid;        }        // poly completely inside        if (invalid_count == 0) {            ArrayList ret_val = new ArrayList(2);            ret_val.add(xs);            ret_val.add(ys);            return ret_val;        }        // poly completely outside        if (invalid_count == len) {            return new ArrayList(0);        }        // handle poly that is partially inside hemisphere        // cases AA & CC        if (!prev_invalid) {            // special case AA wrapping:            if (isFilled && (az_save != null)) {                // copy the wrapped portion into                int l = az_save.index;                x_ = new int[len + l];                y_ = new int[len + l];                System.arraycopy(xs, 0, x_, 0, len);                System.arraycopy(ys, 0, y_, 0, len);                System.arraycopy(xs, 0, x_, len, l);                System.arraycopy(ys, 0, y_, len, l);                az_save.index = len + l;                //              Debug.output("wrap end="+az_save.index+                //                      " az="+ProjMath.radToDeg(az_save.current_azimuth));                sections.add(az_save);//complete section                xs = x_;                ys = y_;                // case CC or AA (non-wrapping):            } else {                if (isFilled && (az_save == null)) {                    Debug.output("AA, filled, no-wrap!");                }                azVar.index = i;                j = rawllpts.length;                azVar.current_azimuth = GreatCircle.spherical_azimuth(ctrLat,                        ctrLon,                        rawllpts[j - 2],                        rawllpts[j - 1]);                //              Debug.output("marker end="+azVar.index+                //                      " az="+ProjMath.radToDeg(azVar.current_azimuth));                sections.add(azVar);            }            // special case DD        } else if (az_save != null) {            Debug.output("DD, filled!");            sections.add(az_first);            sections.add(az_save);        }        int size = sections.size();        ArrayList ret_val = new ArrayList(size);        // filled poly: handle fill problems        if (isFilled && (len > 2)) {            generateFilledPoly(xs, ys, sections, ret_val);            return ret_val;        }        // non-filled poly: just extract the subsections        for (j = 0; j < size; j += 2) {            AzimuthVar az1 = (AzimuthVar) sections.get(j);            AzimuthVar az2 = (AzimuthVar) sections.get(j + 1);            int off1 = az1.index;            int off2 = az2.index;            int l = off2 - off1;            x_ = new int[l];            y_ = new int[l];            System.arraycopy(xs, off1, x_, 0, l);            System.arraycopy(ys, off1, y_, 0, l);            ret_val.add(x_);            ret_val.add(y_);        }        return ret_val;    }//_forwardPoly()