001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005package armyc2.c5isr.JavaLineArray;
006
007import java.util.ArrayList;
008
009import armyc2.c5isr.JavaTacticalRenderer.TGLight;
010import armyc2.c5isr.renderer.utilities.ErrorLogger;
011import armyc2.c5isr.renderer.utilities.RendererException;
012import armyc2.c5isr.renderer.utilities.RendererSettings;
013import armyc2.c5isr.renderer.utilities.Color;
014import armyc2.c5isr.renderer.utilities.IPointConversion;
015import armyc2.c5isr.graphics2d.Area;
016import armyc2.c5isr.graphics2d.BasicStroke;
017import armyc2.c5isr.graphics2d.Polygon;
018import armyc2.c5isr.graphics2d.Rectangle2D;
019import armyc2.c5isr.graphics2d.Shape;
020
021/**
022 * Class to process the pixel arrays
023 */
024public final class arraysupport {
025
026    private static final double maxLength = 100;
027    private static final double minLength = 2.5;    //was 5
028    private static double dACP = 0;
029    private static final String _className = "arraysupport";
030
031//    protected static void setMinLength(double value)
032//    {
033//        minLength=value;
034//    }
035    private static void FillPoints(POINT2[] pLinePoints,
036            int counter,
037            ArrayList<POINT2> points) {
038        points.clear();
039        for (int j = 0; j < counter; j++) {
040            points.add(pLinePoints[j]);
041        }
042    }
043
044    /**
045     * This is the interface function to CELineArray from clsRenderer2 for
046     * non-channel types
047     *
048     * @param pts the client points
049     * @param shapes the symbol ShapeInfo objects
050     * @param clipBounds the rectangular clipping bounds
051     */
052    public static ArrayList<POINT2> GetLineArray2(TGLight tg,
053            ArrayList<POINT2> pts,
054            ArrayList<Shape2> shapes,
055            Rectangle2D clipBounds,
056            IPointConversion converter) {
057
058        ArrayList<POINT2> points = null;
059        try {
060            POINT2 pt = null;
061            POINT2[] pLinePoints2 = null;
062            POINT2[] pLinePoints = null;
063            int vblSaveCounter = pts.size();
064            //get the count from countsupport
065            int j = 0;
066            if (pLinePoints2 == null || pLinePoints2.length == 0)//did not get set above
067            {
068                pLinePoints = new POINT2[vblSaveCounter];
069                for (j = 0; j < vblSaveCounter; j++) {
070                    pt = (POINT2) pts.get(j);
071                    pLinePoints[j] = new POINT2(pt.x, pt.y, pt.style);
072                }
073            }
074            //get the number of points the array will require
075            int vblCounter = countsupport.GetCountersDouble(tg, vblSaveCounter, pLinePoints, clipBounds);
076
077            //resize pLinePoints and fill the first vblSaveCounter elements with the original points
078            if (vblCounter > 0) {
079                pLinePoints = new POINT2[vblCounter];
080            } else {
081                shapes = null;
082                return null;
083            }
084
085            lineutility.InitializePOINT2Array(pLinePoints);
086
087            //safeguards added 2-17-11 after CPOF client was allowed to add points to autoshapes
088            if (vblSaveCounter > pts.size()) {
089                vblSaveCounter = pts.size();
090            }
091            if (vblSaveCounter > pLinePoints.length) {
092                vblSaveCounter = pLinePoints.length;
093            }
094
095            for (j = 0; j < vblSaveCounter; j++) {
096                pt = (POINT2) pts.get(j);
097                pLinePoints[j] = new POINT2(pt.x, pt.y, pt.style);
098            }
099            //we have to adjust the autoshapes because they are instantiating with fewer points
100            points = GetLineArray2Double(tg, pLinePoints, vblCounter, vblSaveCounter, shapes, clipBounds, converter);
101
102        } catch (Exception exc) {
103            ErrorLogger.LogException(_className, "GetLineArray2",
104                    new RendererException("GetLineArray2 " + Integer.toString(tg.get_LineType()), exc));
105
106        }
107        return points;
108        //the caller can get points
109    }
110
111    /**
112     * A function to calculate the points for FORTL
113     *
114     * @param pLinePoints OUT - the points arry also used for the return points
115     * @param vblSaveCounter the number of client points
116     * @return
117     */
118    private static int GetFORTLPointsDouble(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
119        int nCounter = 0;
120        try {
121            int j = 0, k = 0, bolVertical = 0;
122            int lCount = 0;
123            final double dIncrement = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
124            ref<double[]> m = new ref();
125            POINT2[] pSpikePoints = null;
126            POINT2 pt0 = new POINT2(), pt1 = new POINT2();
127
128            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
129            int numGlyphs = 0;
130            final double dGlyphSize = dIncrement / 2;
131
132            pSpikePoints = new POINT2[lCount];
133            lineutility.InitializePOINT2Array(pSpikePoints);
134
135            for (j = 0; j < vblSaveCounter - 1; j++) {
136                bolVertical = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
137                double dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
138                if (dLengthSegment / dIncrement < 1) {
139                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j]);
140                    nCounter++;
141                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
142                    nCounter++;
143                    continue;
144                }
145                numGlyphs = (int) (dLengthSegment / dIncrement);
146                final double dSegIncrement = (dLengthSegment / numGlyphs);
147
148                //for (k = 0; k < dLengthSegment / 20 - 1; k++)
149                for (k = 0; k < numGlyphs; k++) {
150                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dSegIncrement, 0);
151                    nCounter++;
152                    //pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dSegIncrement - 10, 0);
153                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dSegIncrement - dSegIncrement / 2, 0);
154                    nCounter++;
155                    pt0 = new POINT2(pSpikePoints[nCounter - 1]);
156                    //pt1 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], 10);
157                    pt1 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], dSegIncrement / 2);
158                    //the spikes
159                    if (pLinePoints[j].x > pLinePoints[j + 1].x) {
160                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 3, dGlyphSize);
161                        nCounter++;
162                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt1, 3, dGlyphSize);
163                        nCounter++;
164                    }
165                    if (pLinePoints[j].x < pLinePoints[j + 1].x) {
166                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 2, dGlyphSize);
167                        nCounter++;
168                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt1, 2, dGlyphSize);
169                        nCounter++;
170                    }
171                    if (pLinePoints[j].x == pLinePoints[j + 1].x) {
172                        if (pLinePoints[j].y < pLinePoints[j + 1].y) {
173                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 1, dGlyphSize);
174                            nCounter++;
175                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt1, 1, dGlyphSize);
176                            nCounter++;
177                        }
178                        if (pLinePoints[j].y > pLinePoints[j + 1].y) {
179                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 0, dGlyphSize);
180                            nCounter++;
181                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt1, 0, dGlyphSize);
182                            nCounter++;
183                        }
184                    }
185                    //pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 3], 10, 0);
186                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 3], dSegIncrement / 2, 0);
187                    nCounter++;
188                }//end for k
189                pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
190                nCounter++;
191            }//end for j
192            for (j = 0; j < nCounter; j++) {
193                pLinePoints[j] = new POINT2(pSpikePoints[j]);
194            }
195
196            return nCounter;
197        } catch (Exception exc) {
198            ErrorLogger.LogException(_className, "GetFORTLPointsDouble",
199                    new RendererException("GetFORTLPointsDouble " + Integer.toString(tg.get_LineType()), exc));
200        }
201        return nCounter;
202    }
203
204    private static int GetATWallPointsDouble2(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
205        int nCounter = 0;
206        try {
207            int j = 0, k = 0;
208            int lCount = 0;
209            double dLengthSegment = 0, dIncrement = 0;
210            POINT2[] pSpikePoints = null;
211            POINT2 pt0;
212            double dSpikeSize = 0;
213            int limit = 0, numSpikes = 0;;
214
215            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
216            pSpikePoints = new POINT2[lCount];
217            lineutility.InitializePOINT2Array(pSpikePoints);
218            pSpikePoints[nCounter++] = new POINT2(pLinePoints[0]);
219            for (j = 0; j < vblSaveCounter - 1; j++) {
220                dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
221                dSpikeSize = arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
222                dIncrement = 2 * dSpikeSize;
223//  diagnostic
224                numSpikes = (int) Math.round((dLengthSegment - dSpikeSize) / dIncrement);
225                dIncrement = dLengthSegment / numSpikes;
226
227                //limit = (int) (dLengthSegment / dIncrement) - 1;
228                limit = numSpikes - 1;
229//                if (limit < 1) {
230//                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j]);
231//                    nCounter++;
232//                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
233//                    nCounter++;
234//                    continue;
235//                }
236//  end diagnostic                
237                for (k = -1; k < limit; k++)//was k=0 to limit
238                {
239                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - (dSpikeSize * 3), 0);
240                    nCounter++;
241
242                    pt0 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], dSpikeSize / 2);
243
244                    //the spikes
245                    if (pLinePoints[j].x > pLinePoints[j + 1].x) //extend above the line
246                    {
247                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pSpikePoints[nCounter - 1], pt0, 2, dSpikeSize);
248                    }
249                    if (pLinePoints[j].x < pLinePoints[j + 1].x) //extend below the line
250                    {
251                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pSpikePoints[nCounter - 1], pt0, 3, dSpikeSize);
252                    }
253                    if (pLinePoints[j].x == pLinePoints[j + 1].x) {
254                        pSpikePoints[nCounter] = new POINT2(pt0);
255                        if (pLinePoints[j].y < pLinePoints[j + 1].y) //extend left of line
256                        {
257                            pSpikePoints[nCounter].x = pt0.x - dSpikeSize;
258                        } else //extend right of line
259                        {
260                            pSpikePoints[nCounter].x = pt0.x + dSpikeSize;
261                        }
262                    }
263                    nCounter++;
264
265                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 2], dSpikeSize, 0);
266                    nCounter++;
267                }
268                //use the original line point for the segment end point
269                pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
270                pSpikePoints[nCounter].style = 0;
271                nCounter++;
272            }
273
274            for (j = 0; j < nCounter; j++) {
275                pLinePoints[j] = new POINT2(pSpikePoints[j]);
276            }
277
278        } catch (Exception exc) {
279            ErrorLogger.LogException(_className, "GetATWallPointsDouble",
280                    new RendererException("GetATWallPointsDouble", exc));
281        }
282        return nCounter;
283    }
284
285    public static int GetInsideOutsideDouble2(POINT2 pt0,
286            POINT2 pt1,
287            POINT2[] pLinePoints,
288            int vblCounter,
289            int index,
290            int lineType) {
291        int nDirection = 0;
292        try {
293            ref<double[]> m = new ref();
294            ref<double[]> m0 = new ref();
295
296            double b0 = 0;
297            double b2 = 0;
298
299            double b = 0;
300            double X0 = 0;      //segment midpoint X value
301            double Y0 = 0;      //segment midpoint Y value
302            double X = 0;       //X value of horiz line from left intercept with current segment
303            double Y = 0;       //Y value of vertical line from top intercept with current segment
304            int nInOutCounter = 0;
305            int j = 0, bolVertical = 0;
306            int bolVertical2 = 0;
307            int nOrientation = 0; //will use 0 for horiz line from left, 1 for vertical line from top
308
309            POINT2 pt2 = new POINT2();
310            //end declarations. will use this to determine the direction
311
312            //slope of the segment
313            bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m0);
314            if (m0.value == null) {
315                return 0;
316            }
317            //get the midpoint of the segment
318            X0 = (pt0.x + pt1.x) / 2;
319            Y0 = (pt0.y + pt1.y) / 2;
320
321            //slope is not too small or is vertical, use left to right
322            if (Math.abs(m0.value[0]) >= 1 || bolVertical == 0) {
323                nOrientation = 0;       //left to right orientation
324                for (j = 0; j < vblCounter - 1; j++) {
325                    if (index != j) {
326                        //if ((pLinePoints[j].y <= Y0 && pLinePoints[j + 1].y >= Y0) ||
327                        //      (pLinePoints[j].y >= Y0 && pLinePoints[j + 1].y <= Y0)) 
328                        if ((pLinePoints[j].y < Y0 && pLinePoints[j + 1].y > Y0)
329                                || (pLinePoints[j].y > Y0 && pLinePoints[j + 1].y < Y0)
330                                || (pLinePoints[j].y < Y0 && pLinePoints[j + 1].y == Y0)
331                                || (pLinePoints[j].y == Y0 && pLinePoints[j + 1].y < Y0)) {
332                            bolVertical2 = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
333                            if (bolVertical2 == 1 && m.value[0] == 0) //current segment is horizontal, this should not happen
334                            {   //counter unaffected
335                                nInOutCounter++;
336                                nInOutCounter--;
337                            }
338                            //current segment is vertical, it's x value must be to the left
339                            //of the current segment X0 for the horiz line from the left to cross
340                            if (bolVertical2 == 0) {
341                                if (pLinePoints[j].x < X0) {
342                                    nInOutCounter++;
343                                }
344                            }
345
346                            //current segment is not horizontal and not vertical
347                            if (m.value[0] != 0 && bolVertical2 == 1) {
348                                //get the X value of the intersection between the horiz line
349                                //from the left and the current segment
350                                //b=Y0;
351                                b = pLinePoints[j].y - m.value[0] * pLinePoints[j].x;
352                                X = (Y0 - b) / m.value[0];
353                                if (X < X0) //the horizontal line crosses the segment
354                                {
355                                    nInOutCounter++;
356                                }
357                            }
358
359                        }       //end if
360                    }
361
362                }       //end for
363            } //end if
364            else //use top to bottom to get orientation
365            {
366                nOrientation = 1;       //top down orientation
367                for (j = 0; j < vblCounter - 1; j++) {
368                    if (index != j) {
369                        //if ((pLinePoints[j].x <= X0 && pLinePoints[j + 1].x >= X0) ||
370                        //  (pLinePoints[j].x >= X0 && pLinePoints[j + 1].x <= X0)) 
371                        if ((pLinePoints[j].x < X0 && pLinePoints[j + 1].x > X0)
372                                || (pLinePoints[j].x > X0 && pLinePoints[j + 1].x < X0)
373                                || (pLinePoints[j].x < X0 && pLinePoints[j + 1].x == X0)
374                                || (pLinePoints[j].x == X0 && pLinePoints[j + 1].x < X0)) {
375                            bolVertical2 = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
376                            if (bolVertical2 == 0) //current segment is vertical, this should not happen
377                            {   //counter unaffected
378                                nInOutCounter++;
379                                nInOutCounter--;
380                            }
381                            //current segment is horizontal, it's y value must be above
382                            //the current segment Y0 for the horiz line from the left to cross
383                            if (bolVertical2 == 1 && m.value[0] == 0) {
384                                if (pLinePoints[j].y < Y0) {
385                                    nInOutCounter++;
386                                }
387                            }
388
389                            //current segment is not horizontal and not vertical
390                            if (m.value[0] != 0 && bolVertical2 == 1) {
391                                //get the Y value of the intersection between the vertical line
392                                //from the top and the current segment
393                                b = pLinePoints[j].y - m.value[0] * pLinePoints[j].x;
394                                Y = m.value[0] * X0 + b;
395                                if (Y < Y0) //the vertical line crosses the segment
396                                {
397                                    nInOutCounter++;
398                                }
399                            }
400                        }       //end if
401                    }
402                }       //end for
403            }
404
405            switch (nInOutCounter % 2) {
406                case 0:
407                    if (nOrientation == 0) {
408                        nDirection = lineutility.extend_left;
409                    } else {
410                        nDirection = lineutility.extend_above;
411                    }
412                    break;
413                case 1:
414                    if (nOrientation == 0) {
415                        nDirection = lineutility.extend_right;
416                    } else {
417                        nDirection = lineutility.extend_below;
418                    }
419                    break;
420                default:
421                    break;
422            }
423            //reverse direction for ICING
424            if (lineType == TacticalLines.ICING) {
425                nDirection = lineutility.reverseDirection(nDirection);
426            }
427        } catch (Exception exc) {
428            ErrorLogger.LogException(_className, "GetInsideOutsideDouble2",
429                    new RendererException("GetInsideOutsideDouble2", exc));
430        }
431        return nDirection;
432    }
433
434    /**
435     * BELT and others
436     *
437     * @param pLinePoints
438     * @param vblSaveCounter
439     * @return
440     */
441    protected static int GetZONEPointsDouble2(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
442        int nCounter = 0;
443        try {
444            int lineType = tg.get_LineType();
445            int j = 0, k = 0, n = 0;
446            int lCount = 0;
447            double dLengthSegment = 0;
448            POINT2 pt0 = new POINT2(pLinePoints[0]), pt1 = null, pt2 = null, pt3 = null;
449            POINT2[] pSpikePoints = null;
450            int nDirection = 0;
451            double dIncrement = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
452
453            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
454            pSpikePoints = new POINT2[lCount];
455            lineutility.InitializePOINT2Array(pSpikePoints);
456            double remainder = 0;
457            for (j = 0; j < vblSaveCounter - 1; j++) {
458                pt1 = new POINT2(pLinePoints[j]);
459                pt2 = new POINT2(pLinePoints[j + 1]);
460                //get the direction for the spikes
461                nDirection = GetInsideOutsideDouble2(pt1, pt2, pLinePoints, vblSaveCounter, (int) j, lineType);
462                dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
463                //reverse the direction for those lines with inward spikes
464                if (dLengthSegment < dIncrement) {
465                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j]);
466                    nCounter++;
467                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
468                    nCounter++;
469                    continue;
470                }
471                switch (lineType) {
472                    case TacticalLines.OBSAREA:
473                    case TacticalLines.OBSFAREA:
474                        nDirection = lineutility.reverseDirection(nDirection);
475                        break;
476                    default:
477                        break;
478                }
479                n = (int) (dLengthSegment / dIncrement);
480                remainder = dLengthSegment - n * dIncrement;
481                for (k = 0; k < n; k++) {
482                    if (k > 0) {
483                        pSpikePoints[nCounter++] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - remainder / 2, 0);//was +0
484                        pSpikePoints[nCounter++] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - dIncrement / 2 - remainder / 2, 0);//was -10
485                    } else {
486                        pSpikePoints[nCounter++] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement, 0);//was +0
487                        pSpikePoints[nCounter++] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - dIncrement / 2, 0);//was -10
488                    }
489
490                    switch (lineType) {
491                        case TacticalLines.OBSAREA:
492                        case TacticalLines.OBSFAREA:
493                        case TacticalLines.ZONE:
494                        case TacticalLines.ENCIRCLE:
495                            pt0 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], dIncrement / 4);
496                            break;
497                        case TacticalLines.STRONG:
498                        case TacticalLines.FORT_REVD:
499                        case TacticalLines.FORT:
500                            pt0 = new POINT2(pSpikePoints[nCounter - 1]);
501                            break;
502                        default:
503                            break;
504                    }
505
506                    pSpikePoints[nCounter++] = lineutility.ExtendDirectedLine(pt1, pt2, pt0, nDirection, dIncrement / 2);
507                    //nCounter++;
508                    switch (lineType) {
509                        case TacticalLines.OBSAREA:
510                        case TacticalLines.OBSFAREA:
511                        case TacticalLines.ZONE:
512                        case TacticalLines.ENCIRCLE:
513                            pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 2], dIncrement / 2, 0);
514                            break;
515                        case TacticalLines.STRONG:
516                            pSpikePoints[nCounter] = new POINT2(pSpikePoints[nCounter - 2]);
517                            break;
518                        case TacticalLines.FORT_REVD:
519                        case TacticalLines.FORT:
520                            pt3 = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 2], dIncrement / 2, 0);
521                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pt1, pt2, pt3, nDirection, dIncrement / 2);
522                            nCounter++;
523                            pSpikePoints[nCounter] = new POINT2(pt3);
524                            break;
525                        default:
526                            break;
527                    }
528                    //}
529                    nCounter++;
530                    //diagnostic
531                    if (lineType == TacticalLines.ENCIRCLE) {
532                        pSpikePoints[nCounter++] = new POINT2(pSpikePoints[nCounter - 4]);
533                    }
534                }//end for k
535                pSpikePoints[nCounter++] = new POINT2(pLinePoints[j + 1]);
536                //nCounter++;
537            }//end for j
538            for (j = 0; j < nCounter; j++) {
539                if (lineType == (long) TacticalLines.OBSAREA) {
540                    pSpikePoints[j].style = 11;
541                }
542            }
543            if (lineType == (long) TacticalLines.OBSAREA) {
544                pSpikePoints[nCounter - 1].style = 12;
545            } else {
546                if (nCounter > 0) {
547                    pSpikePoints[nCounter - 1].style = 5;
548                }
549            }
550
551            for (j = 0; j < nCounter; j++) {
552                pLinePoints[j] = new POINT2(pSpikePoints[j]);
553                if (j == nCounter - 1) {
554                    if (lineType != (long) TacticalLines.OBSAREA) {
555                        pLinePoints[j].style = 5;
556                    }
557                }
558            }
559
560        } catch (Exception exc) {
561            ErrorLogger.LogException(_className, "GetZONEPointsDouble2",
562                    new RendererException("GetZONEPointsDouble2", exc));
563        }
564        return nCounter;
565    }
566
567    private static boolean IsTurnArcReversed(POINT2[] pPoints) {
568        try {
569            if (pPoints.length < 3) {
570                return false;
571            }
572
573            POINT2[] ptsSeize = new POINT2[2];
574            ptsSeize[0] = new POINT2(pPoints[0]);
575            ptsSeize[1] = new POINT2(pPoints[1]);
576            lineutility.CalcClockwiseCenterDouble(ptsSeize);
577            double d = lineutility.CalcDistanceDouble(ptsSeize[0], pPoints[2]);
578
579            ptsSeize[0] = new POINT2(pPoints[1]);
580            ptsSeize[1] = new POINT2(pPoints[0]);
581            lineutility.CalcClockwiseCenterDouble(ptsSeize);
582            double dArcReversed = lineutility.CalcDistanceDouble(ptsSeize[0], pPoints[2]);
583
584            ptsSeize = null;
585            if (dArcReversed > d) {
586                return true;
587            } else {
588                return false;
589            }
590        } catch (Exception exc) {
591            ErrorLogger.LogException(_className, "IsTurnArcReversed",
592                    new RendererException("IsTurnArcReversed", exc));
593        }
594        return false;
595    }
596
597    private static void GetIsolatePointsDouble(POINT2[] pLinePoints,
598            int lineType,
599            IPointConversion converter) {
600        try {
601            POINT2 pt0 = new POINT2(pLinePoints[0]), pt1 = new POINT2(pLinePoints[1]), pt2 = new POINT2(pLinePoints[0]);
602            if (pt0.x == pt1.x && pt0.y == pt1.y) {
603                pt1.x += 1;
604            }
605
606            POINT2 C = new POINT2(), E = new POINT2();
607            int j = 0, k = 0, l = 0;
608            POINT2[] ptsArc = new POINT2[26];
609            POINT2[] midPts = new POINT2[7];
610            POINT2[] trianglePts = new POINT2[35];
611            POINT2[] pArrowPoints = new POINT2[3];
612            double dRadius = lineutility.CalcDistanceDouble(pt0, pt1);
613            double dLength = Math.abs(dRadius - 20);
614            if (dRadius < 40) {
615                dLength = dRadius / 1.5;
616            }
617
618            double d = lineutility.MBRDistance(pLinePoints, 2);
619            POINT2[] ptsSeize = new POINT2[2];
620            POINT2[] savepoints = new POINT2[3];
621            for (j = 0; j < 2; j++) {
622                savepoints[j] = new POINT2(pLinePoints[j]);
623            }
624
625            if (pLinePoints.length >= 3) {
626                savepoints[2] = new POINT2(pLinePoints[2]);
627            }
628
629            lineutility.InitializePOINT2Array(ptsArc);
630            lineutility.InitializePOINT2Array(midPts);
631            lineutility.InitializePOINT2Array(trianglePts);
632            lineutility.InitializePOINT2Array(pArrowPoints);
633            lineutility.InitializePOINT2Array(ptsSeize);
634
635            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
636            if (d / 7 > maxLength * DPIScaleFactor) {
637                d = 7 * maxLength * DPIScaleFactor;
638            }
639            if (d / 7 < minLength * DPIScaleFactor) {  //was minLength
640                d = 7 * minLength * DPIScaleFactor;    //was minLength
641            }
642            //change due to outsized arrow in 6.0, 11-3-10
643            if (d > 140 * DPIScaleFactor) {
644                d = 140 * DPIScaleFactor;
645            }
646            //calculation points for the SEIZE arrowhead
647            //for SEIZE calculations
648            POINT2[] ptsArc2 = new POINT2[26];
649            lineutility.InitializePOINT2Array(ptsArc2);
650
651            E.x = 2 * pt1.x - pt0.x;
652            E.y = 2 * pt1.y - pt0.y;
653            ptsArc[0] = new POINT2(pLinePoints[1]);
654            ptsArc[1] = new POINT2(E);
655            if(converter != null)
656            {
657                ptsArc[0] = new POINT2(pLinePoints[0]);
658                ptsArc[1] = new POINT2(pLinePoints[1]);
659            }
660
661            lineutility.ArcArrayDouble(ptsArc, 0, dRadius, lineType, converter);
662            for (j = 0; j < 26; j++) {
663                ptsArc[j].style = 0;
664                pLinePoints[j] = new POINT2(ptsArc[j]);
665                pLinePoints[j].style = 0;
666            }
667            if (lineType != TacticalLines.OCCUPY) {
668                lineutility.GetArrowHead4Double(ptsArc[24], ptsArc[25], (int) d / 7, (int) d / 7, pArrowPoints, 0);
669            } else {
670                lineutility.GetArrowHead4Double(ptsArc[24], ptsArc[25], (int) d / 7, (int) (1.75 * d) / 7, pArrowPoints, 0);
671            }
672
673            pLinePoints[25].style = 5;
674
675            switch (lineType) {
676                case TacticalLines.CORDONKNOCK:
677                case TacticalLines.CORDONSEARCH:
678                case TacticalLines.ISOLATE:
679                    if (dRadius > 100) {
680                        dLength = 0.8 * dRadius;
681                    }
682                    for (j = 1; j <= 23; j++) {
683                        if (j % 3 == 0) {
684                            midPts[k].x = pt0.x - (long) ((dLength / dRadius) * (pt0.x - ptsArc[j].x));
685                            midPts[k].y = pt0.y - (long) ((dLength / dRadius) * (pt0.y - ptsArc[j].y));
686                            midPts[k].style = 0;
687                            trianglePts[l] = new POINT2(ptsArc[j - 1]);
688                            l++;
689                            trianglePts[l] = new POINT2(midPts[k]);
690                            l++;
691                            trianglePts[l] = new POINT2(ptsArc[j + 1]);
692                            trianglePts[l].style = 5;
693                            l++;
694                            k++;
695                        }
696                    }
697                    for (j = 26; j < 47; j++) {
698                        pLinePoints[j] = new POINT2(trianglePts[j - 26]);
699                    }
700                    pLinePoints[46].style = 5;
701                    for (j = 47; j < 50; j++) {
702                        pLinePoints[j] = new POINT2(pArrowPoints[j - 47]);
703                        pLinePoints[j].style = 0;
704                    }
705                    break;
706                case TacticalLines.AREA_DEFENSE:
707                    if (dRadius > 100) {
708                        dLength = 0.8 * dRadius;
709                    }
710                    for (j = 1; j <= 23; j++) {
711                        if (j % 3 == 0) {
712                            midPts[k].x = pt0.x - (long) ((dRadius / dLength) * (pt0.x - ptsArc[j].x));
713                            midPts[k].y = pt0.y - (long) ((dRadius / dLength) * (pt0.y - ptsArc[j].y));
714                            trianglePts[l] = new POINT2(ptsArc[j - 1]);
715                            trianglePts[l].style = 9;
716                            l++;
717                            trianglePts[l] = new POINT2(midPts[k]);
718                            trianglePts[l].style = 9;
719                            l++;
720                            trianglePts[l] = new POINT2(ptsArc[j + 1]);
721                            trianglePts[l].style = 9;
722                            l++;
723                            trianglePts[l] = new POINT2(ptsArc[j]);
724                            trianglePts[l].style = 9;
725                            l++;
726                            trianglePts[l] = new POINT2(ptsArc[j - 1]);
727                            trianglePts[l].style = 10;
728                            l++;
729                            k++;
730                        }
731                    }
732                    for (j = 26; j < 61; j++) {
733                        pLinePoints[j] = new POINT2(trianglePts[j - 26]);
734                    }
735                    for (j = 61; j < 64; j++) {
736                        pLinePoints[j] = new POINT2(pArrowPoints[j - 61]);
737                        pLinePoints[j].style = 0;
738                    }
739
740                    lineutility.GetArrowHead4Double(ptsArc[1], ptsArc[0], (int) d / 7, (int) d / 7, pArrowPoints, 0);
741                    pLinePoints[63].style = 5;
742                    for (j = 64; j < 67; j++) {
743                        pLinePoints[j] = new POINT2(pArrowPoints[j - 64]);
744                        pLinePoints[j].style = 0;
745                    }
746                    break;
747                case TacticalLines.OCCUPY:
748                    for (j = 26; j < 29; j++) {
749                        pLinePoints[j] = new POINT2(pArrowPoints[j - 26]);
750                    }
751
752                    pLinePoints[29] = lineutility.ExtendAlongLineDouble(pArrowPoints[0], pArrowPoints[1], lineutility.CalcDistanceDouble(pArrowPoints[0], pArrowPoints[1]) * 2);
753                    pLinePoints[30] = new POINT2(pArrowPoints[1]);
754                    pLinePoints[31] = lineutility.ExtendAlongLineDouble(pArrowPoints[2], pArrowPoints[1], lineutility.CalcDistanceDouble(pArrowPoints[2], pArrowPoints[1]) * 2);
755                    break;
756                case TacticalLines.SECURE:
757                    for (j = 26; j < 29; j++) {
758                        pLinePoints[j] = new POINT2(pArrowPoints[j - 26]);
759                        pLinePoints[j].style = 0;
760                    }
761                    pLinePoints[28].style = 5;
762                    break;
763
764                case TacticalLines.TURN_REVD:
765                case TacticalLines.TURN:
766                    boolean changeArc = IsTurnArcReversed(savepoints);
767                    if (changeArc) //swap the points
768                    {
769                        pt0.x = pt1.x;
770                        pt0.y = pt1.y;
771                        pt1.x = pt2.x;
772                        pt1.y = pt2.y;
773                    }
774
775                    ptsSeize[0] = new POINT2(pt0);
776                    ptsSeize[1] = new POINT2(pt1);
777
778                    dRadius = lineutility.CalcClockwiseCenterDouble(ptsSeize);
779
780                    C = new POINT2(ptsSeize[0]);
781                    E = new POINT2(ptsSeize[1]);
782                    ptsArc[0] = new POINT2(pt0);
783                    ptsArc[1] = new POINT2(E);
784                    lineutility.ArcArrayDouble(ptsArc, 0, dRadius, lineType, null);
785                    for (j = 0; j < 26; j++) {
786                        ptsArc[j].style = 0;
787                        pLinePoints[j] = new POINT2(ptsArc[j]);
788                        pLinePoints[j].style = 0;
789                    }
790
791                    if (changeArc) {
792                        lineutility.GetArrowHead4Double(ptsArc[1], pt0, (int) d / 7, (int) d / 7, pArrowPoints, 5);
793                    } else {
794                        lineutility.GetArrowHead4Double(ptsArc[24], pt1, (int) d / 7, (int) d / 7, pArrowPoints, 5);
795                    }
796
797                    pLinePoints[25].style = 5;
798
799                    for (j = 26; j < 29; j++) {
800                        pLinePoints[j] = new POINT2(pArrowPoints[j - 26]);
801                        pLinePoints[j].style = 9;
802                    }
803                    pLinePoints[28].style = 10;
804
805                    break;
806                case TacticalLines.RETAIN:
807                    for (j = 26; j < 29; j++) {
808                        pLinePoints[j] = new POINT2(pArrowPoints[j - 26]);
809                        pLinePoints[j].style = 0;
810                    }
811                    pLinePoints[28].style = 5;
812                    //get the extended points for retain
813                    k = 29;
814                    for (j = 1; j < 24; j++) {
815                        pLinePoints[k] = new POINT2(ptsArc[j]);
816                        pLinePoints[k].style = 0;
817                        k++;
818                        pLinePoints[k] = lineutility.ExtendLineDouble(pt0, ptsArc[j], (long) d / 7);
819                        pLinePoints[k].style = 5;
820                        k++;
821                    }
822
823                    break;
824                default:
825                    break;
826            }
827        } catch (Exception exc) {
828            ErrorLogger.LogException(_className, "GetIsolatePointsDouble",
829                    new RendererException("GetIsolatePointsDouble " + Integer.toString(lineType), exc));
830        }
831    }
832
833    private static void AirfieldCenterFeature(POINT2[] pLinePoints, int vblCounter) {
834        try {
835            double d = lineutility.MBRDistance(pLinePoints, vblCounter - 5);
836            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
837            if (d > 350 * DPIScaleFactor) {
838                d = 350 * DPIScaleFactor;
839            } else if (d < 100 * DPIScaleFactor) {
840                d = 100 * DPIScaleFactor;
841            }
842
843            for (int k = 0; k < vblCounter; k++) {
844                pLinePoints[k].style = 0;
845            }
846
847            pLinePoints[vblCounter - 5] = new POINT2(pLinePoints[0]);
848            pLinePoints[vblCounter - 5].style = 5;
849            pLinePoints[vblCounter - 4] = lineutility.CalcCenterPointDouble(pLinePoints, vblCounter - 6);
850            pLinePoints[vblCounter - 4].x -= d / 10;    //was 20
851            pLinePoints[vblCounter - 4].style = 0;
852            pLinePoints[vblCounter - 3] = new POINT2(pLinePoints[vblCounter - 4]);
853            pLinePoints[vblCounter - 3].x = pLinePoints[vblCounter - 4].x + d / 5;//was 10
854            pLinePoints[vblCounter - 3].style = 5;
855            pLinePoints[vblCounter - 2] = new POINT2(pLinePoints[vblCounter - 4]);
856            pLinePoints[vblCounter - 2].y += d / 20;//was 40
857            pLinePoints[vblCounter - 2].style = 0;
858            pLinePoints[vblCounter - 1] = new POINT2(pLinePoints[vblCounter - 3]);
859            pLinePoints[vblCounter - 1].y -= d / 20;//was 40
860            pLinePoints[vblCounter - 1].style = 0;
861        } catch (Exception exc) {
862            ErrorLogger.LogException(_className, "AirfieldCenterFeature",
863                    new RendererException("AirfieldCenterFeature", exc));
864        }
865    }
866
867    private static int GetATWallPointsDouble(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
868        int nCounter = 0;
869        try {
870            int lineType = tg.get_LineType();
871            int j = 0, k = 0;
872            int lCount = 0;
873            double dLengthSegment = 0, dIncrement = 0;
874            POINT2[] pSpikePoints = null;
875            POINT2 pt0;
876            double dRemainder = 0, dSpikeSize = 0;
877            int limit = 0;
878            POINT2 crossPt1, crossPt2;
879
880            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
881            pSpikePoints = new POINT2[lCount];
882            switch (lineType) {
883                case TacticalLines.CFG:
884                case TacticalLines.CFY:
885                    pSpikePoints[nCounter] = pLinePoints[0];
886                    pSpikePoints[nCounter].style = 0;
887                    nCounter++;
888                    break;
889                default:
890                    break;
891            }
892            for (j = 0; j < vblSaveCounter - 1; j++) {
893                dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
894                switch (lineType) {
895                    case TacticalLines.UCF:
896                    case TacticalLines.CF:
897                    case TacticalLines.CFG:
898                    case TacticalLines.CFY:
899                        dIncrement = arraysupport.getScaledSize(60, tg.get_LineThickness(), tg.get_patternScale());
900                        dSpikeSize = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
901                        dRemainder = dLengthSegment / dIncrement - (double) ((int) (dLengthSegment / dIncrement));
902                        if (dRemainder < 0.75) {
903                            limit = (int) (dLengthSegment / dIncrement);
904                        } else {
905                            limit = (int) (dLengthSegment / dIncrement) + 1;
906                        }
907                        break;
908                    default:
909                        dIncrement = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
910                        dSpikeSize = arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
911                        limit = (int) (dLengthSegment / dIncrement) - 1;
912                        break;
913                }
914                if (limit < 1) {
915                    pSpikePoints[nCounter] = pLinePoints[j];
916                    nCounter++;
917                    pSpikePoints[nCounter] = pLinePoints[j + 1];
918                    nCounter++;
919                    continue;
920                }
921
922                for (k = 0; k < limit; k++) {
923                    switch (lineType) {
924                        case TacticalLines.CFG: //linebreak for dot
925                            if (k > 0) {
926                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement + arraysupport.getScaledSize(45, tg.get_LineThickness(), tg.get_patternScale()), 0);
927                                nCounter++;
928                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement + arraysupport.getScaledSize(4, tg.get_LineThickness(), tg.get_patternScale()), 5);  //+2
929                                nCounter++;
930                                //dot
931                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(1, tg.get_LineThickness(), tg.get_patternScale()), 20);
932                                nCounter++;
933                                //remainder of line
934                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 0); //-4
935                            } else {
936                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(45, tg.get_LineThickness(), tg.get_patternScale()), 0);
937                            }
938                            break;
939                        case TacticalLines.CFY: //linebreak for crossed line
940                            if (k > 0) {
941                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement + arraysupport.getScaledSize(45, tg.get_LineThickness(), tg.get_patternScale()), 0);
942                                nCounter++;
943                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement + arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 5); //+2
944                                nCounter++;
945                                //dot
946                                //replace the dot with crossed line segment
947                                pSpikePoints[nCounter] = lineutility.ExtendAlongLineDouble(pSpikePoints[nCounter - 1], pLinePoints[j + 1], arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()), 0);
948                                nCounter++;
949                                pSpikePoints[nCounter] = lineutility.ExtendAlongLineDouble(pSpikePoints[nCounter - 1], pLinePoints[j + 1], arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 5);
950                                nCounter++;
951                                crossPt1 = lineutility.ExtendDirectedLine(pSpikePoints[nCounter - 2], pSpikePoints[nCounter - 1], pSpikePoints[nCounter - 1], 3, arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()), 0);
952                                crossPt2 = lineutility.ExtendDirectedLine(pSpikePoints[nCounter - 1], pSpikePoints[nCounter - 2], pSpikePoints[nCounter - 2], 2, arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()), 5);
953                                pSpikePoints[nCounter] = crossPt1;
954                                nCounter++;
955                                pSpikePoints[nCounter] = crossPt2;
956                                nCounter++;
957                                //remainder of line
958                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 0); //-4
959                            } else {
960                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(45, tg.get_LineThickness(), tg.get_patternScale()), 0);
961                            }
962                            break;
963                        default:
964                            pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), 0);
965                            break;
966                    }
967                    if (lineType == TacticalLines.CF) {
968                        pSpikePoints[nCounter].style = 0;
969                    }
970                    nCounter++;
971                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - dSpikeSize, 0);
972
973                    if (lineType == TacticalLines.CF
974                            || lineType == TacticalLines.CFG
975                            || lineType == TacticalLines.CFY) {
976                        pSpikePoints[nCounter].style = 9;
977                    }
978
979                    nCounter++;
980                    pt0 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], dSpikeSize / 2);
981
982                    //the spikes
983                    if (pLinePoints[j].x > pLinePoints[j + 1].x) //extend above the line
984                    {
985                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pSpikePoints[nCounter - 1], pt0, 2, dSpikeSize);
986                    }
987                    if (pLinePoints[j].x < pLinePoints[j + 1].x) //extend below the line
988                    {
989                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pSpikePoints[nCounter - 1], pt0, 3, dSpikeSize);
990                    }
991                    if (pLinePoints[j].x == pLinePoints[j + 1].x) {
992                        pSpikePoints[nCounter] = pt0;
993                        if (pLinePoints[j].y < pLinePoints[j + 1].y) //extend left of line
994                        {
995                            pSpikePoints[nCounter].x = pt0.x - dSpikeSize;
996                        } else //extend right of line
997                        {
998                            pSpikePoints[nCounter].x = pt0.x + dSpikeSize;
999                        }
1000                    }
1001                    nCounter++;
1002
1003                    if (lineType == TacticalLines.CF
1004                            || lineType == TacticalLines.CFG
1005                            || lineType == TacticalLines.CFY) {
1006                        pSpikePoints[nCounter - 1].style = 9;
1007                    }
1008
1009                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 2], dSpikeSize, 0);
1010                    //need an extra point for these
1011                    switch (lineType) {
1012                        case TacticalLines.CF:
1013                            pSpikePoints[nCounter].style = 10;
1014                            break;
1015                        case TacticalLines.CFG:
1016                        case TacticalLines.CFY:
1017                            pSpikePoints[nCounter].style = 10;
1018                            nCounter++;
1019                            pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 3], dSpikeSize, 0);
1020                            break;
1021                        default:
1022                            break;
1023                    }
1024                    nCounter++;
1025                }
1026
1027                //use the original line point for the segment end point
1028                pSpikePoints[nCounter] = pLinePoints[j + 1];
1029                pSpikePoints[nCounter].style = 0;
1030                nCounter++;
1031            }
1032
1033            for (j = 0; j < nCounter; j++) {
1034                pLinePoints[j] = pSpikePoints[j];
1035            }
1036            pLinePoints[nCounter - 1].style = 5;
1037
1038        } catch (Exception exc) {
1039            ErrorLogger.LogException(_className, "GetATWallPointsDouble",
1040                    new RendererException("GetATWallPointsDouble " + Integer.toString(tg.get_LineType()), exc));
1041        }
1042        return nCounter;
1043    }
1044
1045    private static int GetRidgePointsDouble(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
1046        int nCounter = 0;
1047        try {
1048            int j = 0, k = 0;
1049            int lCount = 0;
1050            double dLengthSegment = 0, dIncrement = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1051            ref<double[]> m = new ref();
1052            POINT2[] pSpikePoints = null;
1053            POINT2 pt0;
1054            double dSpikeSize = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1055            int limit = 0;
1056            double d = 0;
1057            int bolVertical = 0;
1058
1059            m.value = new double[1];
1060            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
1061
1062            pSpikePoints = new POINT2[lCount];
1063            lineutility.InitializePOINT2Array(pSpikePoints);
1064            //for(j=0;j<numPts2-1;j++)
1065            for (j = 0; j < vblSaveCounter - 1; j++) {
1066                bolVertical = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
1067                dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
1068                limit = (int) (dLengthSegment / dIncrement);
1069                if (limit < 1) {
1070                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j]);
1071                    nCounter++;
1072                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
1073                    nCounter++;
1074                    continue;
1075                }
1076                for (k = 0; k < limit; k++) {
1077                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement, 0);
1078                    nCounter++;
1079                    d = lineutility.CalcDistanceDouble(pLinePoints[j], pSpikePoints[nCounter - 1]);
1080                    pt0 = lineutility.ExtendLineDouble(pLinePoints[j + 1], pLinePoints[j], -d - dSpikeSize / 2);
1081
1082                    //the spikes
1083                    if (bolVertical != 0) //segment is not vertical
1084                    {
1085                        if (pLinePoints[j].x < pLinePoints[j + 1].x) //extend above the line
1086                        {
1087                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 2, dSpikeSize);
1088                        } else //extend below the line
1089                        {
1090                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 3, dSpikeSize);
1091                        }
1092                    } else //segment is vertical
1093                    {
1094                        if (pLinePoints[j + 1].y < pLinePoints[j].y) //extend left of the line
1095                        {
1096                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 0, dSpikeSize);
1097                        } else //extend right of the line
1098                        {
1099                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 1, dSpikeSize);
1100                        }
1101                    }
1102                    nCounter++;
1103                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -d - dSpikeSize, 0);
1104                    nCounter++;
1105                }
1106                pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
1107                nCounter++;
1108            }
1109
1110            for (j = 0; j < nCounter; j++) {
1111                pLinePoints[j] = new POINT2(pSpikePoints[j]);
1112            }
1113            for (j = nCounter; j < lCount; j++) {
1114                pLinePoints[j] = new POINT2(pSpikePoints[nCounter - 1]);
1115            }
1116
1117        } catch (Exception exc) {
1118            ErrorLogger.LogException(_className, "GetRidgePointsDouble",
1119                    new RendererException("GetRidgePointsDouble " + Integer.toString(tg.get_LineType()), exc));
1120        }
1121        return nCounter;
1122    }
1123
1124    protected static int GetSquallDouble(POINT2[] pLinePoints,
1125            double amplitude,
1126            int quantity,
1127            double length,
1128            int numPoints) {
1129        int counter = 0;
1130        try {
1131            int j = 0, k = 0;
1132            POINT2 StartSegPt, EndSegPt;
1133            POINT2 savePoint1 = new POINT2(pLinePoints[0]);
1134            POINT2 savePoint2 = new POINT2(pLinePoints[numPoints - 1]);
1135            ref<int[]> sign = new ref();
1136            int segQty = 0;
1137            int totalQty = countsupport.GetSquallQty(pLinePoints, quantity, length, numPoints);
1138            POINT2[] pSquallPts = new POINT2[totalQty];
1139            POINT2[] pSquallSegPts = null;
1140
1141            lineutility.InitializePOINT2Array(pSquallPts);
1142            sign.value = new int[1];
1143            sign.value[0] = -1;
1144            if (totalQty == 0) {
1145                return 0;
1146            }
1147
1148            for (j = 0; j < numPoints - 1; j++) {
1149                StartSegPt = new POINT2(pLinePoints[j]);
1150                EndSegPt = new POINT2(pLinePoints[j + 1]);
1151                segQty = countsupport.GetSquallSegQty(StartSegPt, EndSegPt, quantity, length);
1152                if (segQty > 0) {
1153                    pSquallSegPts = new POINT2[segQty];
1154                    lineutility.InitializePOINT2Array(pSquallSegPts);
1155                } else {
1156                    pSquallPts[counter].x = StartSegPt.x;
1157                    pSquallPts[counter++].y = StartSegPt.y;
1158                    pSquallPts[counter].x = EndSegPt.x;
1159                    pSquallPts[counter++].y = EndSegPt.y;
1160                    continue;
1161                }
1162                sign.value[0] = -1;
1163                lineutility.GetSquallSegment(StartSegPt, EndSegPt, pSquallSegPts, sign, amplitude, quantity, length);
1164                for (k = 0; k < segQty; k++) {
1165                    pSquallPts[counter].x = pSquallSegPts[k].x;
1166                    pSquallPts[counter].y = pSquallSegPts[k].y;
1167                    if (k == 0) {
1168                        pSquallPts[counter] = new POINT2(pLinePoints[j]);
1169                    }
1170                    if (k == segQty - 1) {
1171                        pSquallPts[counter] = new POINT2(pLinePoints[j + 1]);
1172                    }
1173                    pSquallPts[counter].style = 0;
1174                    counter++;
1175                }
1176            }
1177            //load the squall points into the linepoints array
1178            for (j = 0; j < counter; j++) {
1179                if (j < totalQty) {
1180                    pLinePoints[j].x = pSquallPts[j].x;
1181                    pLinePoints[j].y = pSquallPts[j].y;
1182                    if (j == 0) {
1183                        pLinePoints[j] = new POINT2(savePoint1);
1184                    }
1185                    if (j == counter - 1) {
1186                        pLinePoints[j] = new POINT2(savePoint2);
1187                    }
1188                    pLinePoints[j].style = pSquallPts[j].style;
1189                }
1190            }
1191            if (counter == 0) {
1192                for (j = 0; j < pLinePoints.length; j++) {
1193                    if (j == 0) {
1194                        pLinePoints[j] = new POINT2(savePoint1);
1195                    } else {
1196                        pLinePoints[j] = new POINT2(savePoint2);
1197                    }
1198                }
1199                counter = pLinePoints.length;
1200            }
1201        } catch (Exception exc) {
1202            ErrorLogger.LogException(_className, "GetSquallDouble",
1203                    new RendererException("GetSquallDouble", exc));
1204        }
1205        return counter;
1206    }
1207
1208    protected static int GetSevereSquall(POINT2[] pLinePoints,
1209            double length,
1210            int numPoints) {
1211        int l = 0;
1212        try {
1213            int quantity = 5, j = 0, k = 0;
1214            int totalQty = countsupport.GetSquallQty(pLinePoints, quantity, length, numPoints) + 2 * numPoints;
1215            POINT2[] squallPts = new POINT2[totalQty];
1216            POINT2 pt0 = new POINT2(), pt1 = new POINT2(), pt2 = new POINT2(),
1217                    pt3 = new POINT2(), pt4 = new POINT2(), pt5 = new POINT2(), pt6 = new POINT2(),
1218                    pt7 = new POINT2(), pt8 = new POINT2();
1219            int segQty = 0;
1220            double dist = 0;
1221
1222            lineutility.InitializePOINT2Array(squallPts);
1223            //each segment looks like this: --- V
1224            for (j = 0; j < numPoints - 1; j++) {
1225                dist = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
1226                segQty = (int) (dist / length);
1227                for (k = 0; k < segQty; k++) {
1228                    pt0 = lineutility.ExtendAlongLineDouble2(pLinePoints[j], pLinePoints[j + 1], k * length);
1229                    pt1 = lineutility.ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * length + length / 6 * 4);
1230                    pt1.style = 5;
1231                    squallPts[l++] = new POINT2(pt0);
1232                    squallPts[l++] = new POINT2(pt1);
1233                    pt5 = lineutility.ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * length + length / 6 * 5);
1234                    pt6 = lineutility.ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * length + length);
1235                    pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 2, length / 6, 0);   //extend above line
1236                    pt3 = lineutility.ExtendDirectedLine(pt0, pt5, pt5, 3, length / 6, 0);   //extend below line
1237                    pt4 = lineutility.ExtendDirectedLine(pt0, pt6, pt6, 2, length / 6, 5);   //extend above line
1238                    pt4.style = 5;
1239                    squallPts[l++] = new POINT2(pt2);
1240                    squallPts[l++] = new POINT2(pt3);
1241                    squallPts[l++] = new POINT2(pt4);
1242                }
1243                //segment remainder
1244                squallPts[l++] = new POINT2(pLinePoints[j + 1]);
1245                pt0 = lineutility.ExtendAlongLineDouble(pLinePoints[j + 1], pLinePoints[j], dist - segQty * length);
1246                pt0.style = 5;
1247                squallPts[l++] = new POINT2(pt0);
1248            }
1249            if (l > pLinePoints.length) {
1250                l = pLinePoints.length;
1251            }
1252
1253            for (j = 0; j < l; j++) {
1254                if (j < totalQty) {
1255                    pLinePoints[j] = new POINT2(squallPts[j]);
1256                } else {
1257                    break;
1258                }
1259            }
1260
1261        } catch (Exception exc) {
1262            ErrorLogger.LogException(_className, "GetSevereSquall",
1263                    new RendererException("GetSevereSquall", exc));
1264        }
1265        return l;
1266    }
1267
1268    private static int GetConvergencePointsDouble(POINT2[] pLinePoints, double length, int vblCounter) {
1269        int counter = vblCounter;
1270        try {
1271            int j = 0, k = 0;
1272            double d = 0;
1273            POINT2 pt0 = new POINT2(), pt1 = new POINT2();
1274            POINT2[] tempPts = new POINT2[vblCounter];
1275            POINT2 tempPt = new POINT2();
1276            int numJags = 0;
1277            //save the original points
1278            for (j = 0; j < vblCounter; j++) {
1279                tempPts[j] = new POINT2(pLinePoints[j]);
1280            }
1281
1282            //result points begin with the original points,
1283            //set the last one's linestyle to 5;
1284            pLinePoints[vblCounter - 1].style = 5;
1285            for (j = 0; j < vblCounter - 1; j++) {
1286
1287                pt0 = new POINT2(tempPts[j]);
1288                pt1 = new POINT2(tempPts[j + 1]);
1289                d = lineutility.CalcDistanceDouble(pt0, pt1);
1290                numJags = (int) (d / length);
1291                //we don't want too small a remainder
1292                if (d - numJags * length < 5) {
1293                    numJags -= 1;
1294                }
1295
1296                //each section has two spikes: one points above the line
1297                //the other spike points below the line
1298                for (k = 0; k < numJags; k++) {
1299                    //the first spike
1300                    tempPt = lineutility.ExtendAlongLineDouble(pt0, pt1, k * length + length / 2, 0);
1301                    pLinePoints[counter++] = new POINT2(tempPt);
1302                    tempPt = lineutility.ExtendAlongLineDouble(tempPt, pt1, length / 2);
1303                    tempPt = lineutility.ExtendDirectedLine(pt0, tempPt, tempPt, 2, length / 2, 5);
1304                    pLinePoints[counter++] = new POINT2(tempPt);
1305                    //the 2nd spike
1306                    tempPt = lineutility.ExtendAlongLineDouble(pt0, pt1, (k + 1) * length, 0);
1307                    pLinePoints[counter++] = new POINT2(tempPt);
1308                    tempPt = lineutility.ExtendAlongLineDouble(tempPt, pt1, length / 2);
1309                    tempPt = lineutility.ExtendDirectedLine(pt0, tempPt, tempPt, 3, length / 2, 5);
1310                    pLinePoints[counter++] = new POINT2(tempPt);
1311                }
1312            }
1313        } catch (Exception exc) {
1314            ErrorLogger.LogException(_className, "GetConvergencePointsDouble",
1315                    new RendererException("GetConvergencePointsDouble", exc));
1316        }
1317        return counter;
1318    }
1319
1320    // Dashes are 2/3*length and spaces are 1/3*length.
1321    private static int GetITDPointsDouble(POINT2[] pLinePoints, double length, int vblCounter) {
1322        int counter = 0;
1323        try {
1324            int j = 0, k = 0;
1325            double d = 0;
1326            POINT2 pt0 = new POINT2(), pt1 = new POINT2();
1327            POINT2[] tempPts = new POINT2[vblCounter];
1328            POINT2 tempPt = new POINT2();
1329            int numJags = 0, lineStyle = 19;
1330            //save the original points
1331            for (j = 0; j < vblCounter; j++) {
1332                tempPts[j] = new POINT2(pLinePoints[j]);
1333            }
1334
1335            //result points begin with the original points,
1336            //set the last one's linestyle to 5;
1337            //pLinePoints[vblCounter-1].style=5;
1338            for (j = 0; j < vblCounter - 1; j++) {
1339                pt0 = new POINT2(tempPts[j]);
1340                pt1 = new POINT2(tempPts[j + 1]);
1341                d = lineutility.CalcDistanceDouble(pt0, pt1);
1342                numJags = (int) (d / length);
1343                //we don't want too small a remainder
1344                if (d - numJags * length / 3 * 2 < length / 3) {
1345                    numJags -= 1;
1346                }
1347                if (numJags == 0) {
1348                    pt0.style = 19;
1349                    pLinePoints[counter++] = new POINT2(pt0);
1350                    pt1.style = 5;
1351                    pLinePoints[counter++] = new POINT2(pt1);
1352                }
1353
1354                for (k = 0; k < numJags; k++) {
1355                    tempPt = lineutility.ExtendAlongLineDouble(pt0, pt1, k * length + length / 3, lineStyle);
1356                    pLinePoints[counter++] = new POINT2(tempPt);
1357
1358                    if (k < numJags - 1) {
1359                        tempPt = lineutility.ExtendAlongLineDouble(tempPt, pt1, length * 2 / 3, 5);
1360                    } else {
1361                        tempPt = new POINT2(tempPts[j + 1]);
1362                        tempPt.style = 5;
1363                    }
1364                    pLinePoints[counter++] = new POINT2(tempPt);
1365                    if (lineStyle == 19) {
1366                        lineStyle = 25;
1367                    } else {
1368                        lineStyle = 19;
1369                    }
1370                }
1371            }
1372        } catch (Exception exc) {
1373            ErrorLogger.LogException(_className, "GetITDPointsDouble",
1374                    new RendererException("GetITDPointsDouble", exc));
1375        }
1376        return counter;
1377    }
1378
1379    private static int GetXPoints(POINT2[] pOriginalLinePoints, POINT2[] XPoints, double segmentLength, int vblCounter) {
1380        int xCounter = 0;
1381        try {
1382            int j = 0, k = 0;
1383            double d = 0;
1384            POINT2 pt0, pt1, pt2, pt3 = new POINT2(), pt4 = new POINT2(), pt5 = new POINT2(), pt6 = new POINT2();
1385            int numThisSegment = 0;
1386            double distInterval = 0;
1387            double xSize = segmentLength / 6;
1388            for (j = 0; j < vblCounter - 1; j++) {
1389                d = lineutility.CalcDistanceDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1390                numThisSegment = (int) ((d - segmentLength) / segmentLength);
1391
1392                //added 4-19-12
1393                distInterval = d / numThisSegment;
1394                for (k = 0; k < numThisSegment; k++) {
1395                    //pt0=lineutility.ExtendAlongLineDouble(pOriginalLinePoints[j],pOriginalLinePoints[j+1], 10+20*k);
1396                    pt0 = lineutility.ExtendAlongLineDouble2(pOriginalLinePoints[j], pOriginalLinePoints[j + 1], distInterval / 2 + distInterval * k);
1397                    pt1 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalLinePoints[j + 1], xSize);
1398                    pt2 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalLinePoints[j + 1], -xSize);
1399
1400                    pt3 = lineutility.ExtendDirectedLine(pOriginalLinePoints[j], pt1, pt1, 2, xSize);
1401                    pt4 = lineutility.ExtendDirectedLine(pOriginalLinePoints[j], pt1, pt1, 3, xSize);
1402                    pt4.style = 5;
1403                    pt5 = lineutility.ExtendDirectedLine(pOriginalLinePoints[j], pt2, pt2, 2, xSize);
1404                    pt6 = lineutility.ExtendDirectedLine(pOriginalLinePoints[j], pt2, pt2, 3, xSize);
1405                    pt6.style = 5;
1406                    XPoints[xCounter++] = new POINT2(pt3);
1407                    XPoints[xCounter++] = new POINT2(pt6);
1408                    XPoints[xCounter++] = new POINT2(pt5);
1409                    XPoints[xCounter++] = new POINT2(pt4);
1410                }
1411            }
1412        } catch (Exception exc) {
1413            ErrorLogger.LogException(_className, "GetXPointsDouble",
1414                    new RendererException("GetXPointsDouble", exc));
1415        }
1416        return xCounter;
1417    }
1418
1419    /**
1420     * returns a 37 point ellipse
1421     *
1422     * @param ptCenter
1423     * @param ptWidth
1424     * @param ptHeight
1425     * @return
1426     */
1427    private static POINT2[] getEllipsePoints(POINT2 ptCenter, POINT2 ptWidth, POINT2 ptHeight) {
1428        POINT2[] pEllipsePoints = null;
1429        try {
1430            pEllipsePoints = new POINT2[37];
1431            int l = 0;
1432            double dFactor = 0;
1433            double a = lineutility.CalcDistanceDouble(ptCenter, ptWidth);
1434            double b = lineutility.CalcDistanceDouble(ptCenter, ptHeight);
1435            lineutility.InitializePOINT2Array(pEllipsePoints);
1436            for (l = 1; l < 37; l++) {
1437                dFactor = (10.0 * l) * Math.PI / 180.0;
1438                pEllipsePoints[l - 1].x = ptCenter.x + (int) (a * Math.cos(dFactor));
1439                pEllipsePoints[l - 1].y = ptCenter.y + (int) (b * Math.sin(dFactor));
1440                pEllipsePoints[l - 1].style = 0;
1441            }
1442            pEllipsePoints[36] = new POINT2(pEllipsePoints[0]);
1443        } catch (Exception exc) {
1444            ErrorLogger.LogException(_className, "GetEllipsePoints",
1445                    new RendererException("GetEllipsePoints", exc));
1446        }
1447        return pEllipsePoints;
1448    }
1449
1450    /**
1451     * Calculate an ellipse and rotate about it's center by azimuth in degrees
1452     *
1453     * @param ptCenter
1454     * @param ptWidth
1455     * @param ptHeight
1456     * @param azimuth
1457     * @return
1458     */
1459    private static POINT2[] getRotatedEllipsePoints(POINT2 ptCenter, POINT2 ptWidth, POINT2 ptHeight, double azimuth, int lineType) {
1460        POINT2[] pResultPoints = null;
1461        try {
1462            POINT2[] pEllipsePoints = new POINT2[36];
1463            int l = 0, j = 0;
1464            double dFactor = 0;
1465            double a = lineutility.CalcDistanceDouble(ptCenter, ptWidth);
1466            double b = lineutility.CalcDistanceDouble(ptCenter, ptHeight);
1467            lineutility.InitializePOINT2Array(pEllipsePoints);
1468            for (l = 1; l < 37; l++) {
1469                dFactor = (10.0 * l) * Math.PI / 180.0;
1470                //pEllipsePoints[l - 1].x = ptCenter.x + (int) (a * Math.cos(dFactor));
1471                //pEllipsePoints[l - 1].y = ptCenter.y + (int) (b * Math.sin(dFactor));
1472                pEllipsePoints[l - 1].x = ptCenter.x + a * Math.cos(dFactor);
1473                pEllipsePoints[l - 1].y = ptCenter.y + b * Math.sin(dFactor);
1474                pEllipsePoints[l - 1].style = 0;
1475            }
1476            lineutility.RotateGeometryDouble(pEllipsePoints, 36, azimuth - 90);
1477            pResultPoints = new POINT2[37];
1478            for (j = 0; j < 36; j++) {
1479                pResultPoints[j] = pEllipsePoints[j];
1480            }
1481            pResultPoints[36] = pEllipsePoints[0];
1482        } catch (Exception exc) {
1483            ErrorLogger.LogException(_className, "GetRotatedEllipsePoints",
1484                    new RendererException("GetRotatedEllipsePoints", exc));
1485        }
1486        return pResultPoints;
1487    }
1488
1489    private static int GetLVOPoints(POINT2[] pOriginalLinePoints, POINT2[] pLinePoints, double ovalWidth, double segmentLength, int vblCounter) {
1490        int lEllipseCounter = 0;
1491        try {
1492            double dAngle = 0, d = 0, ovalLength = ovalWidth * 2, dFactor = 0;
1493            int lHowManyThisSegment = 0, j = 0, k = 0, l = 0, t = 0;
1494            POINT2 ptCenter = new POINT2();
1495            POINT2[] pEllipsePoints2 = new POINT2[37];
1496
1497            double distInterval = 0;
1498            //end declarations
1499            for (j = 0; j < vblCounter - 1; j++) {
1500                lineutility.InitializePOINT2Array(pEllipsePoints2);
1501                d = lineutility.CalcDistanceDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1502                lHowManyThisSegment = (int) ((d - segmentLength) / segmentLength);
1503
1504                distInterval = d / lHowManyThisSegment;
1505
1506                dAngle = lineutility.CalcSegmentAngleDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1507                dAngle = dAngle + Math.PI / 2;
1508                for (k = 0; k < lHowManyThisSegment; k++) {
1509                    ptCenter = lineutility.ExtendAlongLineDouble2(pOriginalLinePoints[j], pOriginalLinePoints[j + 1], k * distInterval);
1510                    for (l = 1; l < 37; l++) {
1511                        //dFactor = (10.0 * l) * Math.PI / 180.0;
1512                        dFactor = (20.0 * l) * Math.PI / 180.0;
1513                        pEllipsePoints2[l - 1].x = ptCenter.x + (int) (ovalWidth * Math.cos(dFactor));
1514                        pEllipsePoints2[l - 1].y = ptCenter.y + (int) (ovalLength * Math.sin(dFactor));
1515                        pEllipsePoints2[l - 1].style = 0;
1516                    }
1517                    lineutility.RotateGeometryDouble(pEllipsePoints2, 36, (int) (dAngle * 180 / Math.PI));
1518                    pEllipsePoints2[36] = new POINT2(pEllipsePoints2[35]);
1519                    pEllipsePoints2[36].style = 5;
1520                    for (l = 0; l < 37; l++) {
1521                        pLinePoints[lEllipseCounter] = new POINT2(pEllipsePoints2[l]);
1522                        lEllipseCounter++;
1523                    }
1524                }//end k loop
1525                //extra ellipse on the final segment at the end of the line
1526                if (j == vblCounter - 2) {
1527                    ptCenter = pOriginalLinePoints[j + 1];
1528
1529                    for (l = 1; l < 37; l++) {
1530                        dFactor = (20.0 * l) * Math.PI / 180.0;
1531                        pEllipsePoints2[l - 1].x = ptCenter.x + (int) (ovalWidth * Math.cos(dFactor));
1532                        pEllipsePoints2[l - 1].y = ptCenter.y + (int) (ovalLength * Math.sin(dFactor));
1533                        pEllipsePoints2[l - 1].style = 0;
1534                    }
1535                    lineutility.RotateGeometryDouble(pEllipsePoints2, 36, (int) (dAngle * 180 / Math.PI));
1536                    pEllipsePoints2[36] = new POINT2(pEllipsePoints2[35]);
1537                    pEllipsePoints2[36].style = 5;
1538                    for (l = 0; l < 37; l++) {
1539                        pLinePoints[lEllipseCounter] = new POINT2(pEllipsePoints2[l]);
1540                        lEllipseCounter++;
1541                    }
1542                }
1543            }
1544        } catch (Exception exc) {
1545            ErrorLogger.LogException(_className, "GetLVOPointsDouble",
1546                    new RendererException("GetLVOPointsDouble", exc));
1547        }
1548        return lEllipseCounter;
1549    }
1550
1551    private static int GetIcingPointsDouble(POINT2[] pLinePoints, double length, int vblCounter) {
1552        int counter = 0;
1553        try {
1554            int j = 0;
1555            POINT2[] origPoints = new POINT2[vblCounter];
1556            int nDirection = -1;
1557            int k = 0, numSegments = 0;
1558            POINT2 pt0 = new POINT2(), pt1 = new POINT2(), midPt = new POINT2(), pt2 = new POINT2();
1559            //save the original points
1560            for (j = 0; j < vblCounter; j++) {
1561                origPoints[j] = new POINT2(pLinePoints[j]);
1562            }
1563            double distInterval = 0;
1564            for (j = 0; j < vblCounter - 1; j++) {
1565                //how many segments for this line segment?
1566                numSegments = (int) lineutility.CalcDistanceDouble(origPoints[j], origPoints[j + 1]);
1567                numSegments /= length;
1568                //4-19-12
1569                distInterval = lineutility.CalcDistanceDouble(origPoints[j], origPoints[j + 1]) / numSegments;
1570                //get the direction and the quadrant
1571                nDirection = GetInsideOutsideDouble2(origPoints[j], origPoints[j + 1], origPoints, vblCounter, j, TacticalLines.ICING);
1572                for (k = 0; k < numSegments; k++) {
1573                    //get the parallel segment
1574                    if (k == 0) {
1575                        pt0 = new POINT2(origPoints[j]);
1576                    } else {
1577                        pt0 = lineutility.ExtendAlongLineDouble(origPoints[j], origPoints[j + 1], k * distInterval, 0);
1578                    }
1579
1580                    pt1 = lineutility.ExtendAlongLineDouble(origPoints[j], origPoints[j + 1], k * distInterval + length * 2 / 3, 5);
1581                    midPt = lineutility.ExtendAlongLineDouble(origPoints[j], origPoints[j + 1], k * distInterval + length / 3, 0);
1582                    //get the perpendicular segment
1583                    pt2 = lineutility.ExtendDirectedLine(origPoints[j], origPoints[j + 1], midPt, nDirection, length / 3, 5);
1584                    pLinePoints[counter] = new POINT2(pt0);
1585                    pLinePoints[counter + 1] = new POINT2(pt1);
1586                    pLinePoints[counter + 2] = new POINT2(midPt);
1587                    pLinePoints[counter + 3] = new POINT2(pt2);
1588                    counter += 4;
1589                }
1590            }
1591        } catch (Exception exc) {
1592            ErrorLogger.LogException(_className, "GetIcingPointsDouble",
1593                    new RendererException("GetIcingPointsDouble", exc));
1594        }
1595        return counter;
1596    }
1597
1598    protected static int GetAnchorageDouble(POINT2[] vbPoints2, double floatDiameter, int numPts) {
1599        int lFlotCounter = 0;
1600        try {
1601            int j = 0, k = 0, l = 0;
1602            int x1 = 0, y1 = 0;
1603            int numSegPts = -1;
1604            int lFlotCount = 0;
1605            int lNumSegs = 0;
1606            double dDistance = 0;
1607            int[] vbPoints = null;
1608            int[] points = null;
1609            int[] points2 = null;
1610            POINT2 pt = new POINT2();
1611            POINT2 pt1 = new POINT2(), pt2 = new POINT2();
1612
1613            lFlotCount = flot.GetAnchorageCountDouble(vbPoints2, floatDiameter, numPts);
1614            vbPoints = new int[2 * numPts];
1615
1616            for (j = 0; j < numPts; j++) {
1617                vbPoints[k] = (int) vbPoints2[j].x;
1618                k++;
1619                vbPoints[k] = (int) vbPoints2[j].y;
1620                k++;
1621            }
1622            k = 0;
1623
1624            ref<int[]> bFlip = new ref();
1625            bFlip.value = new int[1];
1626            ref<int[]> lDirection = new ref();
1627            lDirection.value = new int[1];
1628            ref<int[]> lLastDirection = new ref();
1629            lLastDirection.value = new int[1];
1630            for (l = 0; l < numPts - 1; l++) {
1631                pt1.x = vbPoints[2 * l];
1632                pt1.y = vbPoints[2 * l + 1];
1633                pt2.x = vbPoints[2 * l + 2];
1634                pt2.y = vbPoints[2 * l + 3];
1635                //for all segments after the first segment we shorten
1636                //the line by floatDiameter so the flots will not abut
1637                if (l > 0) {
1638                    pt1 = lineutility.ExtendAlongLineDouble(pt1, pt2, floatDiameter);
1639                }
1640
1641                dDistance = lineutility.CalcDistanceDouble(pt1, pt2);
1642
1643                lNumSegs = (int) (dDistance / floatDiameter);
1644
1645                if (lNumSegs > 0) {
1646                    points2 = new int[lNumSegs * 32];
1647                    numSegPts = flot.GetAnchorageFlotSegment(vbPoints, (int) pt1.x, (int) pt1.y, (int) pt2.x, (int) pt2.y, l, floatDiameter, points2, bFlip, lDirection, lLastDirection);
1648                    points = new int[numSegPts];
1649
1650                    for (j = 0; j < numSegPts; j++) {
1651                        points[j] = points2[j];
1652                    }
1653
1654                    for (j = 0; j < numSegPts / 3; j++) //only using half the flots
1655                    {
1656                        x1 = points[k];
1657                        y1 = points[k + 1];
1658                        k += 3;
1659                        if (j % 10 == 0) {
1660                            pt.x = x1;
1661                            pt.y = y1;
1662                            pt.style = 5;
1663                        } else if ((j + 1) % 10 == 0) {
1664                            if (lFlotCounter < lFlotCount) {
1665                                vbPoints2[lFlotCounter].x = x1;
1666                                vbPoints2[lFlotCounter++].y = y1;
1667                                vbPoints2[lFlotCounter++] = new POINT2(pt);
1668                                continue;
1669                            } else {
1670                                break;
1671                            }
1672                        }
1673                        if (lFlotCounter < lFlotCount) {
1674                            vbPoints2[lFlotCounter].x = x1;
1675                            vbPoints2[lFlotCounter].y = y1;
1676                            lFlotCounter++;
1677                        } else {
1678                            break;
1679                        }
1680                    }
1681                    k = 0;
1682                    points = null;
1683                } else {
1684                    if (lFlotCounter < lFlotCount) {
1685                        vbPoints2[lFlotCounter].x = vbPoints[2 * l];
1686                        vbPoints2[lFlotCounter].y = vbPoints[2 * l + 1];
1687                        lFlotCounter++;
1688                    }
1689                }
1690            }
1691            for (j = lFlotCounter - 1; j < lFlotCount; j++) {
1692                vbPoints2[j].style = 5;
1693            }
1694
1695        } catch (Exception exc) {
1696            ErrorLogger.LogException(_className, "GetAnchorageDouble",
1697                    new RendererException("GetAnchorageDouble", exc));
1698        }
1699        return lFlotCounter;
1700    }
1701
1702    private static int GetPipePoints(POINT2[] pLinePoints,
1703            double length,
1704            int vblCounter) {
1705        int counter = 0;
1706        try {
1707            POINT2[] pOriginalPoints = new POINT2[vblCounter];
1708            POINT2 pt0 = new POINT2();
1709            POINT2 pt1 = new POINT2();
1710            POINT2 pt2 = new POINT2();
1711            POINT2[] xPoints = new POINT2[pLinePoints.length];
1712            int xCounter = 0;
1713            int j = 0, k = 0;
1714            for (j = 0; j < vblCounter; j++) {
1715                pOriginalPoints[j] = new POINT2(pLinePoints[j]);
1716            }
1717            int numSegs = 0;
1718            double d = 0;
1719
1720            lineutility.InitializePOINT2Array(xPoints);
1721            for (j = 0; j < vblCounter - 1; j++) {
1722                d = lineutility.CalcDistanceDouble(pOriginalPoints[j], pOriginalPoints[j + 1]);
1723                numSegs = (int) (d / length);
1724                for (k = 0; k < numSegs; k++) {
1725                    pt0 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k);
1726                    pt0.style = 0;
1727                    pt1 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k + length / 2);
1728                    pt1.style = 5;
1729                    pt2 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k + length / 2);
1730                    pt2.style = 20;     //for filled circle
1731                    pLinePoints[counter++] = new POINT2(pt0);
1732                    pLinePoints[counter++] = new POINT2(pt1);
1733                    xPoints[xCounter++] = new POINT2(pt2);
1734                }
1735                if (numSegs == 0) {
1736                    pLinePoints[counter] = new POINT2(pOriginalPoints[j]);
1737                    pLinePoints[counter++].style = 0;
1738                    pLinePoints[counter] = new POINT2(pOriginalPoints[j + 1]);
1739                    pLinePoints[counter++].style = 5;
1740                } else {
1741                    pLinePoints[counter] = new POINT2(pLinePoints[counter - 1]);
1742                    pLinePoints[counter++].style = 0;
1743                    pLinePoints[counter] = new POINT2(pOriginalPoints[j + 1]);
1744                    pLinePoints[counter++].style = 5;
1745                }
1746            }
1747            //load the circle points
1748            for (k = 0; k < xCounter; k++) {
1749                pLinePoints[counter++] = new POINT2(xPoints[k]);
1750            }
1751            //add one more circle
1752            pLinePoints[counter++] = new POINT2(pLinePoints[counter]);
1753
1754            pOriginalPoints = null;
1755            xPoints = null;
1756        } catch (Exception exc) {
1757            ErrorLogger.LogException(_className, "GetPipePoints",
1758                    new RendererException("GetPipePoints", exc));
1759        }
1760        return counter;
1761    }
1762
1763    private static int GetReefPoints(POINT2[] pLinePoints,
1764            double length,
1765            int vblCounter) {
1766        int counter = 0;
1767        try {
1768            POINT2[] pOriginalPoints = new POINT2[vblCounter];
1769            POINT2 pt0 = new POINT2();
1770            POINT2 pt1 = new POINT2();
1771            POINT2 pt2 = new POINT2();
1772            POINT2 pt3 = new POINT2();
1773            POINT2 pt4 = new POINT2();
1774            //POINT2 pt5=new POINT2();
1775            for (int j = 0; j < vblCounter; j++) {
1776                pOriginalPoints[j] = new POINT2(pLinePoints[j]);
1777            }
1778
1779            int numSegs = 0, direction = 0;
1780            double d = 0;
1781            for (int j = 0; j < vblCounter - 1; j++) {
1782                if (pOriginalPoints[j].x < pOriginalPoints[j + 1].x) {
1783                    direction = 2;
1784                } else {
1785                    direction = 3;
1786                }
1787
1788                d = lineutility.CalcDistanceDouble(pOriginalPoints[j], pOriginalPoints[j + 1]);
1789                numSegs = (int) (d / length);
1790                for (int k = 0; k < numSegs; k++) {
1791                    pt0 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k);
1792
1793                    pt1 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalPoints[j + 1], length * .35);
1794                    pt1 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt1, direction, length);//was 2
1795
1796                    pt2 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalPoints[j + 1], length * .4);
1797                    pt2 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt2, direction, length * .6);//was 2
1798
1799                    pt3 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalPoints[j + 1], length * .75);
1800                    pt3 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt3, direction, length * 1.35);//was 2
1801
1802                    pt4 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * (k + 1));
1803                    pLinePoints[counter++] = new POINT2(pt0);
1804                    pLinePoints[counter++] = new POINT2(pt1);
1805                    pLinePoints[counter++] = new POINT2(pt2);
1806                    pLinePoints[counter++] = new POINT2(pt3);
1807                    pLinePoints[counter++] = new POINT2(pt4);
1808                }
1809                if (numSegs == 0) {
1810                    pLinePoints[counter++] = new POINT2(pOriginalPoints[j]);
1811                    pLinePoints[counter++] = new POINT2(pOriginalPoints[j + 1]);
1812                }
1813            }
1814            pLinePoints[counter++] = new POINT2(pOriginalPoints[vblCounter - 1]);
1815            pOriginalPoints = null;
1816        } catch (Exception exc) {
1817            ErrorLogger.LogException(_className, "GetReefPoints",
1818                    new RendererException("GetReefPoints", exc));
1819        }
1820        return counter;
1821    }
1822
1823    private static int GetRestrictedAreaPoints(POINT2[] pLinePoints,
1824            double length,
1825            int vblCounter) {
1826        int counter = 0;
1827        try {
1828            POINT2[] pOriginalPoints = new POINT2[vblCounter];
1829            POINT2 pt0 = new POINT2();
1830            POINT2 pt1 = new POINT2();
1831            POINT2 pt2 = new POINT2();
1832            POINT2 pt3 = new POINT2();
1833            for (int j = 0; j < vblCounter; j++) {
1834                pOriginalPoints[j] = new POINT2(pLinePoints[j]);
1835            }
1836            int direction = 0;
1837            int numSegs = 0;
1838            double d = 0;
1839            for (int j = 0; j < vblCounter - 1; j++) {
1840                d = lineutility.CalcDistanceDouble(pOriginalPoints[j], pOriginalPoints[j + 1]);
1841                numSegs = (int) (d / length);
1842                if (pOriginalPoints[j].x < pOriginalPoints[j + 1].x) {
1843                    direction = 3;
1844                } else {
1845                    direction = 2;
1846                }
1847                for (int k = 0; k < numSegs; k++) {
1848                    pt0 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k);
1849                    pt0.style = 0;
1850                    pt1 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k + length * 2 / 3);
1851                    pt1.style = 5;
1852                    pt2 = lineutility.MidPointDouble(pt0, pt1, 0);
1853                    //pt3 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt2, 3, 10);
1854                    pt3 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt2, direction, length * 2 / 3);
1855                    pt3.style = 5;
1856                    pLinePoints[counter++] = new POINT2(pt2);
1857                    pLinePoints[counter++] = new POINT2(pt3);
1858                    pLinePoints[counter++] = new POINT2(pt0);
1859                    pLinePoints[counter++] = new POINT2(pt1);
1860                }
1861                if (numSegs == 0) {
1862                    pLinePoints[counter++] = new POINT2(pOriginalPoints[j]);
1863                    pLinePoints[counter++] = new POINT2(pOriginalPoints[j + 1]);
1864                }
1865            }
1866            pLinePoints[counter - 1].style = 0;
1867            pLinePoints[counter++] = new POINT2(pOriginalPoints[vblCounter - 1]);
1868        } catch (Exception exc) {
1869            ErrorLogger.LogException(_className, "GetRestrictedAreaPoints",
1870                    new RendererException("GetRestrictedAreaPoints", exc));
1871        }
1872        return counter;
1873    }
1874
1875    //there should be two linetypes depending on scale
1876    private static int getOverheadWire(TGLight tg, POINT2[] pLinePoints, int vblCounter) {
1877        int counter = 0;
1878        try {
1879            int j = 0;
1880            POINT2 pt = null, pt2 = null;
1881            ArrayList<POINT2> pts = new ArrayList();
1882            for (j = 0; j < vblCounter; j++) {
1883                pt = new POINT2(pLinePoints[j]);
1884                //tower
1885                pt2 = new POINT2(pt);
1886                pt2.y -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1887                pts.add(pt2);
1888                pt2 = new POINT2(pt);
1889                pt2.x -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1890                pts.add(pt2);
1891                pt2 = new POINT2(pt);
1892                pt2.y -= arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1893                pts.add(pt2);
1894                pt2 = new POINT2(pt);
1895                pt2.x += arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1896                pts.add(pt2);
1897                pt2 = new POINT2(pt);
1898                pt2.y -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1899                pt2.style = 5;
1900                pts.add(pt2);
1901                //low cross piece
1902                pt2 = new POINT2(pt);
1903                pt2.x -= arraysupport.getScaledSize(2, tg.get_LineThickness(), tg.get_patternScale());
1904                pt2.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
1905                pts.add(pt2);
1906                pt2 = new POINT2(pt);
1907                pt2.x += arraysupport.getScaledSize(2, tg.get_LineThickness(), tg.get_patternScale());
1908                pt2.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
1909                pt2.style = 5;
1910                pts.add(pt2);
1911                //high cross piece
1912                pt2 = new POINT2(pt);
1913                pt2.x -= arraysupport.getScaledSize(7, tg.get_LineThickness(), tg.get_patternScale());
1914                pt2.y -= arraysupport.getScaledSize(17, tg.get_LineThickness(), tg.get_patternScale());
1915                pts.add(pt2);
1916                pt2 = new POINT2(pt);
1917                pt2.x -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1918                pt2.y -= arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1919                pts.add(pt2);
1920                pt2 = new POINT2(pt);
1921                pt2.x += arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1922                pt2.y -= arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1923                pts.add(pt2);
1924                pt2 = new POINT2(pt);
1925                pt2.x += arraysupport.getScaledSize(7, tg.get_LineThickness(), tg.get_patternScale());
1926                pt2.y -= arraysupport.getScaledSize(17, tg.get_LineThickness(), tg.get_patternScale());
1927                pt2.style = 5;
1928                pts.add(pt2);
1929                //angle piece
1930                pt2 = new POINT2(pt);
1931                pt2.y -= arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1932                pts.add(pt2);
1933                pt2 = new POINT2(pt);
1934                pt2.x += arraysupport.getScaledSize(8, tg.get_LineThickness(), tg.get_patternScale());
1935                pt2.y -= arraysupport.getScaledSize(12, tg.get_LineThickness(), tg.get_patternScale());
1936                pt2.style = 5;
1937                pts.add(pt2);
1938            }
1939            //connect the towers
1940            for (j = 0; j < vblCounter - 1; j++) {
1941                pt = new POINT2(pLinePoints[j]);
1942                pt2 = new POINT2(pLinePoints[j + 1]);
1943                if (pt.x < pt2.x) {
1944                    pt.x += arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1945                    pt.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
1946                    pt2.x -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1947                    pt2.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
1948                    pt2.style = 5;
1949                } else {
1950                    pt.x -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1951                    pt.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
1952                    pt2.x += arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1953                    pt2.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
1954                    pt2.style = 5;
1955                }
1956                pts.add(pt);
1957                pts.add(pt2);
1958            }
1959            for (j = 0; j < pts.size(); j++) {
1960                pLinePoints[j] = pts.get(j);
1961                counter++;
1962            }
1963            for (j = counter; j < pLinePoints.length; j++) {
1964                pLinePoints[j] = new POINT2(pLinePoints[counter - 1]);
1965            }
1966        } catch (Exception exc) {
1967            ErrorLogger.LogException(_className, "GetOverheadWire",
1968                    new RendererException("GetOverheadWire", exc));
1969        }
1970        return counter;
1971    }
1972
1973    //private static int linetype=-1; //use for BLOCK, CONTIAN
1974    /**
1975     * Calculates the points for the non-channel symbols. The points will be
1976     * stored in the original POINT2 array in pixels, pLinePoints. The client
1977     * points occupy the first vblSaveCounter positions in pLinePoints and will
1978     * be overwritten by the symbol points.
1979     *
1980     * @param pLinePoints - OUT - an array of POINT2
1981     * @param vblCounter the number of points allocated
1982     * @param vblSaveCounter the number of client points
1983     *
1984     * @return the symbol point count
1985     */
1986    private static ArrayList<POINT2> GetLineArray2Double(TGLight tg,
1987            POINT2[] pLinePoints,
1988            int vblCounter,
1989            int vblSaveCounter,
1990            ArrayList<Shape2> shapes,
1991            Rectangle2D clipBounds,
1992            IPointConversion converter) {
1993        ArrayList<POINT2> points = new ArrayList();
1994        try {
1995            int lineType = tg.get_LineType();
1996            String client = CELineArray.getClient();
1997            if (pLinePoints == null || pLinePoints.length < 2) {
1998                return null;
1999            }
2000            int[] segments = null;
2001            double dMRR = 0;
2002            int n = 0, bolVertical = 0;
2003            double dExtendLength = 0;
2004            double dWidth = 0;
2005            int nQuadrant = 0;
2006            int lLinestyle = 0, pointCounter = 0;
2007            ref<double[]> offsetX = new ref(), offsetY = new ref();
2008            double b = 0, b1 = 0, dRadius = 0, d1 = 0, d = 0;
2009            ref<double[]> m = new ref();
2010            int direction = 0;
2011            int nCounter = 0;
2012            int j = 0, k = 0, middleSegment = -1;
2013            double dMBR = lineutility.MBRDistance(pLinePoints, vblSaveCounter);
2014            POINT2 pt0 = new POINT2(pLinePoints[0]), //calculation points for autoshapes
2015                    pt1 = new POINT2(pLinePoints[1]),
2016                    pt2 = new POINT2(pLinePoints[1]),
2017                    pt3 = new POINT2(pLinePoints[0]),
2018                    pt4 = new POINT2(pLinePoints[0]),
2019                    pt5 = new POINT2(pLinePoints[0]),
2020                    pt6 = new POINT2(pLinePoints[0]),
2021                    pt7 = new POINT2(pLinePoints[0]),
2022                    pt8 = new POINT2(pLinePoints[0]),
2023                    ptYIntercept = new POINT2(pLinePoints[0]),
2024                    ptYIntercept1 = new POINT2(pLinePoints[0]),
2025                    ptCenter = new POINT2(pLinePoints[0]);
2026            POINT2[] pArrowPoints = new POINT2[3],
2027                    arcPts = new POINT2[26],
2028                    circlePoints = new POINT2[100],
2029                    pts = null, pts2 = null;
2030            POINT2 midpt = new POINT2(pLinePoints[0]), midpt1 = new POINT2(pLinePoints[0]);
2031
2032            POINT2[] pOriginalLinePoints = null;
2033            POINT2[] pUpperLinePoints = null;
2034            POINT2[] pLowerLinePoints = null;
2035            POINT2[] pUpperLowerLinePoints = null;
2036
2037            POINT2 calcPoint0 = new POINT2(),
2038                    calcPoint1 = new POINT2(),
2039                    calcPoint2 = new POINT2(),
2040                    calcPoint3 = new POINT2(),
2041                    calcPoint4 = new POINT2();
2042            POINT2 ptTemp = new POINT2(pLinePoints[0]);
2043            int acCounter = 0;
2044            POINT2[] acPoints = new POINT2[6];
2045            int lFlotCount = 0;
2046            //end declarations
2047
2048            //Bearing line and others only have 2 points
2049            if (vblCounter > 2) {
2050                pt2 = new POINT2(pLinePoints[2]);
2051            }
2052            pt0.style = 0;
2053            pt1.style = 0;
2054            pt2.style = 0;
2055
2056            //set jaggylength in clsDISMSupport before the points get bounded
2057            ArrayList xPoints = null;
2058            pOriginalLinePoints = new POINT2[vblSaveCounter];
2059            for (j = 0; j < vblSaveCounter; j++) {
2060                pOriginalLinePoints[j] = new POINT2(pLinePoints[j]);
2061            }
2062
2063            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
2064
2065            //resize the array and get the line array
2066            //for the specified non-channel line type
2067            switch (lineType) {
2068                case TacticalLines.BBS_AREA:
2069                    lineutility.getExteriorPoints(pLinePoints, vblSaveCounter, lineType, false);
2070                    acCounter = vblSaveCounter;
2071                    break;
2072                case TacticalLines.BS_CROSS:
2073                    pt0 = new POINT2(pLinePoints[0]);
2074                    pLinePoints[0] = new POINT2(pt0);
2075                    pLinePoints[0].x -= 10;
2076                    pLinePoints[1] = new POINT2(pt0);
2077                    pLinePoints[1].x += 10;
2078                    pLinePoints[1].style = 10;
2079                    pLinePoints[2] = new POINT2(pt0);
2080                    pLinePoints[2].y += 10;
2081                    pLinePoints[3] = new POINT2(pt0);
2082                    pLinePoints[3].y -= 10;
2083                    acCounter = 4;
2084                    break;
2085                case TacticalLines.BS_RECTANGLE:
2086                    lineutility.CalcMBRPoints(pLinePoints, pLinePoints.length, pt0, pt2);   //pt0=ul, pt1=lr
2087                    pt1 = new POINT2(pt0);
2088                    pt1.x = pt2.x;
2089                    pt3 = new POINT2(pt0);
2090                    pt3.y = pt2.y;
2091                    pLinePoints = new POINT2[5];
2092                    pLinePoints[0] = new POINT2(pt0);
2093                    pLinePoints[1] = new POINT2(pt1);
2094                    pLinePoints[2] = new POINT2(pt2);
2095                    pLinePoints[3] = new POINT2(pt3);
2096                    pLinePoints[4] = new POINT2(pt0);
2097                    acCounter = 5;
2098                    break;
2099                case TacticalLines.BBS_RECTANGLE:
2100                    //double xmax=pLinePoints[0].x,xmin=pLinePoints[1].x,ymax=pLinePoints[0].y,ymin=pLinePoints[1].y;
2101                    //double xmax=pLinePoints[2].x,xmin=pLinePoints[0].x,ymax=pLinePoints[2].y,ymin=pLinePoints[0].y;
2102                    double buffer = pLinePoints[0].style;
2103
2104                    pOriginalLinePoints = new POINT2[5];
2105                    pOriginalLinePoints[0] = new POINT2(pLinePoints[0]);
2106                    pOriginalLinePoints[1] = new POINT2(pLinePoints[1]);
2107                    pOriginalLinePoints[2] = new POINT2(pLinePoints[2]);
2108                    pOriginalLinePoints[3] = new POINT2(pLinePoints[3]);
2109                    pOriginalLinePoints[4] = new POINT2(pLinePoints[0]);
2110
2111                    //clockwise orientation
2112                    pt0 = pLinePoints[0];
2113                    pt0.x -= buffer;
2114                    pt0.y -= buffer;
2115                    pt1 = pLinePoints[1];
2116                    pt1.x += buffer;
2117                    pt1.y -= buffer;
2118                    pt2 = pLinePoints[2];
2119                    pt2.x += buffer;
2120                    pt2.y += buffer;
2121                    pt3 = pLinePoints[3];
2122                    pt3.x -= buffer;
2123                    pt3.y += buffer;
2124                    pLinePoints = new POINT2[5];
2125                    pLinePoints[0] = new POINT2(pt0);
2126                    pLinePoints[1] = new POINT2(pt1);
2127                    pLinePoints[2] = new POINT2(pt2);
2128                    pLinePoints[3] = new POINT2(pt3);
2129                    pLinePoints[4] = new POINT2(pt0);
2130                    vblSaveCounter = 5;
2131                    acCounter = 5;
2132                    break;
2133                case TacticalLines.BS_ELLIPSE:
2134                    pt0 = pLinePoints[0];//the center of the ellipse
2135                    pt1 = pLinePoints[1];//the width of the ellipse
2136                    pt2 = pLinePoints[2];//the height of the ellipse
2137                    //pLinePoints=getEllipsePoints(pt0,pt1,pt2);
2138                    double azimuth = pLinePoints[3].x;
2139                    pLinePoints = getRotatedEllipsePoints(pt0, pt1, pt2, azimuth, lineType);
2140                    acCounter = 37;
2141                    break;
2142                case TacticalLines.OVERHEAD_WIRE:
2143                    acCounter = getOverheadWire(tg, pLinePoints, vblSaveCounter);
2144                    break;
2145                case TacticalLines.BOUNDARY:
2146                case TacticalLines.TRIP:
2147                    acCounter = pLinePoints.length;
2148                    break;
2149                case TacticalLines.REEF:
2150                    vblCounter = GetReefPoints(pLinePoints, arraysupport.getScaledSize(40, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2151                    acCounter = vblCounter;
2152                    break;
2153                case TacticalLines.RESTRICTED_AREA:
2154                    vblCounter = GetRestrictedAreaPoints(pLinePoints, arraysupport.getScaledSize(15, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2155                    acCounter = vblCounter;
2156                    break;
2157                case TacticalLines.TRAINING_AREA:
2158                    dMBR = lineutility.MBRDistance(pLinePoints, vblSaveCounter);
2159                    d = 20 * DPIScaleFactor;
2160                    if (dMBR < 60 * DPIScaleFactor) {
2161                        d = dMBR / 4;
2162                    }
2163                    if (d < 5 * DPIScaleFactor) {
2164                        d = 5 * DPIScaleFactor;
2165                    }
2166                    for (j = 0; j < vblSaveCounter; j++) {
2167                        pLinePoints[j].style = 1;
2168                    }
2169                    pLinePoints[vblSaveCounter - 1].style = 5;
2170                    pt0 = lineutility.CalcCenterPointDouble(pLinePoints, vblSaveCounter - 1);
2171                    //lineutility.CalcCircleDouble(pt0, 20, 26, arcPts, 0);
2172                    lineutility.CalcCircleDouble(pt0, d, 26, arcPts, 0);
2173
2174                    for (j = vblSaveCounter; j < vblSaveCounter + 26; j++) {
2175                        pLinePoints[j] = new POINT2(arcPts[j - vblSaveCounter]);
2176                    }
2177                    pLinePoints[j - 1].style = 5;
2178
2179                    //! inside the circle
2180                    if (dMBR < 50 * DPIScaleFactor) {
2181                        //d was used as the circle radius
2182                        d *= 0.6;
2183                    } else {
2184                        d = 12 * DPIScaleFactor;
2185                    }
2186
2187                    pt1 = new POINT2(pt0);
2188                    pt1.y -= d;
2189                    pt1.style = 0;
2190                    pt2 = new POINT2(pt1);
2191                    pt2.y += d;
2192                    pt2.style = 5;
2193                    pt3 = new POINT2(pt2);
2194                    pt3.y += d / 4 + tg.get_LineThickness();
2195                    pt3.style = 0;
2196                    pt4 = new POINT2(pt3);
2197                    pt4.y += d / 4;
2198                    pLinePoints[j++] = new POINT2(pt1);
2199                    pLinePoints[j++] = new POINT2(pt2);
2200                    pLinePoints[j++] = new POINT2(pt3);
2201                    pt4.style = 5;
2202                    pLinePoints[j++] = new POINT2(pt4);
2203                    vblCounter = j;
2204                    acCounter = vblCounter;
2205                    break;
2206                case TacticalLines.PIPE:
2207                    vblCounter = GetPipePoints(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2208                    acCounter = vblCounter;
2209                    break;
2210                case TacticalLines.ANCHORAGE_AREA:
2211                    //get the direction and quadrant of the first segment
2212                    n = GetInsideOutsideDouble2(pLinePoints[0], pLinePoints[1], pLinePoints, vblSaveCounter, 0, lineType);
2213                    nQuadrant = lineutility.GetQuadrantDouble(pLinePoints[0], pLinePoints[1]);
2214                    //if the direction and quadrant are not compatible with GetFlotDouble then
2215                    //reverse the points
2216                    switch (nQuadrant) {
2217                        case 4:
2218                            switch (n) {
2219                                case 1: //extend left
2220                                case 2: //extend below
2221                                    break;
2222                                case 0: //extend right
2223                                case 3: //extend above
2224                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2225                                    break;
2226                                default:
2227                                    break;
2228                            }
2229                            break;
2230                        case 1:
2231                            switch (n) {
2232                                case 1: //extend left
2233                                case 3: //extend above
2234                                    break;
2235                                case 0: //extend right
2236                                case 2: //extend below
2237                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2238                                    break;
2239                                default:
2240                                    break;
2241                            }
2242                            break;
2243                        case 2:
2244                            switch (n) {
2245                                case 1: //extend left
2246                                case 2: //extend below
2247                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2248                                    break;
2249                                case 0: //extend right
2250                                case 3: //extend above
2251                                    break;
2252                                default:
2253                                    break;
2254                            }
2255                            break;
2256                        case 3:
2257                            switch (n) {
2258                                case 1: //extend left
2259                                case 3: //extend above
2260                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2261                                    break;
2262                                case 0: //extend right
2263                                case 2: //extend above
2264                                    break;
2265                                default:
2266                                    break;
2267                            }
2268                            break;
2269                        default:
2270                            break;
2271                    }
2272                    lFlotCount = GetAnchorageDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2273                    acCounter = lFlotCount;
2274                    break;
2275                case TacticalLines.ANCHORAGE_LINE:
2276                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2277                    acCounter = GetAnchorageDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2278                    break;
2279                case TacticalLines.LRO:
2280                    int xCount = countsupport.GetXPointsCount(pOriginalLinePoints, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2281                    POINT2[] xPoints2 = new POINT2[xCount];
2282                    int lvoCount = countsupport.GetLVOCount(pOriginalLinePoints, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2283                    POINT2[] lvoPoints = new POINT2[lvoCount];
2284                    xCount = GetXPoints(pOriginalLinePoints, xPoints2, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2285                    lvoCount = GetLVOPoints(pOriginalLinePoints, lvoPoints, arraysupport.getScaledSize(4, tg.get_LineThickness(), tg.get_patternScale()), arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2286                    for (k = 0; k < xCount; k++) {
2287                        pLinePoints[k] = new POINT2(xPoints2[k]);
2288                    }
2289                    if (xCount > 0) {
2290                        pLinePoints[xCount - 1].style = 5;
2291                    }
2292                    for (k = 0; k < lvoCount; k++) {
2293                        pLinePoints[xCount + k] = new POINT2(lvoPoints[k]);
2294                    }
2295                    acCounter = xCount + lvoCount;
2296                    break;
2297                case TacticalLines.UNDERCAST:
2298                    if (pLinePoints[0].x < pLinePoints[1].x) {
2299                        lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2300                    }
2301
2302                    lFlotCount = flot.GetFlotDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2303                    acCounter = lFlotCount;
2304                    break;
2305                case TacticalLines.LVO:
2306                    acCounter = GetLVOPoints(pOriginalLinePoints, pLinePoints, arraysupport.getScaledSize(4, tg.get_LineThickness(), tg.get_patternScale()), arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2307                    break;
2308                case TacticalLines.ICING:
2309                    vblCounter = GetIcingPointsDouble(pLinePoints, arraysupport.getScaledSize(15, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2310                    acCounter = vblCounter;
2311                    break;
2312                case TacticalLines.MVFR:
2313                    //get the direction and quadrant of the first segment
2314                    n = GetInsideOutsideDouble2(pLinePoints[0], pLinePoints[1], pLinePoints, vblSaveCounter, 0, lineType);
2315                    nQuadrant = lineutility.GetQuadrantDouble(pLinePoints[0], pLinePoints[1]);
2316                    //if the direction and quadrant are not compatible with GetFlotDouble then
2317                    //reverse the points
2318                    switch (nQuadrant) {
2319                        case 4:
2320                            switch (n) {
2321                                case 0: //extend left
2322                                case 3: //extend below
2323                                    break;
2324                                case 1: //extend right
2325                                case 2: //extend above
2326                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2327                                    break;
2328                                default:
2329                                    break;
2330                            }
2331                            break;
2332                        case 1:
2333                            switch (n) {
2334                                case 0: //extend left
2335                                case 2: //extend above
2336                                    break;
2337                                case 1: //extend right
2338                                case 3: //extend below
2339                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2340                                    break;
2341                                default:
2342                                    break;
2343                            }
2344                            break;
2345                        case 2:
2346                            switch (n) {
2347                                case 0: //extend left
2348                                case 3: //extend below
2349                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2350                                    break;
2351                                case 1: //extend right
2352                                case 2: //extend above
2353                                    break;
2354                                default:
2355                                    break;
2356                            }
2357                            break;
2358                        case 3:
2359                            switch (n) {
2360                                case 0: //extend left
2361                                case 2: //extend above
2362                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2363                                    break;
2364                                case 1: //extend right
2365                                case 3: //extend above
2366                                    break;
2367                                default:
2368                                    break;
2369                            }
2370                            break;
2371                        default:
2372                            break;
2373                    }
2374                    lFlotCount = flot.GetFlotDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2375                    acCounter = lFlotCount;
2376                    break;
2377                case TacticalLines.ITD:
2378                    acCounter = GetITDPointsDouble(pLinePoints, arraysupport.getScaledSize(15, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2379                    break;
2380                case TacticalLines.CONVERGENCE:
2381                    acCounter = GetConvergencePointsDouble(pLinePoints, arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2382                    break;
2383                case TacticalLines.RIDGE:
2384                    vblCounter = GetRidgePointsDouble(tg, pLinePoints, vblSaveCounter);
2385                    acCounter = vblCounter;
2386                    break;
2387                case TacticalLines.TROUGH:
2388                case TacticalLines.UPPER_TROUGH:
2389                case TacticalLines.INSTABILITY:
2390                case TacticalLines.SHEAR:
2391                    vblCounter = GetSquallDouble(pLinePoints, arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 6, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2392                    acCounter = vblCounter;
2393                    break;
2394                case TacticalLines.CABLE:
2395                    vblCounter = GetSquallDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), 6, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2396                    acCounter = vblCounter;
2397                    break;
2398                case TacticalLines.SQUALL:
2399                    vblCounter = GetSevereSquall(pLinePoints, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2400                    acCounter = vblCounter;
2401                    break;
2402                case TacticalLines.SF:
2403                case TacticalLines.USF:
2404                case TacticalLines.SFG:
2405                case TacticalLines.SFY:
2406                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2407                    vblCounter = flot.GetSFPointsDouble(tg, pLinePoints, vblSaveCounter);
2408                    acCounter = vblCounter;
2409                    break;
2410                case TacticalLines.OFY:
2411                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2412                    vblCounter = flot.GetOFYPointsDouble(tg, pLinePoints, vblSaveCounter);
2413                    acCounter = vblCounter;
2414                    break;
2415                case TacticalLines.OCCLUDED:
2416                case TacticalLines.UOF:
2417                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2418                    vblCounter = flot.GetOccludedPointsDouble(tg, pLinePoints, vblSaveCounter);
2419                    for (j = 0; j < vblSaveCounter; j++) {
2420                        pLinePoints[vblCounter + j] = pOriginalLinePoints[j];
2421                    }
2422                    vblCounter += vblSaveCounter;
2423                    acCounter = vblCounter;
2424                    break;
2425                case TacticalLines.WF:
2426                case TacticalLines.UWF:
2427                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2428                    lFlotCount = flot.GetFlot2Double(tg, pLinePoints, vblSaveCounter);
2429                    for (j = 0; j < vblSaveCounter; j++) {
2430                        pLinePoints[vblCounter - vblSaveCounter + j] = pOriginalLinePoints[j];
2431                    }
2432                    acCounter = lFlotCount + vblSaveCounter;
2433                    break;
2434                case TacticalLines.WFG:
2435                case TacticalLines.WFY:
2436                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2437                    lFlotCount = flot.GetFlot2Double(tg, pLinePoints, vblSaveCounter);
2438                    acCounter = lFlotCount;
2439                    break;
2440                case TacticalLines.CFG:
2441                case TacticalLines.CFY:
2442                    vblCounter = GetATWallPointsDouble(tg, pLinePoints, vblSaveCounter);
2443                    acCounter = vblCounter;
2444                    break;
2445                case TacticalLines.CF:
2446                case TacticalLines.UCF:
2447                    vblCounter = GetATWallPointsDouble(tg, pLinePoints, vblSaveCounter);
2448                    pLinePoints[vblCounter - 1].style = 5;
2449                    for (j = 0; j < vblSaveCounter; j++) {
2450                        pLinePoints[vblCounter + j] = pOriginalLinePoints[j];
2451                    }
2452                    vblCounter += vblSaveCounter;
2453                    pLinePoints[vblCounter - 1].style = 5;
2454                    acCounter = vblCounter;
2455                    break;
2456                case TacticalLines.IL:
2457                case TacticalLines.PLANNED:
2458                case TacticalLines.ESR1:
2459                case TacticalLines.ESR2:
2460                    lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pLinePoints[2], pt0, pt1);
2461                    d = lineutility.CalcDistanceDouble(pLinePoints[0], pt0);
2462                    pt4 = lineutility.ExtendLineDouble(pt0, pLinePoints[0], d);
2463                    lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pt4, pt2, pt3);
2464                    pLinePoints[0] = new POINT2(pt0);
2465                    pLinePoints[1] = new POINT2(pt1);
2466                    pLinePoints[2] = new POINT2(pt3);
2467                    pLinePoints[3] = new POINT2(pt2);
2468                    switch (lineType) {
2469                        case TacticalLines.IL:
2470                        case TacticalLines.ESR2:
2471                            pLinePoints[0].style = 0;
2472                            pLinePoints[1].style = 5;
2473                            pLinePoints[2].style = 0;
2474                            break;
2475                        case TacticalLines.PLANNED:
2476                            pLinePoints[0].style = 1;
2477                            pLinePoints[1].style = 5;
2478                            pLinePoints[2].style = 1;
2479                            break;
2480                        case TacticalLines.ESR1:
2481                            pLinePoints[1].style = 5;
2482                            if (pt0.x <= pt1.x) {
2483                                if (pLinePoints[1].y <= pLinePoints[2].y) {
2484                                    pLinePoints[0].style = 0;
2485                                    pLinePoints[2].style = 1;
2486                                } else {
2487                                    pLinePoints[0].style = 1;
2488                                    pLinePoints[2].style = 0;
2489                                }
2490                            } else {
2491                                if (pLinePoints[1].y >= pLinePoints[2].y) {
2492                                    pLinePoints[0].style = 0;
2493                                    pLinePoints[2].style = 1;
2494                                } else {
2495                                    pLinePoints[0].style = 1;
2496                                    pLinePoints[2].style = 0;
2497                                }
2498                            }
2499                            break;
2500                        default:
2501                            break;
2502                    }
2503                    acCounter = 4;
2504                    break;
2505                case TacticalLines.FORDSITE:
2506                    lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pLinePoints[2], pt0, pt1);
2507                    pLinePoints[0].style = 1;
2508                    pLinePoints[1].style = 5;
2509                    pLinePoints[2] = new POINT2(pt0);
2510                    pLinePoints[2].style = 1;
2511                    pLinePoints[3] = new POINT2(pt1);
2512                    pLinePoints[3].style = 5;
2513                    acCounter = 4;
2514                    break;
2515                case TacticalLines.ROADBLK:
2516                    pts = new POINT2[4];
2517                    for (j = 0; j < 4; j++) {
2518                        pts[j] = new POINT2(pLinePoints[j]);
2519                    }
2520                    dRadius = lineutility.CalcDistanceDouble(pLinePoints[0], pLinePoints[1]);
2521                    d = lineutility.CalcDistanceToLineDouble(pLinePoints[0], pLinePoints[1], pLinePoints[2]);
2522
2523                    //first two lines
2524                    pLinePoints[0] = lineutility.ExtendTrueLinePerpDouble(pts[0], pts[1], pts[1], d, 0);
2525                    pLinePoints[1] = lineutility.ExtendTrueLinePerpDouble(pts[0], pts[1], pts[0], d, 5);
2526                    pLinePoints[2] = lineutility.ExtendTrueLinePerpDouble(pts[0], pts[1], pts[1], -d, 0);
2527                    pLinePoints[3] = lineutility.ExtendTrueLinePerpDouble(pts[0], pts[1], pts[0], -d, 5);
2528
2529                    midpt = lineutility.MidPointDouble(pts[0], pts[1], 0);
2530                    //move the midpoint
2531                    midpt = lineutility.ExtendLineDouble(pts[0], midpt, d);
2532
2533                    //the next line
2534                    pLinePoints[4] = lineutility.ExtendAngledLine(pts[0], pts[1], midpt, 105, dRadius / 2);
2535                    pLinePoints[5] = lineutility.ExtendAngledLine(pts[0], pts[1], midpt, -75, dRadius / 2);
2536                    pLinePoints[5].style = 5;
2537
2538                    //recompute the original midpt because it was moved
2539                    midpt = lineutility.MidPointDouble(pts[0], pts[1], 0);
2540                    //move the midpoint
2541                    midpt = lineutility.ExtendLineDouble(pts[1], midpt, d);
2542
2543                    //the last line
2544                    pLinePoints[6] = lineutility.ExtendAngledLine(pts[0], pts[1], midpt, 105, dRadius / 2);
2545                    pLinePoints[7] = lineutility.ExtendAngledLine(pts[0], pts[1], midpt, -75, dRadius / 2);
2546                    pLinePoints[7].style = 5;
2547
2548                    acCounter = 8;
2549                    break;
2550                case TacticalLines.AIRFIELD:
2551                    AirfieldCenterFeature(pLinePoints, vblCounter);
2552                    acCounter = vblCounter;
2553                    //FillPoints(pLinePoints,acCounter,points);
2554                    break;
2555                case TacticalLines.PNO:
2556                case TacticalLines.PLD:
2557                case TacticalLines.CFL:
2558                    for (j = 0; j < vblCounter; j++) {
2559                        pLinePoints[j].style = 1;
2560                    }
2561
2562                    acCounter = vblCounter;
2563                    break;
2564                case TacticalLines.FENCED:
2565                    FillPoints(pLinePoints, vblCounter, points);
2566                    xPoints = lineutility.LineOfXPoints(tg, pOriginalLinePoints);
2567                    for (j = 0; j < xPoints.size(); j++) {
2568                        points.add((POINT2) xPoints.get(j));
2569                    }
2570
2571                    acCounter = points.size();
2572                    break;
2573                case TacticalLines.FOXHOLE:
2574                    bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
2575
2576                    if (bolVertical == 0) //line is vertical
2577                    {
2578                        if (pt0.y > pt1.y) {
2579                            direction = 0;
2580                        } else {
2581                            direction = 1;
2582                        }
2583                    }
2584                    if (bolVertical != 0 && m.value[0] <= 1) {
2585                        if (pt0.x < pt1.x) {
2586                            direction = 3;
2587                        } else {
2588                            direction = 2;
2589                        }
2590                    }
2591                    if (bolVertical != 0 && m.value[0] > 1) {
2592                        if (pt0.x < pt1.x && pt0.y > pt1.y) {
2593                            direction = 1;
2594                        }
2595                        if (pt0.x < pt1.x && pt0.y < pt1.y) {
2596                            direction = 0;
2597                        }
2598
2599                        if (pt0.x > pt1.x && pt0.y > pt1.y) {
2600                            direction = 1;
2601                        }
2602                        if (pt0.x > pt1.x && pt0.y < pt1.y) {
2603                            direction = 0;
2604                        }
2605                    }
2606
2607                    if (dMBR / 20 > maxLength * DPIScaleFactor) {
2608                        dMBR = 20 * maxLength * DPIScaleFactor;
2609                    }
2610                    if (dMBR / 20 < minLength * DPIScaleFactor) {
2611                        dMBR = 20 * minLength * DPIScaleFactor;
2612                    }
2613                    if (dMBR < 250 * DPIScaleFactor) {
2614                        dMBR = 250 * DPIScaleFactor;
2615                    }
2616                    if (dMBR > 500 * DPIScaleFactor) {
2617                        dMBR = 500 * DPIScaleFactor;
2618                    }
2619
2620                    pLinePoints[0] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, direction, dMBR / 20);
2621                    pLinePoints[1] = new POINT2(pt0);
2622                    pLinePoints[2] = new POINT2(pt1);
2623                    pLinePoints[3] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, direction, dMBR / 20);
2624                    acCounter = 4;
2625                    break;
2626                case TacticalLines.ISOLATE:
2627                case TacticalLines.CORDONKNOCK:
2628                case TacticalLines.CORDONSEARCH:
2629                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2630                    acCounter = 50;
2631                    break;
2632                case TacticalLines.AREA_DEFENSE:
2633                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2634                    acCounter = 67;
2635                    break;
2636                case TacticalLines.OCCUPY:
2637                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2638                    acCounter = 32;
2639                    break;
2640                case TacticalLines.RETAIN:
2641                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2642                    acCounter = 75;
2643                    break;
2644                case TacticalLines.SECURE:
2645                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2646                    acCounter = 29;
2647                    break;
2648                case TacticalLines.TURN_REVD:
2649                case TacticalLines.TURN:
2650                    // Switch first and last point. Order changed in 2525C
2651                    POINT2 swapPt = pLinePoints[0];
2652                    pLinePoints[0] = pLinePoints[1];
2653                    pLinePoints[1] = swapPt;
2654                    GetIsolatePointsDouble(pLinePoints, lineType, null);
2655                    acCounter = 29;
2656                    break;
2657                case TacticalLines.ENCIRCLE:
2658                case TacticalLines.ZONE:
2659                case TacticalLines.OBSAREA:
2660                case TacticalLines.OBSFAREA:
2661                case TacticalLines.STRONG:
2662                case TacticalLines.FORT_REVD:
2663                case TacticalLines.FORT:
2664                    acCounter = GetZONEPointsDouble2(tg, pLinePoints, vblSaveCounter);
2665                    break;
2666                case TacticalLines.ATWALL:
2667                case TacticalLines.LINE:  //7-9-07
2668                    acCounter = GetATWallPointsDouble2(tg, pLinePoints, vblSaveCounter);
2669                    break;
2670                case TacticalLines.SC:
2671                case TacticalLines.MRR:
2672                case TacticalLines.SL:
2673                case TacticalLines.TC:
2674                case TacticalLines.LLTR:        //added 5-4-07
2675                case TacticalLines.SAAFR:       //these have multiple segments
2676                case TacticalLines.AC:
2677                    boolean bolSegmentAC = false;
2678                    //uncomment the next line if the air corridor is segmented
2679                    bolSegmentAC = true;
2680                    dMRR = dACP;
2681                    lineutility.InitializePOINT2Array(acPoints);
2682                    lineutility.InitializePOINT2Array(arcPts);
2683                    acCounter = 0;
2684                    if (!bolSegmentAC) {
2685                        for (j = 0; j < vblSaveCounter; j++) {
2686                            if (pOriginalLinePoints[j].style <= 0) {
2687                                pOriginalLinePoints[j].style = 1; //was 14
2688                            }
2689                        }
2690                    }
2691                    //get the SAAFR segments
2692                    for (j = 0; j < vblSaveCounter - 1; j++) {
2693                        //diagnostic: use style member for dMBR
2694                        dMBR = pOriginalLinePoints[j].style;
2695                        acPoints[0] = new POINT2(pOriginalLinePoints[j]);
2696                        acPoints[1] = new POINT2(pOriginalLinePoints[j + 1]);
2697                        lineutility.GetSAAFRSegment(acPoints, lineType, dMBR);//was dMRR
2698                        for (k = 0; k < 6; k++) {
2699                            pLinePoints[acCounter] = new POINT2(acPoints[k]);
2700                            acCounter++;
2701                        }
2702                    }
2703                    //get the circles
2704                    int currentCircleSize = 0;
2705                    if (!bolSegmentAC) 
2706                    {
2707                        for (j = 0; j < vblSaveCounter - 1; j++) {
2708                            currentCircleSize = pOriginalLinePoints[j].style;
2709                            //nextCircleSize=pOriginalLinePoints[j+1].style;                        
2710
2711                            //draw the circle at the segment front end
2712                            arcPts[0] = new POINT2(pOriginalLinePoints[j]);
2713                            //diagnostic: use style member for dMBR
2714                            dMBR = currentCircleSize;
2715                            lineutility.CalcCircleDouble(arcPts[0], dMBR, 26, arcPts, 0);//was dMRR
2716                            arcPts[25].style = 5;
2717                            for (k = 0; k < 26; k++) {
2718                                pLinePoints[acCounter] = new POINT2(arcPts[k]);
2719                                acCounter++;
2720                            }
2721
2722                            //draw the circle at the segment back end
2723                            arcPts[0] = new POINT2(pOriginalLinePoints[j + 1]);
2724                            dMBR = currentCircleSize;
2725                            lineutility.CalcCircleDouble(arcPts[0], dMBR, 26, arcPts, 0);//was dMRR
2726                            arcPts[25].style = 5;
2727                            for (k = 0; k < 26; k++) {
2728                                pLinePoints[acCounter] = new POINT2(arcPts[k]);
2729                                acCounter++;
2730                            }
2731                        }
2732                    } 
2733                    else    //segmented air corridors 
2734                    {
2735                        int lastCircleSize = 0;
2736                        POINT2 lastCirclePoint = null;
2737                        for (j = 0; j < vblSaveCounter; j++) {
2738                            currentCircleSize = pOriginalLinePoints[j].style;
2739                            if (j == 0) {
2740                                lastCircleSize = currentCircleSize;
2741                                lastCirclePoint = pOriginalLinePoints[j];
2742                                continue;
2743                            }
2744                            if (currentCircleSize < 0) {
2745                                continue;
2746                            }
2747                            //the current circle point
2748                            arcPts[0] = new POINT2(pOriginalLinePoints[j]);
2749                            dMBR = lastCircleSize;
2750                            lineutility.CalcCircleDouble(arcPts[0], dMBR, 26, arcPts, 0);
2751                            arcPts[25].style = 5;
2752                            for (k = 0; k < 26; k++) {
2753                                pLinePoints[acCounter] = new POINT2(arcPts[k]);
2754                                acCounter++;
2755                            }
2756                            //the previous circle point
2757                            arcPts[0] = new POINT2(lastCirclePoint);
2758                            lineutility.CalcCircleDouble(arcPts[0], dMBR, 26, arcPts, 0);
2759                            arcPts[25].style = 5;
2760                            for (k = 0; k < 26; k++) {
2761                                pLinePoints[acCounter] = new POINT2(arcPts[k]);
2762                                acCounter++;
2763                            }
2764                            //set the last values
2765                            lastCircleSize = currentCircleSize;
2766                            lastCirclePoint = pOriginalLinePoints[j];
2767                        }
2768                    }
2769                    break;
2770                case TacticalLines.MINED:
2771                case TacticalLines.UXO:
2772                case TacticalLines.ACOUSTIC:
2773                case TacticalLines.ACOUSTIC_AMB:
2774                case TacticalLines.BEARING:
2775                case TacticalLines.BEARING_J:
2776                case TacticalLines.BEARING_RDF:
2777                case TacticalLines.ELECTRO:
2778                case TacticalLines.BEARING_EW:
2779                case TacticalLines.TORPEDO:
2780                case TacticalLines.OPTICAL:
2781                    acCounter = vblCounter;
2782                    break;
2783                case TacticalLines.MSDZ:
2784                    lineutility.InitializePOINT2Array(circlePoints);
2785                    pt3 = new POINT2(pLinePoints[3]);
2786                    //dRadius = lineutility.CalcDistanceDouble(pt0, pt1);
2787                    if(converter==null)
2788                    {
2789                        dRadius = lineutility.CalcDistanceDouble(pt0, pt1);
2790                        lineutility.CalcCircleDouble(pt0, dRadius, 100,
2791                                circlePoints, 0);
2792                    }
2793                    else    //use the converter
2794                        lineutility.CalcCircleDouble2(pt0, pt1, 100,
2795                            circlePoints, converter);
2796                    for (j = 0; j < 100; j++) {
2797                        pLinePoints[j] = new POINT2(circlePoints[j]);
2798                    }
2799                    pLinePoints[99].style = 5;
2800                    //dRadius = lineutility.CalcDistanceDouble(pt0, pt2);
2801                    if(converter==null)
2802                    {
2803                        dRadius = lineutility.CalcDistanceDouble(pt0, pt2);
2804                        lineutility.CalcCircleDouble(pt0, dRadius, 100,
2805                            circlePoints, 0);
2806                    }
2807                    else
2808                        lineutility.CalcCircleDouble2(pt0, pt2, 100,
2809                            circlePoints, converter);
2810                    for (j = 0; j < 100; j++) {
2811                        pLinePoints[100 + j] = new POINT2(circlePoints[j]);
2812                    }
2813                    pLinePoints[199].style = 5;
2814                    //dRadius = lineutility.CalcDistanceDouble(pt0, pt3);
2815                   if (vblSaveCounter == 4) {
2816                       if (converter == null) {
2817                           dRadius = lineutility.CalcDistanceDouble(pt0, pt3);
2818                           lineutility.CalcCircleDouble(pt0, dRadius, 100,
2819                                   circlePoints, 0);
2820                       } else
2821                           lineutility.CalcCircleDouble2(pt0, pt3, 100,
2822                                   circlePoints, converter);
2823                       for (j = 0; j < 100; j++) {
2824                           pLinePoints[200 + j] = new POINT2(circlePoints[j]);
2825                       }
2826                   }
2827                    acCounter = vblCounter;
2828                    //FillPoints(pLinePoints,acCounter,points);
2829                    break;
2830                case TacticalLines.CONVOY:
2831                    if (dMBR < 150 * DPIScaleFactor) {
2832                        dMBR = 150 * DPIScaleFactor;
2833                    }
2834                    if (dMBR > 500 * DPIScaleFactor) {
2835                        dMBR = 500 * DPIScaleFactor;
2836                    }
2837                    dWidth = dMBR / 25;
2838
2839                    pt0 = new POINT2(pLinePoints[0]);
2840                    pt1 = new POINT2(pLinePoints[1]);
2841
2842                    bolVertical = lineutility.CalcTrueSlopeDouble(pt1, pt0, m);
2843                    pt0 = lineutility.ExtendLine2Double(pt1, pt0, -dWidth*3, 0);
2844                    if (m.value[0] < 1) {
2845                        pLinePoints[0] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 2, dWidth);
2846                        pLinePoints[1] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 2, dWidth);
2847                        pLinePoints[2] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 3, dWidth);
2848                        pLinePoints[3] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 3, dWidth);
2849                    } else {
2850                        pLinePoints[0] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 0, dWidth);
2851                        pLinePoints[1] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 0, dWidth);
2852                        pLinePoints[2] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 1, dWidth);
2853                        pLinePoints[3] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 1, dWidth);
2854                    }
2855                    pt2 = lineutility.ExtendLineDouble(pt1, pt0, dWidth * 3);
2856                    lineutility.GetArrowHead4Double(pt0, pt2, (int) (dWidth * 3), (int) (dWidth * 3), pArrowPoints, 0);
2857
2858                    d = lineutility.CalcDistanceDouble(pLinePoints[0], pArrowPoints[0]);
2859                    d1 = lineutility.CalcDistanceDouble(pLinePoints[3], pArrowPoints[0]);
2860                    pLinePoints[3].style = 5;
2861                    if (d < d1) {
2862                        pLinePoints[4] = new POINT2(pLinePoints[0]);
2863                        pLinePoints[4].style = 0;
2864                        pLinePoints[5] = new POINT2(pArrowPoints[0]);
2865                        pLinePoints[5].style = 0;
2866                        pLinePoints[6] = new POINT2(pArrowPoints[1]);
2867                        pLinePoints[6].style = 0;
2868                        pLinePoints[7] = new POINT2(pArrowPoints[2]);
2869                        pLinePoints[7].style = 0;
2870                        pLinePoints[8] = new POINT2(pLinePoints[3]);
2871                    } else {
2872                        pLinePoints[4] = pLinePoints[3];
2873                        pLinePoints[4].style = 0;
2874                        pLinePoints[5] = pArrowPoints[0];
2875                        pLinePoints[5].style = 0;
2876                        pLinePoints[6] = pArrowPoints[1];
2877                        pLinePoints[6].style = 0;
2878                        pLinePoints[7] = pArrowPoints[2];
2879                        pLinePoints[7].style = 0;
2880                        pLinePoints[8] = pLinePoints[0];
2881                    }
2882
2883                    acCounter = 9;
2884                    //FillPoints(pLinePoints,acCounter,points);
2885                    break;
2886                case TacticalLines.HCONVOY:
2887                    if (dMBR < 150 * DPIScaleFactor) {
2888                        dMBR = 150 * DPIScaleFactor;
2889                    }
2890                    if (dMBR > 500 * DPIScaleFactor) {
2891                        dMBR = 500 * DPIScaleFactor;
2892                    }
2893                    dWidth = dMBR / 25;
2894
2895                    pt0 = new POINT2(pLinePoints[0]);
2896                    pt1 = new POINT2(pLinePoints[1]);
2897
2898                    pt2 = lineutility.ExtendAlongLineDouble(pt0, pt1, dWidth * 2); // Arrow point
2899                    lineutility.GetArrowHead4Double(pt0, pt2, (int) dWidth * 2, (int) dWidth * 2, pArrowPoints, 0);
2900
2901                    bolVertical = lineutility.CalcTrueSlopeDouble(pt1, pt2, m);
2902                    if (m.value[0] < 1) {
2903                        pLinePoints[0] = lineutility.ExtendDirectedLine(pt2, pt1, pt2, lineutility.extend_above, dWidth);
2904                        pLinePoints[1] = lineutility.ExtendDirectedLine(pt2, pt1, pt1, lineutility.extend_above, dWidth);
2905                        pLinePoints[2] = lineutility.ExtendDirectedLine(pt2, pt1, pt1, lineutility.extend_below, dWidth);
2906                        pLinePoints[3] = lineutility.ExtendDirectedLine(pt2, pt1, pt2, lineutility.extend_below, dWidth);
2907                    } else {
2908                        pLinePoints[0] = lineutility.ExtendDirectedLine(pt2, pt1, pt2, lineutility.extend_left, dWidth);
2909                        pLinePoints[1] = lineutility.ExtendDirectedLine(pt2, pt1, pt1, lineutility.extend_left, dWidth);
2910                        pLinePoints[2] = lineutility.ExtendDirectedLine(pt2, pt1, pt1, lineutility.extend_right, dWidth);
2911                        pLinePoints[3] = lineutility.ExtendDirectedLine(pt2, pt1, pt2, lineutility.extend_right, dWidth);
2912                    }
2913
2914                    pLinePoints[4] = new POINT2(pLinePoints[0]);
2915                    pLinePoints[5] = new POINT2(pt2);
2916                    pLinePoints[5].style = 0;
2917
2918                    pLinePoints[6] = new POINT2(pArrowPoints[1]);
2919                    pLinePoints[7] = new POINT2(pArrowPoints[0]);
2920                    pLinePoints[8] = new POINT2(pArrowPoints[2]);
2921                    pLinePoints[8].style = 0;
2922                    pLinePoints[9] = new POINT2(pArrowPoints[1]);
2923
2924                    acCounter = 10;
2925                    //FillPoints(pLinePoints,acCounter,points);
2926                    break;
2927                case TacticalLines.MSR_ONEWAY:
2928                case TacticalLines.MSR_TWOWAY:
2929                case TacticalLines.MSR_ALT:
2930                case TacticalLines.ASR_ONEWAY:
2931                case TacticalLines.ASR_TWOWAY:
2932                case TacticalLines.ASR_ALT:
2933                case TacticalLines.ROUTE_ONEWAY:
2934                case TacticalLines.ROUTE_ALT:
2935                    nCounter = (int) vblSaveCounter;
2936                    pLinePoints[vblSaveCounter - 1].style = 5;
2937                    for (j = 0; j < vblSaveCounter - 1; j++) {
2938                        d = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
2939                        if (d < 20) //too short
2940                        {
2941                            continue;
2942                        }
2943                        pt0 = new POINT2(pLinePoints[j]);
2944                        pt1 = new POINT2(pLinePoints[j + 1]);
2945                        pt2 = lineutility.ExtendLine2Double(pLinePoints[j], pLinePoints[j + 1], -3 * d / 4, 0);
2946                        pt3 = lineutility.ExtendLine2Double(pLinePoints[j], pLinePoints[j + 1], -1 * d / 4, 5);
2947                        double distFromLine = 10 * DPIScaleFactor;
2948                        direction = SupplyRouteArrowSide(pLinePoints[j], pLinePoints[j + 1]);
2949                        pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt2, direction, distFromLine);
2950                        pt3 = lineutility.ExtendDirectedLine(pt0, pt1, pt3, direction, distFromLine);
2951                        pLinePoints[nCounter] = new POINT2(pt2);
2952                        nCounter++;
2953                        pLinePoints[nCounter] = new POINT2(pt3);
2954                        nCounter++;
2955
2956                        d = distFromLine;
2957                        if (dMBR / 20 < minLength * DPIScaleFactor) {
2958                            d = 5 * DPIScaleFactor;
2959                        }
2960
2961                        lineutility.GetArrowHead4Double(pt2, pt3, (int) d, (int) d,
2962                                pArrowPoints, 0);
2963
2964                        for (k = 0; k < 3; k++) {
2965                            pLinePoints[nCounter] = new POINT2(pArrowPoints[k]);
2966                            nCounter++;
2967                        }
2968
2969                        if (lineType == TacticalLines.MSR_ALT || lineType == TacticalLines.ASR_ALT || lineType == TacticalLines.ROUTE_ALT) {
2970                            lineutility.GetArrowHead4Double(pt3, pt2, (int) d, (int) d,
2971                                    pArrowPoints, 0);
2972
2973                            for (k = 0; k < 3; k++) {
2974                                pLinePoints[nCounter] = new POINT2(pArrowPoints[k]);
2975                                nCounter++;
2976                            }
2977                        }
2978                        if (lineType == TacticalLines.MSR_TWOWAY || lineType == TacticalLines.ASR_TWOWAY) {
2979                            distFromLine = 15 * DPIScaleFactor;
2980                            pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt2, direction, distFromLine);
2981                            pt3 = lineutility.ExtendDirectedLine(pt0, pt1, pt3, direction, distFromLine);
2982
2983                            pLinePoints[nCounter] = new POINT2(pt2);
2984                            nCounter++;
2985                            pLinePoints[nCounter] = new POINT2(pt3);
2986                            nCounter++;
2987                            lineutility.GetArrowHead4Double(pt3, pt2, (int) d, (int) d,
2988                                    pArrowPoints, 0);
2989
2990                            for (k = 0; k < 3; k++) {
2991                                pLinePoints[nCounter] = new POINT2(pArrowPoints[k]);
2992                                nCounter++;
2993                            }
2994                        }
2995                    }
2996                    acCounter = nCounter;
2997                    break;
2998                case TacticalLines.FORDIF:
2999                    lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pLinePoints[2], pt4, pt5);   //as pt2,pt3
3000                    pLinePoints[2] = new POINT2(pt5);//was pt3
3001                    pLinePoints[3] = new POINT2(pt4);//was pt2
3002
3003                    for (j = 0; j < vblCounter; j++) {
3004                        pLinePoints[j].style = 1;
3005                    }
3006
3007                    pt0 = lineutility.MidPointDouble(pLinePoints[0], pLinePoints[1], 0);
3008                    pt1 = lineutility.MidPointDouble(pLinePoints[2], pLinePoints[3], 0);
3009                    POINT2[] savepoints = null;
3010                    Boolean drawJaggies = true;
3011                    if (clipBounds != null) {
3012                        POINT2 ul = new POINT2(clipBounds.getMinX(), clipBounds.getMinY());
3013                        POINT2 lr = new POINT2(clipBounds.getMaxX(), clipBounds.getMaxY());
3014                        savepoints = lineutility.BoundOneSegment(pt0, pt1, ul, lr);
3015                        if (savepoints != null && savepoints.length > 1) {
3016                            pt0 = savepoints[0];
3017                            pt1 = savepoints[1];
3018                        } else {
3019                            savepoints = new POINT2[2];
3020                            savepoints[0] = new POINT2(pt0);
3021                            savepoints[1] = new POINT2(pt1);
3022                            drawJaggies = false;
3023                        }
3024                    }
3025
3026                    midpt = lineutility.MidPointDouble(pt0, pt1, 0);
3027                    double dist0 = lineutility.CalcDistanceDouble(midpt, pt0);
3028                    double dist1 = lineutility.CalcDistanceDouble(midpt, pt1);
3029
3030                    if (dist0 > dist1) {
3031                        lineutility.LineRelativeToLine(pLinePoints[2], pLinePoints[3], pt0, pt4, pt5);
3032                        pLinePoints[0] = new POINT2(pt5.x, pt5.y, 1);
3033                        pLinePoints[1] = new POINT2(pt4.x, pt4.y, 1);
3034                    } else {
3035                        lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pt1, pt4, pt5);
3036                        pLinePoints[2] = new POINT2(pt5.x, pt5.y, 1);
3037                        pLinePoints[3] = new POINT2(pt4.x, pt4.y, 1);
3038                    }
3039
3040                    //end section
3041                    //calculate start, end points for upper and lower lines
3042                    //across the middle
3043                    double spikeLength = getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
3044                    pt2 = lineutility.ExtendLine2Double(pLinePoints[0], pt0, -spikeLength, 0);
3045                    pt3 = lineutility.ExtendLine2Double(pLinePoints[3], pt1, -spikeLength, 0);
3046                    pt4 = lineutility.ExtendLine2Double(pLinePoints[0], pt0, spikeLength, 0);
3047                    pt5 = lineutility.ExtendLine2Double(pLinePoints[3], pt1, spikeLength, 0);
3048
3049                    dWidth = lineutility.CalcDistanceDouble(pt0, pt1);
3050
3051                    pointCounter = 4;
3052                    n = 1;
3053                    pLinePoints[pointCounter] = new POINT2(pt0);
3054                    pLinePoints[pointCounter].style = 0;
3055                    pointCounter++;
3056                    if (drawJaggies) {
3057                        while (dExtendLength < dWidth - spikeLength) {
3058                            dExtendLength = (double) n * spikeLength / 2;
3059                            pLinePoints[pointCounter] = lineutility.ExtendLine2Double(pt2, pt3, dExtendLength - dWidth, 0);
3060                            pointCounter++;
3061                            n++;
3062                            //dExtendLength = (double) n * 10;
3063                            dExtendLength = (double) n * spikeLength / 2;
3064                            pLinePoints[pointCounter] = lineutility.ExtendLine2Double(pt4, pt5, dExtendLength - dWidth, 0);
3065                            pointCounter++;
3066                            if (pointCounter >= pLinePoints.length - 1) {
3067                                break;
3068                            }
3069                            n++;
3070                        }
3071                    }
3072                    pLinePoints[pointCounter] = new POINT2(pt1);
3073                    pLinePoints[pointCounter].style = 5;
3074                    pointCounter++;
3075                    acCounter = pointCounter;
3076                    break;
3077                case TacticalLines.ATDITCH:
3078                    acCounter = lineutility.GetDitchSpikeDouble(tg, pLinePoints, vblSaveCounter, 0);
3079                    break;
3080                case (int) TacticalLines.ATDITCHC:      //extra Points were calculated by a function
3081                    pLinePoints[0].style = 9;
3082                    acCounter = lineutility.GetDitchSpikeDouble(tg, pLinePoints, vblSaveCounter, 0);
3083                    //pLinePoints[vblCounter-1].style=10;
3084                    break;
3085                case TacticalLines.ATDITCHM:
3086                    lineutility.ReversePointsDouble2(
3087                            pLinePoints,
3088                            vblSaveCounter);
3089                    pLinePoints[0].style = 9;
3090                    acCounter = lineutility.GetDitchSpikeDouble(tg, pLinePoints, vblSaveCounter, 0);
3091                    break;
3092                case TacticalLines.DIRATKGND:
3093                    //was 20
3094                    if (dMBR / 30 > maxLength * DPIScaleFactor) {
3095                        dMBR = 30 * maxLength * DPIScaleFactor;
3096                    }
3097                    if (dMBR / 30 < minLength * DPIScaleFactor) {
3098                        dMBR = 30 * minLength * DPIScaleFactor;
3099                    }
3100                    if (dMBR < 150 * DPIScaleFactor) {
3101                        dMBR = 150 * DPIScaleFactor;
3102                    }
3103                    if (dMBR > 500 * DPIScaleFactor) {
3104                        dMBR = 500 * DPIScaleFactor;
3105                    }
3106
3107                    d = lineutility.CalcDistanceDouble(pLinePoints[0], pLinePoints[1]);
3108                    if (d < dMBR / 40) {
3109                        pLinePoints[1] = lineutility.ExtendLineDouble(pLinePoints[0], pLinePoints[1], dMBR / 40 + 1);
3110                    }
3111
3112                    pLinePoints[0] = lineutility.ExtendAlongLineDouble(pLinePoints[0], pLinePoints[1], dMBR / 40);
3113
3114                    //reverse the points
3115                    lineutility.ReversePointsDouble2(
3116                            pLinePoints,
3117                            vblSaveCounter);
3118
3119                    pt0 = new POINT2(pLinePoints[vblCounter - 12]);
3120                    pt1 = new POINT2(pLinePoints[vblCounter - 11]);
3121                    pt2 = lineutility.ExtendLineDouble(pt0, pt1, dMBR / 40);
3122                    lineutility.GetArrowHead4Double(pt0, pt1, (int) dMBR / 20, (int) dMBR / 20,
3123                            pArrowPoints, 0);
3124
3125                    for (j = 0; j < 3; j++) {
3126                        pLinePoints[vblCounter - 10 + j] = new POINT2(pArrowPoints[j]);
3127                    }
3128                    lineutility.GetArrowHead4Double(pt0, pt2, (int) (dMBR / 13.33), (int) (dMBR / 13.33),
3129                            pArrowPoints, 0);
3130
3131                    for (j = 0; j < 3; j++) {
3132                        pLinePoints[vblCounter - 7 + j] = new POINT2(pArrowPoints[j]);
3133                    }
3134
3135                    pLinePoints[vblCounter - 4] = new POINT2(pLinePoints[vblCounter - 10]);
3136                    pLinePoints[vblCounter - 4].style = 0;
3137                    pLinePoints[vblCounter - 3] = new POINT2(pLinePoints[vblCounter - 7]);
3138                    pLinePoints[vblCounter - 3].style = 5;
3139
3140                    pLinePoints[vblCounter - 2] = new POINT2(pLinePoints[vblCounter - 8]);
3141                    pLinePoints[vblCounter - 2].style = 0;
3142                    pLinePoints[vblCounter - 1] = new POINT2(pLinePoints[vblCounter - 5]);
3143                    pLinePoints[vblCounter - 1].style = 5;
3144                    acCounter = vblCounter;
3145                    break;
3146                case TacticalLines.MFLANE:
3147                case TacticalLines.RAFT:
3148                    pt2 = lineutility.ExtendLineDouble(pLinePoints[vblCounter - 8], pLinePoints[vblCounter - 7], dMBR / 2);
3149                    pt3 = new POINT2(pLinePoints[vblCounter - 7]);
3150                    pt1 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], dMBR / 2);
3151
3152                    if (dMBR / 10 > maxLength * DPIScaleFactor) {
3153                        dMBR = 10 * maxLength * DPIScaleFactor;
3154                    }
3155                    if (dMBR / 10 < minLength * DPIScaleFactor) {
3156                        dMBR = 10 * minLength * DPIScaleFactor;
3157                    }
3158                    if (dMBR > 250 * DPIScaleFactor) {
3159                        dMBR = 250 * DPIScaleFactor;
3160                    }
3161
3162                    lineutility.GetArrowHead4Double(pt2, pt3, (int) dMBR / 10, (int) dMBR / 5,
3163                            pArrowPoints, 0);
3164
3165                    for (k = 0; k < 3; k++) {
3166                        pLinePoints[vblCounter - 6 + k] = new POINT2(pArrowPoints[k]);
3167                    }
3168
3169                    lineutility.GetArrowHead4Double(pt1, pt0, (int) dMBR / 10, (int) dMBR / 5,
3170                            pArrowPoints, 0);
3171
3172                    for (k = 0; k < 3; k++) {
3173                        pLinePoints[vblCounter - 3 + k] = new POINT2(pArrowPoints[k]);
3174                    }
3175                    pLinePoints[vblSaveCounter - 1].style = 5;
3176                    acCounter = vblCounter;
3177                    break;
3178                case TacticalLines.DIRATKAIR:
3179                    lineutility.ReversePointsDouble2(
3180                            pLinePoints,
3181                            vblSaveCounter);
3182
3183                    for (k = vblSaveCounter - 1; k > 0; k--) {
3184                        d += lineutility.CalcDistanceDouble(pLinePoints[k], pLinePoints[k - 1]);
3185                        if (d > 60) {
3186                            break;
3187                        }
3188                    }
3189                    if (d > 60) {
3190                        middleSegment = k;
3191                        pt2 = pLinePoints[middleSegment];
3192                        if (middleSegment >= 1) {
3193                            pt3 = pLinePoints[middleSegment - 1];
3194                        }
3195                    } else {
3196                        if (vblSaveCounter <= 3) {
3197                            middleSegment = 1;
3198                        } else {
3199                            middleSegment = 2;
3200                        }
3201
3202                        pt2 = pLinePoints[middleSegment];
3203                        if (middleSegment >= 1) {
3204                            pt3 = pLinePoints[middleSegment - 1];
3205                        }
3206                    }
3207
3208                    pt0 = new POINT2(pLinePoints[0]);
3209
3210                    if (dMBR / 20 > maxLength * DPIScaleFactor) {
3211                        dMBR = 20 * maxLength * DPIScaleFactor;
3212                    }
3213                    if (dMBR / 20 < minLength * DPIScaleFactor) {
3214                        dMBR = 20 * minLength * DPIScaleFactor;
3215                    }
3216                    if (dMBR < 150 * DPIScaleFactor) {
3217                        dMBR = 150 * DPIScaleFactor;
3218                    }
3219
3220                    if (dMBR > 250 * DPIScaleFactor) {
3221                        dMBR = 250 * DPIScaleFactor;
3222                    }
3223
3224                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 11], pLinePoints[vblCounter - 10], (int) dMBR / 20, (int) dMBR / 20,
3225                            pArrowPoints, 0);
3226
3227                    for (j = 0; j < 3; j++) {
3228                        pLinePoints[vblCounter - 9 + j] = new POINT2(pArrowPoints[j]);
3229                    }
3230
3231                    pLinePoints[vblCounter - 6].x = (pLinePoints[vblCounter - 11].x + pLinePoints[vblCounter - 10].x) / 2;
3232                    pLinePoints[vblCounter - 6].y = (pLinePoints[vblCounter - 11].y + pLinePoints[vblCounter - 10].y) / 2;
3233                    pt0 = new POINT2(pLinePoints[vblCounter - 6]);
3234                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 11], pt0, (int) dMBR / 20, (int) dMBR / 20,
3235                            pArrowPoints, 9);
3236
3237                    if (middleSegment >= 1) {
3238                        pt0 = lineutility.MidPointDouble(pt2, pt3, 0);
3239                        lineutility.GetArrowHead4Double(pt3, pt0, (int) dMBR / 20, (int) dMBR / 20,
3240                                pArrowPoints, 9);
3241                    }
3242
3243                    for (j = 0; j < 3; j++) {
3244                        pLinePoints[vblCounter - 6 + j] = new POINT2(pArrowPoints[j]);
3245                    }
3246
3247                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 10], pt0, (int) dMBR / 20, (int) dMBR / 20,
3248                            pArrowPoints, 9);
3249                    if (middleSegment >= 1) {
3250                        pt0 = lineutility.MidPointDouble(pt2, pt3, 0);
3251                        lineutility.GetArrowHead4Double(pt2, pt0, (int) dMBR / 20, (int) dMBR / 20,
3252                                pArrowPoints, 9);
3253                    }
3254                    for (j = 0; j < 3; j++) {
3255                        pLinePoints[vblCounter - 3 + j] = new POINT2(pArrowPoints[j]);
3256                    }
3257
3258                    //this section was added to remove fill from the bow tie feature
3259                    ArrayList<POINT2> airPts = new ArrayList();
3260                    pLinePoints[middleSegment - 1].style = 5;
3261                    //pLinePoints[middleSegment].style=14;
3262                    if (vblSaveCounter == 2) {
3263                        pLinePoints[1].style = 5;
3264                    }
3265
3266                    for (j = 0; j < vblCounter; j++) {
3267                        airPts.add(new POINT2(pLinePoints[j]));
3268                    }
3269
3270                    midpt = lineutility.MidPointDouble(pLinePoints[middleSegment - 1], pLinePoints[middleSegment], 0);
3271                    pt0 = lineutility.ExtendAlongLineDouble(midpt, pLinePoints[middleSegment], dMBR / 20, 0);
3272                    airPts.add(pt0);
3273                    pt1 = new POINT2(pLinePoints[middleSegment]);
3274                    pt1.style = 5;
3275                    airPts.add(pt1);
3276
3277                    pt0 = lineutility.ExtendAlongLineDouble(midpt, pLinePoints[middleSegment - 1], dMBR / 20, 0);
3278                    airPts.add(pt0);
3279                    pt1 = new POINT2(pLinePoints[middleSegment - 1]);
3280                    pt1.style = 5;
3281                    airPts.add(pt1);
3282
3283                    //re-dimension pLinePoints so that it can hold the
3284                    //the additional points required by the shortened middle segment
3285                    //which has the bow tie feature
3286                    vblCounter = airPts.size();
3287                    pLinePoints = new POINT2[airPts.size()];
3288                    for (j = 0; j < airPts.size(); j++) {
3289                        pLinePoints[j] = new POINT2(airPts.get(j));
3290                    }
3291                    //end section
3292
3293                    acCounter = vblCounter;
3294                    //FillPoints(pLinePoints,vblCounter,points);
3295                    break;
3296                case TacticalLines.PDF:
3297                    pt0 = new POINT2(pLinePoints[1]);
3298                    pt1 = new POINT2(pLinePoints[0]);
3299                    pLinePoints[0] = new POINT2(pt0);
3300                    pLinePoints[1] = new POINT2(pt1);
3301                    pts2 = new POINT2[3];
3302                    pts2[0] = new POINT2(pt0);
3303                    pts2[1] = new POINT2(pt1);
3304                    pts2[2] = new POINT2(pt2);
3305                    lineutility.GetPixelsMin(pts2, 3,
3306                            offsetX,
3307                            offsetY);
3308                    if (offsetX.value[0] < 0) {
3309                        offsetX.value[0] = offsetX.value[0] - 100;
3310                    } else {
3311                        offsetX.value[0] = 0;
3312                    }
3313
3314                    pLinePoints[2].style = 5;
3315
3316                    if (dMBR / 20 > maxLength * DPIScaleFactor) {
3317                        dMBR = 20 * maxLength * DPIScaleFactor;
3318                    }
3319                    if (dMBR / 20 < minLength * DPIScaleFactor) {
3320                        dMBR = 20 * minLength * DPIScaleFactor;
3321                    }
3322                    if (dMBR > 500 * DPIScaleFactor) {
3323                        dMBR = 500 * DPIScaleFactor;
3324                    }
3325
3326                    double rectWidth = getScaledSize(2, tg.get_LineThickness() / 2.0, tg.get_patternScale());
3327
3328                    pt2 = lineutility.ExtendLineDouble(pt0, pt1, -dMBR / 10);
3329                    bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
3330                    if (bolVertical != 0 && m.value[0] != 0) {
3331                        b = pt2.y + (1 / m.value[0]) * pt2.x;
3332                        b1 = (-1 / m.value[0]) * offsetX.value[0] + b;
3333                        ptYIntercept.x = offsetX.value[0];
3334                        ptYIntercept.y = b1;
3335                        pLinePoints[3] = lineutility.ExtendLineDouble(ptYIntercept, pt2, -rectWidth);
3336                        pLinePoints[3].style = 0;
3337                        pLinePoints[4] = lineutility.ExtendLineDouble(ptYIntercept, pt2, rectWidth);
3338                        pLinePoints[4].style = 0;
3339                    }
3340                    if (bolVertical != 0 && m.value[0] == 0) {
3341                        pLinePoints[3] = new POINT2(pt2);
3342                        pLinePoints[3].y = pt2.y - rectWidth;
3343                        pLinePoints[3].style = 0;
3344                        pLinePoints[4] = new POINT2(pt2);
3345                        pLinePoints[4].y = pt2.y + rectWidth;
3346                        pLinePoints[4].style = 0;
3347                    }
3348                    if (bolVertical == 0) {
3349                        pLinePoints[3] = new POINT2(pt2);
3350                        pLinePoints[3].x = pt2.x - rectWidth;
3351                        pLinePoints[3].style = 0;
3352                        pLinePoints[4] = new POINT2(pt2);
3353                        pLinePoints[4].x = pt2.x + rectWidth;
3354                        pLinePoints[4].style = 0;
3355                    }
3356
3357                    pt2 = lineutility.ExtendLineDouble(pt1, pt0, -dMBR / 10);
3358                    if (bolVertical != 0 && m.value[0] != 0) {
3359                        b = pt2.y + (1 / m.value[0]) * pt2.x;
3360                        //get the Y intercept at x=offsetX
3361                        b1 = (-1 / m.value[0]) * offsetX.value[0] + b;
3362                        ptYIntercept.x = offsetX.value[0];
3363                        ptYIntercept.y = b1;
3364                        pLinePoints[5] = lineutility.ExtendLineDouble(ptYIntercept, pt2, rectWidth);
3365                        pLinePoints[5].style = 0;
3366                        pLinePoints[6] = lineutility.ExtendLineDouble(ptYIntercept, pt2, -rectWidth);
3367                    }
3368                    if (bolVertical != 0 && m.value[0] == 0) {
3369                        pLinePoints[5] = new POINT2(pt2);
3370                        pLinePoints[5].y = pt2.y + rectWidth;
3371                        pLinePoints[5].style = 0;
3372                        pLinePoints[6] = new POINT2(pt2);
3373                        pLinePoints[6].y = pt2.y - rectWidth;
3374                    }
3375                    if (bolVertical == 0) {
3376                        pLinePoints[5] = new POINT2(pt2);
3377                        pLinePoints[5].x = pt2.x + rectWidth;
3378                        pLinePoints[5].style = 0;
3379                        pLinePoints[6] = new POINT2(pt2);
3380                        pLinePoints[6].x = pt2.x - rectWidth;
3381                    }
3382
3383                    pLinePoints[6].style = 0;
3384                    pLinePoints[7] = new POINT2(pLinePoints[3]);
3385                    pLinePoints[7].style = 5;
3386                    lineutility.GetArrowHead4Double(pLinePoints[1], pLinePoints[0], (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 0);
3387                    for (j = 0; j < 3; j++) {
3388                        pLinePoints[8 + j] = new POINT2(pArrowPoints[j]);
3389                    }
3390                    lineutility.GetArrowHead4Double(pLinePoints[1], pLinePoints[2], (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 0);
3391                    for (j = 0; j < 3; j++) {
3392                        pLinePoints[11 + j] = new POINT2(pArrowPoints[j]);
3393                        pLinePoints[11 + j].style = 0;
3394                    }
3395                    acCounter = 14;
3396                    break;
3397                case TacticalLines.DIRATKSPT:
3398                case TacticalLines.INFILTRATION:
3399                    if (lineType == TacticalLines.DIRATKSPT) {
3400                        //reverse the points
3401                        lineutility.ReversePointsDouble2(
3402                                pLinePoints,
3403                                vblSaveCounter);
3404                    }
3405                    if (dMBR / 20 > maxLength * DPIScaleFactor) {
3406                        dMBR = 20 * maxLength * DPIScaleFactor;
3407                    }
3408                    if (dMBR / 20 < minLength * DPIScaleFactor) {
3409                        dMBR = 20 * minLength * DPIScaleFactor;
3410                    }
3411                    if (dMBR < 150 * DPIScaleFactor) {
3412                        dMBR = 150 * DPIScaleFactor;
3413                    }
3414                    if (dMBR > 500 * DPIScaleFactor) {
3415                        dMBR = 500 * DPIScaleFactor;
3416                    }
3417
3418                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 5], pLinePoints[vblCounter - 4], (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 0);
3419                    for (k = 0; k < 3; k++) {
3420                        pLinePoints[vblCounter - k - 1] = new POINT2(pArrowPoints[k]);
3421                    }
3422                    acCounter = vblCounter;
3423                    break;
3424                case TacticalLines.EXPLOIT:
3425                    // Convert arrows to 90 degrees with the hypotenuse distance = distance between pt1 and pt2
3426                    int triBiSector = (int) (lineutility.CalcDistanceDouble(pt1, pt2) / Math.sqrt(2));
3427
3428                    // Arrow at pt1
3429                    lineutility.GetArrowHead4Double(pt1, pt0, triBiSector, triBiSector * 2, pArrowPoints, 0);
3430                    for (k = 0; k < 3; k++) {
3431                        pLinePoints[k+2] = new POINT2(pArrowPoints[k]);
3432                    }
3433
3434                    // Dashed tail at pt2
3435                    lineutility.GetArrowHead4Double(lineutility.ExtendLineDouble(pt0, pt1, 10), pt1, triBiSector, triBiSector * 2, pArrowPoints, 1);
3436                    for (k = 0; k < 3; k++) {
3437                        pLinePoints[k+5] = new POINT2(pArrowPoints[k]);
3438                    }
3439                    acCounter = vblCounter;
3440                    break;
3441                case TacticalLines.ABATIS:
3442                    //must use an x offset for ptYintercept because of extending from it
3443                    pts2 = new POINT2[2];
3444                    pts2[0] = new POINT2(pt0);
3445                    pts2[1] = new POINT2(pt1);
3446                    lineutility.GetPixelsMin(pts2, 2,
3447                            offsetX,
3448                            offsetY);
3449                    if (offsetX.value[0] <= 0) {
3450                        offsetX.value[0] = offsetX.value[0] - 100;
3451                    } else {
3452                        offsetX.value[0] = 0;
3453                    }
3454                    if (dMBR > 300 * DPIScaleFactor) {
3455                        dMBR = 300 * DPIScaleFactor;
3456                    }
3457
3458                    pLinePoints[0] = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], -dMBR / 10);
3459                    bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
3460                    midpt.x = (pt0.x + pLinePoints[0].x) / 2;
3461                    midpt.y = (pt0.y + pLinePoints[0].y) / 2;
3462                    pLinePoints[vblCounter - 3] = new POINT2(pt0);
3463                    pLinePoints[vblCounter - 4].style = 5;
3464                    pLinePoints[vblCounter - 3].style = 0;
3465                    if (bolVertical != 0 && m.value[0] != 0) {
3466                        b = midpt.y + (1 / m.value[0]) * midpt.x;       //the line equation
3467                        //get Y intercept at x=offsetX
3468                        b1 = (-1 / m.value[0]) * offsetX.value[0] + b;
3469                        ptYIntercept.x = offsetX.value[0];
3470                        ptYIntercept.y = b1;
3471                        pLinePoints[vblCounter - 2] = lineutility.ExtendLineDouble(ptYIntercept, midpt, dMBR / 20);
3472                        if (pLinePoints[vblCounter - 2].y >= midpt.y) {
3473                            pLinePoints[vblCounter - 2] = lineutility.ExtendLineDouble(ptYIntercept, midpt, -dMBR / 20);
3474                        }
3475                    }
3476                    if (bolVertical != 0 && m.value[0] == 0) //horizontal line
3477                    {
3478                        pLinePoints[vblCounter - 2] = new POINT2(midpt);
3479                        pLinePoints[vblCounter - 2].y = midpt.y - dMBR / 20;
3480                    }
3481                    if (bolVertical == 0) {
3482                        pLinePoints[vblCounter - 2] = new POINT2(midpt);
3483                        pLinePoints[vblCounter - 2].x = midpt.x - dMBR / 20;
3484                    }
3485                    pLinePoints[vblCounter - 2].style = 0;
3486                    pLinePoints[vblCounter - 1] = new POINT2(pLinePoints[0]);
3487
3488                    //FillPoints(pLinePoints,vblCounter,points);
3489                    acCounter = vblCounter;
3490                    //FillPoints(pLinePoints,acCounter,points);
3491                    break;
3492                case TacticalLines.CLUSTER:
3493                    //must use an x offset for ptYintercept because of extending from it
3494                    pts2 = new POINT2[2];
3495
3496                    //for some reason occulus puts the points on top of one another
3497                    if (Math.abs(pt0.y - pt1.y) < 1) {
3498                        pt1.y = pt0.y + 1;
3499                    }
3500
3501                    pts2[0] = new POINT2(pt0);
3502                    pts2[1] = new POINT2(pt1);
3503
3504                    pts = new POINT2[26];
3505                    dRadius = lineutility.CalcDistanceDouble(pt0, pt1) / 2;
3506                    midpt.x = (pt1.x + pt0.x) / 2;
3507                    midpt.y = (pt1.y + pt0.y) / 2;
3508                    bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
3509                    if (bolVertical != 0 && m.value[0] != 0) //not vertical or horizontal
3510                    {
3511                        b = midpt.y + (1 / m.value[0]) * midpt.x;       //normal y intercept at x=0
3512                        ptYIntercept.x = 0;
3513                        ptYIntercept.y = b;
3514                        pt2 = lineutility.ExtendLineDouble(ptYIntercept, midpt, dRadius);
3515                        if (pLinePoints[0].x <= pLinePoints[1].x) {
3516                            if (pt2.y >= midpt.y) {
3517                                pt2 = lineutility.ExtendLineDouble(ptYIntercept, midpt, -dRadius);
3518                            }
3519                        } else {
3520                            if (pt2.y <= midpt.y) {
3521                                pt2 = lineutility.ExtendLineDouble(ptYIntercept, midpt, -dRadius);
3522                            }
3523                        }
3524
3525                    }
3526                    if (bolVertical != 0 && m.value[0] == 0) //horizontal line
3527                    {
3528                        pt2 = midpt;
3529                        if (pLinePoints[0].x <= pLinePoints[1].x) {
3530                            pt2.y = midpt.y - dRadius;
3531                        } else {
3532                            pt2.y = midpt.y + dRadius;
3533                        }
3534                    }
3535                    if (bolVertical == 0) //vertical line
3536                    {
3537                        pt2 = midpt;
3538                        if (pLinePoints[0].y <= pLinePoints[1].y) {
3539                            pt2.x = midpt.x + dRadius;
3540                        } else {
3541                            pt2.x = midpt.x - dRadius;
3542                        }
3543                    }
3544
3545                    pt1 = lineutility.ExtendLineDouble(midpt, pt2, 100);
3546
3547                    pts[0] = new POINT2(pt2);
3548                    pts[1] = new POINT2(pt1);
3549
3550                    lineutility.ArcArrayDouble(
3551                            pts,
3552                            0, dRadius,
3553                            lineType,
3554                            null);
3555                    pLinePoints[0].style = 1;
3556                    pLinePoints[1].style = 5;
3557                    for (j = 0; j < 26; j++) {
3558                        pLinePoints[2 + j] = new POINT2(pts[j]);
3559                        pLinePoints[2 + j].style = 1;
3560                    }
3561                    acCounter = 28;
3562                    break;
3563                case TacticalLines.FOLLA:
3564                    //reverse the points
3565                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
3566
3567                    if (dMBR / 10 > maxLength * DPIScaleFactor) {
3568                        dMBR = 10 * maxLength * DPIScaleFactor;
3569                    }
3570                    if (dMBR / 10 < minLength * DPIScaleFactor) {
3571                        dMBR = 10 * minLength * DPIScaleFactor;
3572                    }
3573                    if (dMBR > 150 * DPIScaleFactor) {
3574                        dMBR = 150 * DPIScaleFactor;
3575                    }
3576
3577                    pLinePoints[0] = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], -2 * dMBR / 10);
3578
3579                    for (k = 0; k < vblCounter - 14; k++) {
3580                        pLinePoints[k].style = 18;
3581                    }
3582                    pLinePoints[vblCounter - 15].style = 5;
3583
3584                    pt0 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], 5 * dMBR / 10);
3585
3586                    lineutility.GetArrowHead4Double(pt0, pLinePoints[0], (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, 0);
3587                    for (k = 0; k < 3; k++) {
3588                        pLinePoints[vblCounter - 14 + k] = new POINT2(pArrowPoints[k]);
3589                    }
3590
3591                    pt3 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], dMBR / 10);
3592
3593                    lineutility.GetArrowHead4Double(pt0, pt3, (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, 0);
3594                    pLinePoints[vblCounter - 12].style = 0;
3595                    pLinePoints[vblCounter - 11] = new POINT2(pArrowPoints[2]);
3596                    pLinePoints[vblCounter - 11].style = 0;
3597                    pLinePoints[vblCounter - 10] = new POINT2(pArrowPoints[0]);
3598                    pLinePoints[vblCounter - 10].style = 0;
3599                    pLinePoints[vblCounter - 9] = new POINT2(pLinePoints[vblCounter - 14]);
3600                    pLinePoints[vblCounter - 9].style = 5;
3601
3602                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 16], pLinePoints[vblCounter - 15], (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, 0);
3603
3604                    for (k = 0; k < 3; k++) {
3605                        pLinePoints[vblCounter - 8 + k] = new POINT2(pArrowPoints[k]);
3606                    }
3607                    pLinePoints[vblCounter - 6].style = 0;
3608
3609                    //diagnostic to make first point tip of arrowhead    6-14-12
3610                    //pt3 = lineutility.ExtendLineDouble(pLinePoints[vblCounter - 16], pLinePoints[vblCounter - 15], 0.75 * dMBR / 10);
3611                    pt3 = lineutility.ExtendLineDouble(pLinePoints[vblCounter - 16], pLinePoints[vblCounter - 15], -0.75 * dMBR / 10);
3612                    pLinePoints[1] = pt3;
3613                    pLinePoints[1].style = 5;
3614                    //lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 16], pt3, (int) (1.25 * dMBR / 10), (int) (1.25 * dMBR / 10), pArrowPoints, 0);
3615                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 16], pt3, (int) (dMBR / 10), (int) (dMBR / 10), pArrowPoints, 0);
3616                    //end section
3617
3618                    for (k = 0; k < 3; k++) {
3619                        pLinePoints[vblCounter - 5 + k] = new POINT2(pArrowPoints[2 - k]);
3620                    }
3621                    pLinePoints[vblCounter - 5].style = 0;
3622
3623                    pLinePoints[vblCounter - 2] = new POINT2(pLinePoints[vblCounter - 8]);
3624                    pLinePoints[vblCounter - 2].style = 5;
3625                    pLinePoints[vblCounter - 1] = new POINT2(pLinePoints[vblCounter - 7]);
3626                    acCounter = 16;
3627                    break;
3628                case TacticalLines.FOLSP:
3629                    lineutility.ReversePointsDouble2(
3630                            pLinePoints,
3631                            vblSaveCounter);
3632
3633                    if (dMBR / 15 > maxLength * DPIScaleFactor) {
3634                        dMBR = 15 * maxLength * DPIScaleFactor;
3635                    }
3636                    if (dMBR / 15 < minLength * DPIScaleFactor) {
3637                        dMBR = 15 * minLength * DPIScaleFactor;
3638                    }
3639                    if (dMBR < 100 * DPIScaleFactor) {
3640                        dMBR = 100 * DPIScaleFactor;
3641                    }
3642                    if (dMBR > 500 * DPIScaleFactor) {
3643                        dMBR = 500 * DPIScaleFactor;
3644                    }
3645
3646                    //make tail larger 6-10-11 m. Deutch
3647                    pLinePoints[0] = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], -dMBR / 8.75);
3648
3649                    pLinePoints[vblCounter - 15].style = 5;
3650                    pt0 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], dMBR / 4);
3651
3652                    lineutility.GetArrowHead4Double(pt0, pLinePoints[0], (int) dMBR / 20, (int) dMBR / 20,
3653                            pArrowPoints, 0);
3654
3655                    for (k = 0; k < 3; k++) {
3656                        pLinePoints[vblCounter - 14 + k] = new POINT2(pArrowPoints[k]);
3657                    }
3658
3659                    pLinePoints[vblCounter - 12].style = 0;
3660
3661                    //make tail larger 6-10-11 m. Deutch
3662                    pt3 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], dMBR / 15);
3663
3664                    lineutility.GetArrowHead4Double(pt0, pt3, (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 0);
3665
3666                    for (k = 0; k < 3; k++) {
3667                        pLinePoints[vblCounter - 11 + k] = new POINT2(pArrowPoints[2 - k]);
3668                        pLinePoints[vblCounter - 11 + k].style = 0;
3669                    }
3670                    pLinePoints[vblCounter - 8] = new POINT2(pLinePoints[vblCounter - 14]);
3671                    pLinePoints[vblCounter - 8].style = 5;
3672
3673                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 16], pLinePoints[vblCounter - 15], (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 9);
3674
3675                    for (k = 0; k < 3; k++) {
3676                        pLinePoints[vblCounter - 7 + k] = new POINT2(pArrowPoints[k]);
3677                    }
3678                    for (k = 4; k > 0; k--) {
3679                        pLinePoints[vblCounter - k].style = 5;
3680                    }
3681                    acCounter = 12;
3682                    break;
3683                case TacticalLines.FERRY:
3684                    lLinestyle = 9;
3685                    if (dMBR / 10 > maxLength * DPIScaleFactor) {
3686                        dMBR = 10 * maxLength * DPIScaleFactor;
3687                    }
3688                    if (dMBR / 10 < minLength * DPIScaleFactor) {
3689                        dMBR = 10 * minLength * DPIScaleFactor;
3690                    }
3691                    if (dMBR > 250 * DPIScaleFactor) {
3692                        dMBR = 250 * DPIScaleFactor;
3693                    }
3694
3695                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 8], pLinePoints[vblCounter - 7], (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, lLinestyle);
3696                    for (k = 0; k < 3; k++) {
3697                        pLinePoints[vblCounter - 6 + k] = new POINT2(pArrowPoints[k]);
3698                    }
3699                    lineutility.GetArrowHead4Double(pLinePoints[1], pLinePoints[0], (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, lLinestyle);
3700                    for (k = 0; k < 3; k++) {
3701                        pLinePoints[vblCounter - 3 + k] = new POINT2(pArrowPoints[k]);
3702                    }
3703
3704                    acCounter = 8;
3705                    break;
3706                case TacticalLines.NAVIGATION:
3707                    double extensionLength = getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
3708                    pt3 = lineutility.ExtendLine2Double(pt1, pt0, -extensionLength, 0);
3709                    pt4 = lineutility.ExtendLine2Double(pt0, pt1, -extensionLength, 0);
3710
3711                    pt5 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt3, extensionLength, 0);
3712                    pt6 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt3, -extensionLength, 0);
3713                    pt7 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt4, extensionLength, 0);
3714                    pt8 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt4, -extensionLength, 0);
3715                    if (pt5.y < pt6.y) {
3716                        pLinePoints[0] = new POINT2(pt5);
3717                    } else {
3718                        pLinePoints[0] = new POINT2(pt6);
3719                    }
3720                    if (pt7.y > pt8.y) {
3721                        pLinePoints[3] = new POINT2(pt7);
3722                    } else {
3723                        pLinePoints[3] = new POINT2(pt8);
3724                    }
3725                    pLinePoints[1] = new POINT2(pt0);
3726                    pLinePoints[2] = new POINT2(pt1);
3727                    acCounter = 4;
3728                    break;
3729                case TacticalLines.FORTL:
3730                    acCounter = GetFORTLPointsDouble(tg, pLinePoints, vblSaveCounter);
3731                    break;
3732                case TacticalLines.CANALIZE:
3733                    acCounter = DISMSupport.GetDISMCanalizeDouble(pLinePoints, lineType);
3734                    break;
3735                case TacticalLines.BREACH:
3736                    acCounter = DISMSupport.GetDISMBreachDouble(pLinePoints, lineType);
3737                    break;
3738                case TacticalLines.SCREEN:
3739                case TacticalLines.GUARD:
3740                case TacticalLines.COVER:
3741                    if (vblSaveCounter == 4) {
3742                        acCounter = DISMSupport.GetDISMCoverDoubleRevC(pLinePoints, lineType, vblSaveCounter);
3743                    } else {
3744                        acCounter = DISMSupport.GetDISMCoverDouble(pLinePoints, lineType);
3745                    }
3746                    break;
3747                case TacticalLines.SARA:
3748                    acCounter = DISMSupport.GetDISMCoverDouble(pLinePoints, lineType);
3749                    //reorder pLinePoints
3750                    POINT2[] saraPts = new POINT2[16];
3751                    for (j = 0; j < 4; j++) {
3752                        saraPts[j] = pLinePoints[j];  //0-3
3753                    }
3754                    for (j = 4; j < 8; j++) {
3755                        saraPts[j] = pLinePoints[j + 4];    //8-11
3756                    }
3757                    for (j = 8; j < 12; j++) {
3758                        saraPts[j] = pLinePoints[j - 4];    //4-7
3759                    }
3760                    for (j = 12; j < 16; j++) {
3761                        saraPts[j] = pLinePoints[j];  //12-15
3762                    }
3763                    pLinePoints = saraPts;
3764                    //acCounter=14;
3765                    break;
3766                case TacticalLines.DISRUPT:
3767                    acCounter = DISMSupport.GetDISMDisruptDouble(pLinePoints, lineType);
3768                    break;
3769                case TacticalLines.CONTAIN:
3770                    acCounter = DISMSupport.GetDISMContainDouble(pLinePoints, lineType);
3771                    break;
3772                case TacticalLines.PENETRATE:
3773                    DISMSupport.GetDISMPenetrateDouble(pLinePoints, lineType);
3774                    acCounter = 7;
3775                    break;
3776                case TacticalLines.MNFLDBLK:
3777                case TacticalLines.BLOCK:
3778                    DISMSupport.GetDISMBlockDouble2(
3779                            pLinePoints,
3780                            lineType);
3781                    acCounter = 4;
3782                    break;
3783                case TacticalLines.LINTGT:
3784                case TacticalLines.LINTGTS:
3785                case TacticalLines.FPF:
3786                    acCounter = DISMSupport.GetDISMLinearTargetDouble(pLinePoints, lineType, vblCounter);
3787                    break;
3788                case TacticalLines.GAP:
3789                case TacticalLines.ASLTXING:
3790                    DISMSupport.GetDISMGapDouble(
3791                            pLinePoints,
3792                            lineType);
3793                    acCounter = 12;
3794                    break;
3795                case TacticalLines.MNFLDDIS:
3796                    acCounter = DISMSupport.GetDISMMinefieldDisruptDouble(pLinePoints, lineType);
3797                    break;
3798                case TacticalLines.SPTBYFIRE:
3799                    acCounter = DISMSupport.GetDISMSupportByFireDouble(pLinePoints, lineType);
3800                    break;
3801                case TacticalLines.ATKBYFIRE:
3802                    acCounter = DISMSupport.GetDISMATKBYFIREDouble(pLinePoints, lineType);
3803                    break;
3804                case TacticalLines.BYIMP:
3805                    acCounter = DISMSupport.GetDISMByImpDouble(pLinePoints, lineType);
3806                    break;
3807                case TacticalLines.CLEAR:
3808                    acCounter = DISMSupport.GetDISMClearDouble(pLinePoints, lineType);
3809                    break;
3810                case TacticalLines.BYDIF:
3811                    acCounter = DISMSupport.GetDISMByDifDouble(pLinePoints, lineType, clipBounds);
3812                    break;
3813                case TacticalLines.SEIZE:
3814                case TacticalLines.EVACUATE:
3815                    double radius = 0;
3816                    if (vblSaveCounter == 4) {
3817                        radius = lineutility.CalcDistanceDouble(pLinePoints[0], pLinePoints[1]);
3818                        pLinePoints[1] = new POINT2(pLinePoints[3]);
3819                        pLinePoints[2] = new POINT2(pLinePoints[2]);
3820                    }
3821                    acCounter = DISMSupport.GetDISMSeizeDouble(pLinePoints, lineType, radius);
3822                    break;
3823                case TacticalLines.FIX:
3824                case TacticalLines.MNFLDFIX:
3825                    acCounter = DISMSupport.GetDISMFixDouble(pLinePoints, lineType, clipBounds);
3826                    break;
3827                case TacticalLines.RIP:
3828                case TacticalLines.DEMONSTRATE:
3829                    acCounter = DISMSupport.GetDISMRIPDouble(pLinePoints, lineType);
3830                    break;
3831                case TacticalLines.MOBILE_DEFENSE:
3832                    pLinePoints[2] = lineutility.PointRelativeToLine(pt0, pt1, pt1, pt2);
3833                    pLinePoints[3] =  lineutility.PointRelativeToLine(pt0, pt1, pt0, pt2);
3834                    acCounter = DISMSupport.GetDISMRIPDouble(pLinePoints, lineType);
3835                    // Add spikes
3836                    POINT2[] trianglePts = new POINT2[18];
3837                    lineutility.InitializePOINT2Array(trianglePts);
3838                    int l = 0;
3839                    dRadius = lineutility.CalcDistanceDouble(pLinePoints[1], pLinePoints[2]) / 2;
3840                    POINT2 arcCenter = lineutility.MidPointDouble(pLinePoints[1], pLinePoints[2], 0);
3841                    double dLength = Math.abs(dRadius - 20);
3842                    if (dRadius < 40) {
3843                        dLength = dRadius / 1.5;
3844                    }
3845                    if (dRadius > 100) {
3846                        dLength = 0.8 * dRadius;
3847                    }
3848
3849                    POINT2 tmpPt = new POINT2();
3850                    tmpPt.x = arcCenter.x - (long) ((dRadius / dLength) * (arcCenter.x - pLinePoints[10].x));
3851                    tmpPt.y = arcCenter.y - (long) ((dRadius / dLength) * (arcCenter.y - pLinePoints[10].y));
3852                    trianglePts[l] = new POINT2(pLinePoints[10 - 1]);
3853                    trianglePts[l].style = 9;
3854                    l++;
3855                    trianglePts[l] = new POINT2(tmpPt);
3856                    trianglePts[l].style = 9;
3857                    l++;
3858                    trianglePts[l] = new POINT2(pLinePoints[10 + 1]);
3859                    trianglePts[l].style = 9;
3860                    l++;
3861                    trianglePts[l] = new POINT2(pLinePoints[10]);
3862                    trianglePts[l].style = 9;
3863                    l++;
3864                    trianglePts[l] = new POINT2(pLinePoints[10 - 1]);
3865                    trianglePts[l].style = 10;
3866                    l++;
3867
3868                    tmpPt.x = arcCenter.x - (long) ((dRadius / dLength) * (arcCenter.x - pLinePoints[22].x));
3869                    tmpPt.y = arcCenter.y - (long) ((dRadius / dLength) * (arcCenter.y - pLinePoints[22].y));
3870                    trianglePts[l] = new POINT2(pLinePoints[22 - 1]);
3871                    trianglePts[l].style = 9;
3872                    l++;
3873                    trianglePts[l] = new POINT2(tmpPt);
3874                    trianglePts[l].style = 9;
3875                    l++;
3876                    trianglePts[l] = new POINT2(pLinePoints[22 + 1]);
3877                    trianglePts[l].style = 9;
3878                    l++;
3879                    trianglePts[l] = new POINT2(pLinePoints[22]);
3880                    trianglePts[l].style = 9;
3881                    l++;
3882                    trianglePts[l] = new POINT2(pLinePoints[22 - 1]);
3883                    trianglePts[l].style = 10;
3884                    l++;
3885
3886                    double triangleBaseLen = lineutility.CalcDistanceDouble(trianglePts[0], trianglePts[2]);
3887                    double triangleHeight = lineutility.CalcDistanceDouble(trianglePts[1], trianglePts[3]);
3888                    trianglePts[l] = lineutility.ExtendAlongLineDouble(pLinePoints[3], pLinePoints[2], lineutility.CalcDistanceDouble(pt0, pt1) / 8, 9);
3889                    trianglePts[l].style = 9;
3890                    l++;
3891
3892                    trianglePts[l] = lineutility.ExtendAlongLineDouble2(trianglePts[l-1], pLinePoints[2], triangleBaseLen);
3893                    trianglePts[l].style = 9;
3894                    l++;
3895
3896                    trianglePts[l] = lineutility.ExtendDirectedLine(trianglePts[l-2], trianglePts[l-1],
3897                            lineutility.MidPointDouble(trianglePts[l-2], trianglePts[l-1], 0), lineutility.extend_above, triangleHeight);
3898                    trianglePts[l].style = 9;
3899                    l++;
3900
3901                    trianglePts[l] = new POINT2(trianglePts[l-3]);
3902                    trianglePts[l].style = 10;
3903                    l++;
3904
3905                    trianglePts[l] = lineutility.ExtendAlongLineDouble(pLinePoints[0], pLinePoints[1], lineutility.CalcDistanceDouble(pt0, pt1) / 8, 9);
3906                    trianglePts[l].style = 9;
3907                    l++;
3908
3909                    trianglePts[l] = lineutility.ExtendAlongLineDouble2(trianglePts[l-1], pLinePoints[1], triangleBaseLen);
3910                    trianglePts[l].style = 9;
3911                    l++;
3912
3913                    trianglePts[l] = lineutility.ExtendDirectedLine(trianglePts[l-2], trianglePts[l-1],
3914                            lineutility.MidPointDouble(trianglePts[l-2], trianglePts[l-1], 0), lineutility.extend_below, triangleHeight);
3915                    trianglePts[l].style = 9;
3916                    l++;
3917
3918                    trianglePts[l] = new POINT2(trianglePts[l-3]);
3919                    trianglePts[l].style = 10;
3920
3921                    for (j = 0; j < 18; j++) {
3922                        pLinePoints[acCounter] = new POINT2(trianglePts[j]);
3923                        acCounter++;
3924                    }
3925                    break;
3926                case TacticalLines.DELAY:
3927                case TacticalLines.WITHDRAW:
3928                case TacticalLines.DISENGAGE:
3929                case TacticalLines.WDRAWUP:
3930                case TacticalLines.RETIRE:
3931                case TacticalLines.FPOL:
3932                case TacticalLines.RPOL:
3933                case TacticalLines.PURSUIT:
3934                    acCounter = DISMSupport.GetDelayGraphicEtcDouble(pLinePoints, lineType);
3935                    break;
3936                case TacticalLines.ENVELOPMENT:
3937                    acCounter = DISMSupport.GetEnvelopmentGraphicDouble(pLinePoints);
3938                    break;
3939                case TacticalLines.EASY:
3940                    acCounter = DISMSupport.GetDISMEasyDouble(pLinePoints, lineType);
3941                    break;
3942                case TacticalLines.BYPASS:
3943                    acCounter = DISMSupport.GetDISMBypassDouble(pLinePoints, lineType);
3944                    break;
3945                case TacticalLines.AMBUSH:
3946                    acCounter = DISMSupport.AmbushPointsDouble(pLinePoints);
3947                    break;
3948                case TacticalLines.FLOT:
3949                    acCounter = flot.GetFlotDouble(pLinePoints, getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
3950                    break;
3951                default:
3952                    acCounter = vblSaveCounter;
3953                    break;
3954            }
3955            switch (lineType) {
3956                case TacticalLines.BOUNDARY:
3957                    FillPoints(pLinePoints, acCounter, points);
3958                    return points;
3959                case TacticalLines.CONTAIN:
3960                case TacticalLines.BLOCK:
3961                case TacticalLines.COVER:
3962                case TacticalLines.SCREEN:  //note: screen, cover, guard are getting their modifiers before the call to getlinearray
3963                case TacticalLines.GUARD:
3964                case TacticalLines.PAA_RECTANGULAR:
3965                case TacticalLines.RECTANGULAR_TARGET:
3966                case TacticalLines.FOLSP:
3967                case TacticalLines.FOLLA:
3968                //add these for rev c   3-12-12
3969                case TacticalLines.BREACH:
3970                case TacticalLines.BYPASS:
3971                case TacticalLines.CANALIZE:
3972                case TacticalLines.CLEAR:
3973                case TacticalLines.DISRUPT:
3974                case TacticalLines.FIX:
3975                case TacticalLines.ISOLATE:
3976                case TacticalLines.OCCUPY:
3977                case TacticalLines.PENETRATE:
3978                case TacticalLines.RETAIN:
3979                case TacticalLines.SECURE:
3980                case TacticalLines.AREA_DEFENSE:
3981                case TacticalLines.SEIZE:
3982                case TacticalLines.EVACUATE:
3983                case TacticalLines.TURN:
3984                case TacticalLines.BS_RECTANGLE:
3985                case TacticalLines.BBS_RECTANGLE:
3986                //add these
3987                case TacticalLines.AIRFIELD:
3988                case TacticalLines.CORDONKNOCK:
3989                case TacticalLines.CORDONSEARCH:
3990                case TacticalLines.MSDZ:
3991                case TacticalLines.CONVOY:
3992                case TacticalLines.HCONVOY:
3993                case TacticalLines.MFLANE:
3994                case TacticalLines.DIRATKAIR:
3995                case TacticalLines.ABATIS:
3996                case TacticalLines.MOBILE_DEFENSE:
3997                case TacticalLines.ENVELOPMENT:
3998                    FillPoints(pLinePoints, acCounter, points);
3999                    break;
4000                default:
4001                    //if shapes is null then it is a non-CPOF client, dependent upon pixels
4002                    //instead of shapes
4003                    if (shapes == null) {
4004                        FillPoints(pLinePoints, acCounter, points);
4005                        return points;
4006                    }
4007                    break;
4008            }
4009
4010            //the shapes require pLinePoints
4011            //if the shapes are null then it is a non-CPOF client,
4012            if (shapes == null) {
4013                return points;
4014            }
4015
4016            Shape2 shape = null;
4017            Shape gp = null;
4018            Shape2 redShape = null, blueShape = null, paleBlueShape = null, whiteShape = null;
4019            Shape2 redFillShape = null, blueFillShape = null, blackShape = null;
4020            BasicStroke blueStroke, paleBlueStroke;
4021            Area blueArea = null;
4022            Area paleBlueArea = null;
4023            Area whiteArea = null;
4024            boolean beginLine = true;
4025            Polygon poly = null;
4026            POINT2[] secondPoly;
4027
4028            //a loop for the outline shapes
4029            switch (lineType) {
4030                case TacticalLines.PDF:
4031                    // Lines
4032                    addPolyline(pLinePoints, 3, shapes);
4033
4034                    // Rectangle
4035                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4036                    shape.moveTo(pLinePoints[3]);
4037                    for (k = 4; k < 8; k++) {
4038                        shape.lineTo(pLinePoints[k]);
4039                    }
4040                    shapes.add(shape);
4041
4042                    // Arrows
4043                    secondPoly = new POINT2[6];
4044                    for (int i = 0; i < 6; i++) {
4045                        secondPoly[i] = pLinePoints[i + 8];
4046                    }
4047                    addPolyline(secondPoly, 6, shapes);
4048                    break;
4049                case TacticalLines.BBS_AREA:
4050                case TacticalLines.BBS_RECTANGLE:
4051                    shape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4052                    shape.moveTo(pLinePoints[0]);
4053                    for (j = 0; j < vblSaveCounter; j++) {
4054                        shape.lineTo(pLinePoints[j]);
4055                    }
4056                    shapes.add(shape);
4057
4058                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4059                    shape.moveTo(pOriginalLinePoints[0]);
4060                    for (j = 1; j < vblSaveCounter; j++) {
4061                        shape.lineTo(pOriginalLinePoints[j]);
4062                    }
4063                    shapes.add(shape);
4064
4065                    break;
4066                case TacticalLines.DIRATKGND:
4067                    //create two shapes. the first shape is for the line
4068                    //the second shape is for the arrow
4069                    //renderer will know to use a skinny stroke for the arrow shape
4070
4071                    //the line shape
4072                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4073                    shape.moveTo(pLinePoints[0]);
4074                    for (j = 0; j < acCounter - 10; j++) {
4075                        shape.lineTo(pLinePoints[j]);
4076                    }
4077
4078                    shapes.add(shape);
4079
4080                    //the arrow shape
4081                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4082                    shape.moveTo(pLinePoints[acCounter - 10]);
4083
4084                    for (j = 9; j > 0; j--) {
4085                        if (pLinePoints[acCounter - j - 1].style == 5) {
4086                            shape.moveTo(pLinePoints[acCounter - j]);
4087                        } else {
4088                            shape.lineTo(pLinePoints[acCounter - j]);
4089                        }
4090                    }
4091
4092                    shapes.add(shape);
4093                    break;
4094                case TacticalLines.DEPTH_AREA:
4095                    whiteShape = new Shape2(Shape2.SHAPE_TYPE_FILL);//use for symbol
4096                    whiteShape.setFillColor(Color.WHITE);
4097                    BasicStroke whiteStroke = new BasicStroke((float) arraysupport.getScaledSize(28, tg.get_LineThickness(), tg.get_patternScale()));
4098
4099                    blueShape = new Shape2(Shape2.SHAPE_TYPE_FILL);//use for symbol
4100                    blueShape.setFillColor(new Color(30, 144, 255));
4101
4102                    paleBlueStroke = new BasicStroke(whiteStroke.getLineWidth() / 2);
4103                    paleBlueShape = new Shape2(Shape2.SHAPE_TYPE_FILL);//use for symbol
4104                    paleBlueShape.setFillColor(new Color(153, 204, 255));
4105
4106                    poly = new Polygon();
4107
4108                    for (k = 0; k < vblSaveCounter; k++) {
4109                        poly.addPoint((int) pLinePoints[k].x, (int) pLinePoints[k].y);
4110                        if (k == 0) {
4111                            whiteShape.moveTo(pLinePoints[k]);
4112                        } else {
4113                            whiteShape.lineTo(pLinePoints[k]);
4114                        }
4115                    }
4116
4117                    blueArea = new Area(poly);
4118                    blueShape.setShape(blueArea);
4119
4120                    whiteArea = new Area((Shape) whiteStroke.createStrokedShape(poly));
4121                    whiteShape.setShape(lineutility.createStrokedShape(whiteArea));
4122
4123                    paleBlueArea = new Area((Shape) paleBlueStroke.createStrokedShape(poly));
4124                    paleBlueShape.setShape(lineutility.createStrokedShape(paleBlueArea));
4125
4126                    shapes.add(blueShape);
4127                    shapes.add(paleBlueShape);
4128                    shapes.add(whiteShape);
4129                    break;
4130                case TacticalLines.TRAINING_AREA:
4131                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);//use for outline
4132                    redShape.set_Style(1);
4133                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);//use for symbol
4134                    blueShape.set_Style(0);
4135
4136                    redShape.moveTo(pLinePoints[0]);
4137                    for (k = 1; k < vblSaveCounter; k++) {
4138                        redShape.lineTo(pLinePoints[k]);
4139                    }
4140
4141                    beginLine = true;
4142                    for (k = vblSaveCounter; k < acCounter; k++) {
4143                        if (pLinePoints[k].style == 0) {
4144                            if (beginLine) {
4145                                blueShape.moveTo(pLinePoints[k]);
4146                                beginLine = false;
4147                            } else {
4148                                blueShape.lineTo(pLinePoints[k]);
4149                            }
4150                        }
4151                        if (pLinePoints[k].style == 5) {
4152                            blueShape.lineTo(pLinePoints[k]);
4153                            beginLine = true;
4154                        }
4155                    }
4156                    shapes.add(redShape);
4157                    shapes.add(blueShape);
4158                    break;
4159                case TacticalLines.ITD:
4160                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4161                    redShape.setLineColor(Color.RED);
4162                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4163                    blueShape.setLineColor(Color.GREEN);
4164                    for (k = 0; k < acCounter - 1; k++) {
4165                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 5) {
4166                            redShape.moveTo(pLinePoints[k]);
4167                            redShape.lineTo(pLinePoints[k + 1]);
4168                        } else if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 5) {
4169                            blueShape.moveTo(pLinePoints[k]);
4170                            blueShape.lineTo(pLinePoints[k + 1]);
4171                        }
4172                    }
4173                    shapes.add(redShape);
4174                    shapes.add(blueShape);
4175                    tg.set_lineCap(BasicStroke.CAP_BUTT);
4176                    break;
4177                case TacticalLines.SFY:
4178                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4179                    redShape.setLineColor(Color.RED);
4180                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4181                    blueShape.setLineColor(Color.BLUE);
4182                    //flots and spikes (triangles)
4183                    for (k = 0; k < acCounter - 1; k++) {
4184                        if (pLinePoints[k].style == 23) //red flots
4185                        {
4186                            redFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);    //1-3-12
4187                            redFillShape.setFillColor(Color.RED);
4188                            redFillShape.moveTo(pLinePoints[k - 9]);
4189                            for (int l = k - 8; l <= k; l++) {
4190                                redFillShape.lineTo(pLinePoints[l]);
4191                            }
4192                            shapes.add(redFillShape);   //1-3-12
4193                        }
4194                        if (pLinePoints[k].style == 24)//blue spikes
4195                        {
4196                            blueFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);   //1-3-12
4197                            blueFillShape.setFillColor(Color.BLUE);
4198                            blueFillShape.moveTo(pLinePoints[k - 2]);
4199                            blueFillShape.lineTo(pLinePoints[k - 1]);
4200                            blueFillShape.lineTo(pLinePoints[k]);
4201                            shapes.add(blueFillShape);  //1-3-12
4202                        }
4203                    }
4204                    //the corners
4205                    for (k = 0; k < vblSaveCounter; k++) {
4206                        if (k == 0) {
4207                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4208                            redShape.moveTo(pOriginalLinePoints[0]);
4209                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[0], pOriginalLinePoints[1]);
4210                            if (d1 < d) {
4211                                d = d1;
4212                            }
4213
4214                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[0], pOriginalLinePoints[1], d);
4215                            redShape.lineTo(pt0);
4216                        } else if (k > 0 && k < vblSaveCounter - 1) {
4217                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4218                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[k], pOriginalLinePoints[k - 1]);
4219                            if (d1 < d) {
4220                                d = d1;
4221                            }
4222
4223                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[k], pOriginalLinePoints[k - 1], d);
4224                            pt1 = pOriginalLinePoints[k];
4225
4226                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4227                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[k], pOriginalLinePoints[k + 1]);
4228                            if (d1 < d) {
4229                                d = d1;
4230                            }
4231
4232                            pt2 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[k], pOriginalLinePoints[k + 1], d);
4233                            redShape.moveTo(pt0);
4234                            redShape.lineTo(pt1);
4235                            redShape.lineTo(pt2);
4236                        } else //last point
4237                        {
4238                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4239                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[vblSaveCounter - 1], pOriginalLinePoints[vblSaveCounter - 2]);
4240                            if (d1 < d) {
4241                                d = d1;
4242                            }
4243
4244                            redShape.moveTo(pOriginalLinePoints[vblSaveCounter - 1]);
4245                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[vblSaveCounter - 1], pOriginalLinePoints[vblSaveCounter - 2], d);
4246                            redShape.lineTo(pt0);
4247                        }
4248                    }
4249                    //red and blue short segments (between the flots)
4250                    for (k = 0; k < vblCounter - 1; k++) {
4251                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 5) {
4252                            redShape.moveTo(pLinePoints[k]);
4253                            redShape.lineTo(pLinePoints[k + 1]);
4254                        } else if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 5) {
4255                            blueShape.moveTo(pLinePoints[k]);
4256                            blueShape.lineTo(pLinePoints[k + 1]);
4257                        }
4258                    }
4259                    shapes.add(redShape);
4260                    shapes.add(blueShape);
4261                    break;
4262                case TacticalLines.SFG:
4263                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4264                    redShape.setLineColor(Color.RED);
4265                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4266                    blueShape.setLineColor(Color.BLUE);
4267                    for (k = 0; k < acCounter - 1; k++) {
4268                        if (pLinePoints[k].style == 23) //red flots
4269                        {
4270                            redFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);    //1-3-12
4271                            redFillShape.setFillColor(Color.RED);
4272                            redFillShape.moveTo(pLinePoints[k - 9]);
4273                            for (int l = k - 8; l <= k; l++) {
4274                                redFillShape.lineTo(pLinePoints[l]);
4275                            }
4276                            shapes.add(redFillShape);   //1-3-12
4277                        }
4278                        if (pLinePoints[k].style == 24)//blue spikes red outline
4279                        {
4280                            blueFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);   //1-3-12
4281                            blueFillShape.setFillColor(Color.BLUE);
4282                            blueFillShape.moveTo(pLinePoints[k - 2]);
4283                            blueFillShape.lineTo(pLinePoints[k - 1]);
4284                            blueFillShape.lineTo(pLinePoints[k]);
4285                            shapes.add(blueFillShape);   //1-3-12
4286                        }
4287                    }
4288                    //the corners
4289                    for (k = 0; k < vblSaveCounter; k++) {
4290                        if (k == 0) {
4291                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4292                            redShape.moveTo(pOriginalLinePoints[0]);
4293                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[0], pOriginalLinePoints[1]);
4294                            if (d1 < d) {
4295                                d = d1;
4296                            }
4297
4298                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[0], pOriginalLinePoints[1], d);
4299                            redShape.lineTo(pt0);
4300                        } else if (k > 0 && k < vblSaveCounter - 1) {
4301                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4302                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[k], pOriginalLinePoints[k - 1]);
4303                            if (d1 < d) {
4304                                d = d1;
4305                            }
4306
4307                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[k], pOriginalLinePoints[k - 1], d);
4308                            pt1 = pOriginalLinePoints[k];
4309
4310                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4311                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[k], pOriginalLinePoints[k + 1]);
4312                            if (d1 < d) {
4313                                d = d1;
4314                            }
4315
4316                            pt2 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[k], pOriginalLinePoints[k + 1], d);
4317                            redShape.moveTo(pt0);
4318                            redShape.lineTo(pt1);
4319                            redShape.lineTo(pt2);
4320                        } else //last point
4321                        {
4322                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4323                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[vblSaveCounter - 1], pOriginalLinePoints[vblSaveCounter - 2]);
4324                            if (d1 < d) {
4325                                d = d1;
4326                            }
4327
4328                            redShape.moveTo(pOriginalLinePoints[vblSaveCounter - 1]);
4329                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[vblSaveCounter - 1], pOriginalLinePoints[vblSaveCounter - 2], d);
4330                            redShape.lineTo(pt0);
4331                        }
4332                    }
4333                    shapes.add(redShape);
4334                    //the dots
4335                    for (k = 0; k < acCounter; k++) {
4336                        if (pLinePoints[k].style == 22) {
4337                            POINT2[] CirclePoints = new POINT2[8];
4338                            redShape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(3, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4339                            redShape.setFillColor(Color.RED);
4340                            if (redShape != null && redShape.getShape() != null) {
4341                                shapes.add(redShape);
4342                            }
4343                        }
4344                        if (pLinePoints[k].style == 20) {
4345                            POINT2[] CirclePoints = new POINT2[8];
4346                            blueShape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(3, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4347                            blueShape.setFillColor(Color.BLUE);
4348                            if (blueShape != null && blueShape.getShape() != null) {
4349                                shapes.add(blueShape);
4350                            }
4351                        }
4352                    }
4353                    break;
4354                case TacticalLines.USF:
4355                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4356                    redShape.setLineColor(Color.RED);
4357                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4358                    blueShape.setLineColor(Color.BLUE);
4359                    beginLine = true;
4360                    //int color=0;//red
4361                    for (k = 0; k < acCounter - 1; k++) {
4362                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 5) {
4363                            redShape.moveTo(pLinePoints[k]);
4364                            redShape.lineTo(pLinePoints[k + 1]);
4365                            //color=0;
4366                        }
4367                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 19) {
4368                            redShape.moveTo(pLinePoints[k]);
4369                            redShape.lineTo(pLinePoints[k + 1]);
4370                            //color=0;
4371                        }
4372                        if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 5) {
4373                            blueShape.moveTo(pLinePoints[k]);
4374                            blueShape.lineTo(pLinePoints[k + 1]);
4375                            //color=1;
4376                        }
4377                        if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 25) {
4378                            blueShape.moveTo(pLinePoints[k]);
4379                            blueShape.lineTo(pLinePoints[k + 1]);
4380                            //color=1;
4381                        }
4382                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4383                            redShape.moveTo(pLinePoints[k]);
4384                            redShape.lineTo(pLinePoints[k + 1]);
4385                        }
4386
4387                    }
4388                    shapes.add(redShape);
4389                    shapes.add(blueShape);
4390                    break;
4391                case TacticalLines.SF:
4392                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4393                    redShape.setLineColor(Color.RED);
4394                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4395                    blueShape.setLineColor(Color.BLUE);
4396                    redFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4397                    redFillShape.setLineColor(Color.RED);
4398                    redFillShape.setFillColor(Color.RED);
4399                    blueFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4400                    blueFillShape.setLineColor(Color.BLUE);
4401                    blueFillShape.setFillColor(Color.BLUE);
4402                    for (k = 0; k < acCounter - 1; k++) {
4403                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 5) {
4404                            redShape.moveTo(pLinePoints[k]);
4405                            redShape.lineTo(pLinePoints[k + 1]);
4406                        }
4407                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 19) {
4408                            if (redFillShape.getPoints().isEmpty()) {
4409                                redFillShape.moveTo(pLinePoints[k + 9]);
4410                                for (int l = k + 9; l >= k; l--) {
4411                                    redFillShape.lineTo(pLinePoints[l]);
4412                                }
4413                            } else {
4414                                redFillShape.moveTo(pLinePoints[k]);
4415                                for (int l = k; l < k + 10; l++) {
4416                                    redFillShape.lineTo(pLinePoints[l]);
4417                                }
4418                            }
4419                            k+=9;
4420                            shapes.add(redFillShape);
4421                            redFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4422                            redFillShape.setLineColor(Color.RED);
4423                            redFillShape.setFillColor(Color.RED);
4424                        }
4425                        if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 5) {
4426                            blueShape.moveTo(pLinePoints[k]);
4427                            blueShape.lineTo(pLinePoints[k + 1]);
4428                        }
4429                        if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 25) {
4430                            if (blueFillShape.getPoints().isEmpty()) {
4431                                blueFillShape.moveTo(pLinePoints[k + 2]);
4432                                blueFillShape.lineTo(pLinePoints[k + 1]);
4433                                blueFillShape.lineTo(pLinePoints[k]);
4434                            } else {
4435                                blueFillShape.moveTo(pLinePoints[k]);
4436                                blueFillShape.lineTo(pLinePoints[k + 1]);
4437                                blueFillShape.lineTo(pLinePoints[k + 2]);
4438                            }
4439                            shapes.add(blueFillShape);
4440                            blueFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4441                            blueFillShape.setLineColor(Color.BLUE);
4442                            blueFillShape.setFillColor(Color.BLUE);
4443                        }
4444                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4445                            redShape.moveTo(pLinePoints[k]);
4446                            redShape.lineTo(pLinePoints[k + 1]);
4447                        }
4448                    }
4449                    shapes.add(redShape);
4450                    shapes.add(blueShape);
4451                    break;
4452                case TacticalLines.WFG:
4453                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4454                    for (k = 0; k < acCounter - 1; k++) {
4455                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4456                            shape.moveTo(pLinePoints[k]);
4457                            shape.lineTo(pLinePoints[k + 1]);
4458                        }
4459                    }
4460                    shapes.add(shape);
4461
4462                    //the dots
4463                    for (k = 0; k < acCounter; k++) {
4464                        if (pLinePoints[k].style == 20) {
4465                            POINT2[] CirclePoints = new POINT2[8];
4466                            shape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(3, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4467                            if (shape != null && shape.getShape() != null) {
4468                                shapes.add(shape);
4469                            }
4470                        }
4471                    }
4472                    break;
4473                case TacticalLines.FOLLA:
4474                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4475                    shape.set_Style(1); //dashed line
4476                    shape.moveTo(pLinePoints[0]);
4477                    shape.lineTo(pLinePoints[1]);
4478                    shapes.add(shape);
4479
4480                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4481                    shape.set_Style(0); //dashed line
4482                    for (j = 2; j < vblCounter; j++) {
4483                        if (pLinePoints[j - 1].style != 5) {
4484                            shape.lineTo(pLinePoints[j]);
4485                        } else {
4486                            shape.moveTo(pLinePoints[j]);
4487                        }
4488                    }
4489                    shapes.add(shape);
4490                    break;
4491                case TacticalLines.CFG:
4492                    for (k = 0; k < acCounter; k++) {
4493                        if (pLinePoints[k].style == 20) {
4494                            POINT2[] CirclePoints = new POINT2[8];
4495                            shape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(3, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4496                            if (shape != null && shape.getShape() != null) {
4497                                shapes.add(shape);
4498                            }
4499                            continue;
4500                        }
4501                    }
4502                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4503                    for (k = 0; k < acCounter - 1; k++) {
4504                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 0) {
4505                            shape.moveTo(pLinePoints[k]);
4506                            shape.lineTo(pLinePoints[k + 1]);
4507                        }
4508                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 9) {
4509                            shape.moveTo(pLinePoints[k]);
4510                            shape.lineTo(pLinePoints[k + 1]);
4511                        }
4512
4513                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4514                            d = lineutility.CalcDistanceDouble(pLinePoints[k], pLinePoints[k + 1]);
4515                            pt0 = lineutility.ExtendAlongLineDouble(pLinePoints[k], pLinePoints[k + 1], d - arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()));
4516                            shape.moveTo(pLinePoints[k]);
4517                            shape.lineTo(pt0);
4518                        }
4519
4520                        if (pLinePoints[k].style == 0 && k == acCounter - 2) {
4521                            shape.moveTo(pLinePoints[k]);
4522                            shape.lineTo(pLinePoints[k + 1]);
4523                        }
4524                    }
4525                    shapes.add(shape);
4526                    break;
4527                case TacticalLines.PIPE:
4528                    for (k = 0; k < acCounter; k++) {
4529                        if (pLinePoints[k].style == 20) {
4530                            POINT2[] CirclePoints = new POINT2[8];
4531                            shape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4532                            if (shape != null && shape.getShape() != null) {
4533                                shapes.add(shape);
4534                            }
4535                        }
4536                    }
4537                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4538                    for (k = 0; k < acCounter - 1; k++) {
4539                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4540                            shape.moveTo(pLinePoints[k]);
4541                            shape.lineTo(pLinePoints[k + 1]);
4542                        }
4543                    }
4544                    shapes.add(shape);
4545                    break;
4546                case TacticalLines.ATDITCHM:
4547                    for (k = 0; k < acCounter; k++) {
4548                        if (pLinePoints[k].style == 20) {
4549                            POINT2[] CirclePoints = new POINT2[8];
4550                            shape = lineutility.CalcCircleShape(pLinePoints[k], getScaledSize(4, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);//was 3
4551                            if (shape != null && shape.getShape() != null) {
4552                                shapes.add(shape);
4553                            }
4554                            continue;
4555                        }
4556                        if (k < acCounter - 2) {
4557                            if (pLinePoints[k].style != 0 && pLinePoints[k + 1].style == 0) {
4558                                shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4559                                shape.set_Style(pLinePoints[k].style);
4560                                shape.moveTo(pLinePoints[k]);
4561                                shape.lineTo(pLinePoints[k]);
4562                            } else if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 0) {
4563                                shape.moveTo(pLinePoints[k]);
4564                                shape.lineTo(pLinePoints[k + 1]);
4565                            } else if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 10) {
4566                                shape.moveTo(pLinePoints[k]);
4567                                shape.lineTo(pLinePoints[k + 1]);
4568                                shapes.add(shape);
4569                            }
4570                        }
4571                        if (k < acCounter - 2) {
4572                            if (pLinePoints[k].style == 5 && pLinePoints[k + 1].style == 0) {
4573                                shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4574                                shape.set_Style(pLinePoints[k].style);
4575                                shape.moveTo(pLinePoints[k]);
4576                                //shape.lineTo(pLinePoints[k]);
4577                            } else if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 0) {
4578                                shape.lineTo(pLinePoints[k + 1]);
4579                            } else if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4580                                shape.lineTo(pLinePoints[k + 1]);
4581                                shapes.add(shape);
4582                            }
4583                        }
4584                    }//end for
4585                    break;
4586                case TacticalLines.ESR1:
4587                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4588                    shape.set_Style(pLinePoints[0].style);
4589                    shape.moveTo(pLinePoints[0]);
4590                    shape.lineTo(pLinePoints[1]);
4591                    //if(shape !=null && shape.get_Shape() != null)
4592                    shapes.add(shape);
4593                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4594                    shape.set_Style(pLinePoints[2].style);
4595                    shape.moveTo(pLinePoints[2]);
4596                    shape.lineTo(pLinePoints[3]);
4597                    //if(shape !=null && shape.get_Shape() != null)
4598                    shapes.add(shape);
4599                    break;
4600                case TacticalLines.FORDIF:
4601                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4602                    shape.set_Style(pLinePoints[0].style);
4603                    shape.moveTo(pLinePoints[0]);
4604                    shape.lineTo(pLinePoints[1]);
4605                    shape.moveTo(pLinePoints[2]);
4606                    shape.lineTo(pLinePoints[3]);
4607                    shapes.add(shape);
4608                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4609                    shape.set_Style(pLinePoints[4].style);
4610                    shape.moveTo(pLinePoints[4]);
4611                    for (k = 5; k < acCounter; k++) {
4612                        if (pLinePoints[k - 1].style != 5) {
4613                            shape.lineTo(pLinePoints[k]);
4614                        }
4615                    }
4616
4617                    if (shape != null && shape.getShape() != null) {
4618                        shapes.add(shape);
4619                    }
4620                    break;
4621                case TacticalLines.FENCED:
4622                    //first shape is the original points
4623                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4624                    shape.set_Style(points.get(0).style);
4625                    shape.moveTo(points.get(0));
4626                    for (k = 1; k < vblCounter; k++) {
4627                        shape.lineTo(points.get(k));
4628                    }
4629                    if (shape != null && shape.getShape() != null) {
4630                        shapes.add(shape);
4631                    }
4632
4633                    //second shape are the xpoints
4634                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4635                    beginLine = true;
4636                    for (k = vblCounter; k < points.size(); k++) {
4637                        if (beginLine) {
4638                            if (k == 0) {
4639                                shape.set_Style(points.get(k).style);
4640                            }
4641
4642                            if (k > 0) //doubled points with linestyle=5
4643                            {
4644                                if (points.get(k).style == 5 && points.get(k - 1).style == 5) {
4645                                    shape.lineTo(points.get(k));
4646                                }
4647                            }
4648
4649                            shape.moveTo(points.get(k));
4650                            beginLine = false;
4651                        } else {
4652                            shape.lineTo(points.get(k));
4653                            if (points.get(k).style == 5 || points.get(k).style == 10) {
4654                                beginLine = true;
4655                                //unless there are doubled points with style=5
4656                            }
4657                        }
4658                        if (k == points.size() - 1) //non-LC should only have one shape
4659                        {
4660                            if (shape != null && shape.getShape() != null) {
4661                                shapes.add(shape);
4662                            }
4663                        }
4664                    }
4665                    break;
4666                case TacticalLines.AIRFIELD:
4667                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4668                    shape.moveTo(pLinePoints[0]);
4669                    for (k = 1; k < acCounter - 5; k++) {
4670                        shape.lineTo(pLinePoints[k]);
4671                    }
4672
4673                    shapes.add(shape);
4674
4675                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4676                    shape.moveTo(pLinePoints[acCounter - 4]);
4677                    shape.lineTo(pLinePoints[acCounter - 3]);
4678                    shape.moveTo(pLinePoints[acCounter - 2]);
4679                    shape.lineTo(pLinePoints[acCounter - 1]);
4680                    shapes.add(shape);
4681                    break;
4682                case TacticalLines.STRIKWARN:
4683                    addPolyline(pLinePoints, acCounter / 2, shapes);
4684                    secondPoly = new POINT2[acCounter / 2];
4685                    for (int i = 0; i < acCounter / 2; i++) {
4686                        secondPoly[i] = pLinePoints[i + acCounter / 2];
4687                    }
4688                    addPolyline(secondPoly, acCounter / 2, shapes);
4689                    break;
4690                case TacticalLines.DIRATKAIR:
4691                    secondPoly = new POINT2[9];
4692                    for (int i = 0; i < 4 ; i++) {
4693                        secondPoly[i] = pLinePoints[pLinePoints.length - 4 + i];
4694                    }
4695                    addPolyline(secondPoly, 4, shapes); // Main line
4696                    addPolyline(pLinePoints, acCounter - 13, shapes); // Main line extension
4697                    for (int i = 0; i < 9 ; i++) {
4698                        secondPoly[i] = pLinePoints[pLinePoints.length - 13 + i];
4699                    }
4700                    addPolyline(secondPoly, 9, shapes); // Arrow and bowtie
4701                    break;
4702                case TacticalLines.DIRATKSPT:
4703                case TacticalLines.INFILTRATION:
4704                    addPolyline(pLinePoints, acCounter - 3, shapes); // Main line
4705                    secondPoly = new POINT2[3];
4706                    for (int i = 0; i < 3; i++) {
4707                        secondPoly[i] = pLinePoints[pLinePoints.length - 3 + i];
4708                    }
4709                    addPolyline(secondPoly, 3, shapes); // Arrow
4710                    break;
4711                case TacticalLines.EXPLOIT:
4712                    addPolyline(pLinePoints, 2, shapes); // Main line
4713                    secondPoly = new POINT2[3];
4714                    for (int i = 0; i < 3; i++) {
4715                        secondPoly[i] = pLinePoints[i + 2];
4716                    }
4717                    addPolyline(secondPoly, 3, shapes); // Arrow at pt1
4718                    secondPoly = new POINT2[3];
4719                    for (int i = 0; i < 3; i++) {
4720                        secondPoly[i] = pLinePoints[i + 5];
4721                    }
4722                    addPolyline(secondPoly, 3, shapes); // Dashed tail at pt2
4723                    break;
4724                default:
4725                    addPolyline(pLinePoints, acCounter, shapes);
4726                    break;
4727            }//end switch
4728            //a loop for arrowheads with fill
4729            //these require a separate shape for fill
4730            switch (lineType) {
4731                case TacticalLines.AC:
4732                case TacticalLines.SAAFR:
4733                case TacticalLines.MRR:
4734                case TacticalLines.SL:
4735                case TacticalLines.TC:
4736                case TacticalLines.SC:
4737                case TacticalLines.LLTR:
4738                    for (j = 0; j < vblSaveCounter - 1; j++) {
4739                        dMBR = pOriginalLinePoints[j].style;
4740                        acPoints[0] = new POINT2(pOriginalLinePoints[j]);
4741                        acPoints[1] = new POINT2(pOriginalLinePoints[j + 1]);
4742                        lineutility.GetSAAFRFillSegment(acPoints, dMBR);//was dMRR
4743                        shape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4744                        shape.moveTo(acPoints[0]);
4745                        shape.lineTo(acPoints[1]);
4746                        shape.lineTo(acPoints[2]);
4747                        shape.lineTo(acPoints[3]);
4748                        shapes.add(0, shape);
4749                    }
4750                    break;
4751                case TacticalLines.DIRATKAIR:
4752                    //added this section to not fill the bow tie and instead
4753                    //add a shape to close what had been the bow tie fill areas with
4754                    //a line segment for each one
4755                    int outLineCounter = 0;
4756                    POINT2[] ptOutline = new POINT2[4];
4757                    for (k = 0; k < acCounter; k++) {
4758                        if (pLinePoints[k].style == 10) {
4759                            shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4760                            shape.moveTo(pLinePoints[k - 2]);
4761                            shape.lineTo(pLinePoints[k]);
4762                            if (shape != null && shape.getShape() != null) {
4763                                shapes.add(shape);
4764                            }
4765
4766                            //collect these four points
4767                            ptOutline[outLineCounter++] = pLinePoints[k - 2];
4768                            ptOutline[outLineCounter++] = pLinePoints[k];
4769                        }
4770                    }//end for
4771                    break;
4772                case TacticalLines.OFY:
4773                case TacticalLines.OCCLUDED:
4774                case TacticalLines.WF:
4775                case TacticalLines.WFG:
4776                case TacticalLines.WFY:
4777                case TacticalLines.CF:
4778                case TacticalLines.CFY:
4779                case TacticalLines.CFG:
4780                case TacticalLines.SARA:
4781                case TacticalLines.FERRY:
4782                case TacticalLines.EASY:
4783                case TacticalLines.BYDIF:
4784                case TacticalLines.BYIMP:
4785                case TacticalLines.FOLSP:
4786                case TacticalLines.ATDITCHC:
4787                case TacticalLines.ATDITCHM:
4788                case TacticalLines.MNFLDFIX:
4789                case TacticalLines.TURN_REVD:
4790                case TacticalLines.TURN:
4791                case TacticalLines.MNFLDDIS:
4792                case TacticalLines.AREA_DEFENSE:
4793                case TacticalLines.MOBILE_DEFENSE:
4794                    //POINT2 initialFillPt=null;
4795                    for (k = 0; k < acCounter; k++) {
4796                        if (k == 0) {
4797                            if (pLinePoints[k].style == 9) {
4798                                shape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4799                                shape.set_Style(pLinePoints[k].style);
4800                                shape.moveTo(pLinePoints[k]);
4801                            }
4802                        } else //k>0
4803                        {
4804                            if (pLinePoints[k].style == 9 && pLinePoints[k - 1].style != 9) {
4805                                shape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4806                                shape.set_Style(pLinePoints[k].style);
4807                                shape.moveTo(pLinePoints[k]);
4808                            }
4809                            if (pLinePoints[k].style == 9 && pLinePoints[k - 1].style == 9) //9,9,...,9,10
4810                            {
4811                                shape.lineTo(pLinePoints[k]);
4812                            }
4813                        }
4814                        if (pLinePoints[k].style == 10) {
4815                            shape.lineTo(pLinePoints[k]);
4816                            if (shape != null && shape.getShape() != null) {
4817                                if (lineType == TacticalLines.AREA_DEFENSE)
4818                                    shapes.add(shape);
4819                                else
4820                                    shapes.add(0, shape);
4821                            }
4822                        }
4823                    }//end for
4824                    break;
4825                default:
4826                    break;
4827            }
4828        } catch (Exception exc) {
4829            ErrorLogger.LogException(_className, "GetLineArray2Double",
4830                    new RendererException("GetLineArray2Double " + Integer.toString(tg.get_LineType()), exc));
4831        }
4832        return points;
4833    }
4834
4835    private static void addPolyline(POINT2[] pLinePoints, int acCounter, ArrayList<Shape2> shapes) {
4836        Shape2 shape = null;
4837        boolean beginLine = true;
4838        for (int k = 0; k < acCounter; k++) {
4839            //use shapes instead of pixels
4840            if (shape == null) {
4841                shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4842            }
4843
4844            if (beginLine) {
4845
4846                if (k == 0) {
4847                    shape.set_Style(pLinePoints[k].style);
4848                }
4849
4850                if (k > 0) //doubled points with linestyle=5
4851                {
4852                    if (pLinePoints[k].style == 5 && pLinePoints[k - 1].style == 5 && k < acCounter - 1) {
4853                        continue;
4854                    } else if (pLinePoints[k].style == 5 && pLinePoints[k - 1].style == 10) //CF
4855                    {
4856                        continue;
4857                    }
4858                }
4859
4860                if (k == 0 && pLinePoints.length > 1) {
4861                    if (pLinePoints[k].style == 5 && pLinePoints[k + 1].style == 5) {
4862                        continue;
4863                    }
4864                }
4865
4866                shape.moveTo(pLinePoints[k]);
4867                beginLine = false;
4868            } else {
4869                shape.lineTo(pLinePoints[k]);
4870                if (pLinePoints[k].style == 5 || pLinePoints[k].style == 10) {
4871                    beginLine = true;
4872                    //unless there are doubled points with style=5
4873                }
4874            }
4875            if (k == acCounter - 1) //non-LC should only have one shape
4876            {
4877                if (shape != null && shape.getShape() != null) {
4878                    shapes.add(shape);
4879                }
4880            }
4881        }//end for
4882    }
4883
4884    /**
4885     * Returns which side of the line segment the arrow(s) go on for supply routes
4886     */
4887    public static int SupplyRouteArrowSide(POINT2 pt0, POINT2 pt1) {
4888        ref<double[]> m = new ref();
4889        int bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
4890        if (pt0.x < pt1.x) {
4891            if (m.value[0] < 1) {
4892               return 2;
4893            }
4894            if (m.value[0] >= 1) {
4895                return 1;
4896            }
4897        } else if (pt0.x > pt1.x) {
4898            if (m.value[0] < 1) {
4899                return 3;
4900            }
4901            if (m.value[0] >= 1) {
4902                return 0;
4903            }
4904        } else if (bolVertical == 0) {
4905            if (pt0.y > pt1.y) {
4906             return 0;
4907            } else {
4908                return 1;
4909            }
4910        }
4911        return 0;
4912    }
4913
4914    public static double getScaledSize(double originalSize, double lineWidth, double patternScale) {
4915        if (lineWidth <= 3) { // Default line width
4916            return originalSize;
4917        } else if (lineWidth > 100) {
4918            lineWidth = 100; // Max scale size
4919        }
4920        return originalSize * (1 + ((lineWidth - 3) / 2) * patternScale);
4921    }
4922}