001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005
006package armyc2.c2sd.JavaLineArray;
007import armyc2.c2sd.renderer.utilities.ErrorLogger;
008import armyc2.c2sd.renderer.utilities.RendererException;
009
010/**
011 * A class for calculating flot ellipses. Some functions use the same array for the client points
012 * and the return points. The caller allocates a size large enough to hold the return points.
013 *
014 * @author Michael Deutch
015 */
016public final class flot {
017    private static final String _className = "flot";
018    protected static int GetAnchorageFlotSegment(int[] vbPoints,
019            int x1,
020            int y1,
021            int x2,
022            int y2,
023            int segment,
024            int[] points,
025            ref<int[]>bFlip,
026            ref<int[]>lDirection,
027            ref<int[]>lLastDirection)
028    {
029        int lSegCounter = 0;
030        try {
031            int j = 0;
032            double dDistance = 0;
033            int nNumSegs = 0, m = 0;
034            int lLocx = 0, lLocy = 0;
035            double dAngle = 0;
036            int[] arcPoints = new int[30];
037            double dRemainder = 0;
038            double dNum = 0, dDen = 0;
039
040            if (segment == 0 && vbPoints[0] >= vbPoints[2]) {
041                bFlip.value[0] = 1;//TRUE;
042            }
043            if (segment == 0 && vbPoints[0] < vbPoints[2]) {
044                bFlip.value[0] = 0;//FALSE;
045            }
046
047            dNum = vbPoints[2 * segment + 3] - vbPoints[2 * segment + 1];
048            dDen = vbPoints[2 * segment + 2] - vbPoints[2 * segment];
049
050            //for some reason this did not blow up before I put the if/else
051            //instead it would assign pi/2 to dAngle when dDen=0
052            if (dDen == 0) {
053                dAngle = Math.PI / 2;
054            } else {
055                dAngle = Math.abs(Math.atan(dNum / dDen));
056            }
057
058            //convert to degrees
059            dAngle = (180 / Math.PI) * dAngle;
060
061            if (vbPoints[2 * segment + 0] <= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] >= vbPoints[2 * segment + 3]) {
062                dAngle = 90 - dAngle;
063            } else if (vbPoints[2 * segment + 0] <= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] <= vbPoints[2 * segment + 3]) {
064                dAngle = dAngle + 90;
065            } else if (vbPoints[2 * segment + 0] >= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] <= vbPoints[2 * segment + 3]) {
066                dAngle = 270 - dAngle;
067            } else if (vbPoints[2 * segment + 0] >= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] >= vbPoints[2 * segment + 3]) {
068                dAngle = 270 + dAngle;
069            }
070
071            dDistance = lineutility.CalcDistance2(x1, y1, x2, y2);
072
073            nNumSegs = (int) (dDistance / 20);
074            if (nNumSegs % 2 == 0) {
075                nNumSegs -= 1;
076            }
077
078            dRemainder = nNumSegs * 20 - dDistance;
079            dDistance = dDistance + dRemainder;
080
081            //calculate the default dAngle here
082            //also establish the lDirection
083            if (vbPoints[2 * segment] >= vbPoints[2 * segment + 2]) {
084                dAngle = dAngle + 90;
085                lDirection.value[0] = 1;
086            } else {
087                dAngle = dAngle - 90;
088                lDirection.value[0] = 0;
089            }
090
091            if (segment > 0 && lDirection.value[0] != lLastDirection.value[0]) {
092                //'toggle bflip if the lDirection changes
093                if (bFlip.value[0] == 1) {
094                    bFlip.value[0] = 0;
095                } else {
096                    bFlip.value[0] = 1;
097                }
098            }
099
100            //'flip the segment if necessary
101            if (bFlip.value[0] == 1) {
102                dAngle = dAngle + 180;
103            }
104
105            //for( m = 0; m< nNumSegs;m++)
106            for (m = 0; m < nNumSegs; m += 2) //get evry other flot only for anchorage
107            {
108                lLocx = (int) (x1 + (m + 0.5) * (x2 - x1) * 20 / dDistance);
109                lLocy = (int) (y1 + (m + 0.5) * (y2 - y1) * 20 / dDistance);
110
111                CalcAnglePoints(lLocx, lLocy, dAngle, arcPoints, dDistance / ((double) nNumSegs * 2d));
112
113                for (j = 0; j < 30; j++) {
114                    points[lSegCounter] = arcPoints[j];
115                    lSegCounter++;
116                }
117            }
118
119            //save last lDirection
120            lLastDirection.value[0] = lDirection.value[0];
121            arcPoints = null;
122        } catch (Exception exc) {
123            ErrorLogger.LogException(_className ,"GetAnchorageFlotSegment",
124                    new RendererException("Failed inside GetAnchorageFlotSegment", exc));
125        }
126        return lSegCounter;
127    }
128
129    protected static int GetAnchorageCountDouble(POINT2[] vbPoints, int numPts) {
130        int lTotalpts = 0;
131        try {
132            //declarations
133            int j = 0, lNumSegs = 0;
134            double dDistance = 0;
135            POINT2[] vbPoints2 = null;
136            //end declarations
137
138            vbPoints2 = new POINT2[numPts];
139            for (j = 0; j < numPts; j++) {
140                vbPoints2[j] = new POINT2(vbPoints[j]);
141            }
142            for (j = 0; j < numPts - 1; j++) {
143                dDistance = lineutility.CalcDistanceDouble(vbPoints2[j], vbPoints2[j + 1]);
144                lNumSegs = (int) (dDistance / 20);   //flot diameter is 20
145                if (lNumSegs > 0) {
146                    lTotalpts += lNumSegs * 12; //10 points per flot + 2 end points for line
147                } else {
148                    lTotalpts += 1;
149                }
150            }
151            lTotalpts += 1;
152
153        } catch (Exception exc) {
154            ErrorLogger.LogException(_className ,"GetAnchorageCountDouble",
155                    new RendererException("Failed inside GetAnchorageCountDouble", exc));
156        }
157        return (lTotalpts);
158    }
159    protected static int GetFlotCount2Double(POINT2[] vbPoints, int numPts, int lineType) {
160        int lTotalpts = 0;
161        try {
162            int j = 0, lNumSegs = 0;
163            double dDistance = 0, dIncrement = 0;
164            int nFactor = 10;
165
166            switch (lineType) {
167                case TacticalLines.WF:
168                case TacticalLines.UWF:
169                    dIncrement = 40d;
170                    break;
171                case TacticalLines.WFG:
172                    dIncrement = 60d;
173                    nFactor = 17;
174                    break;
175                case TacticalLines.WFY:
176                    dIncrement = 60d;
177                    nFactor = 20;
178                    break;
179                default:
180                    dIncrement = 20d;
181                    break;
182            }
183
184            for (j = 0; j < numPts - 1; j++) {
185                dDistance = lineutility.CalcDistanceDouble(vbPoints[j], vbPoints[j + 1]);
186                lNumSegs = (int) (dDistance / dIncrement);   //flot diameter is 20
187                lTotalpts = lTotalpts + lNumSegs * nFactor; //10 points per flot
188                switch (lineType) {
189                    case TacticalLines.WFG:
190                    case TacticalLines.WFY:
191                        if (lNumSegs == 0) {
192                            lTotalpts += 2;     //add 2 points for the line segment
193                        }
194                        break;
195                    default:
196                        break;
197                }
198
199            }
200        } catch (Exception exc)
201        {
202            ErrorLogger.LogException(_className ,"GetFlotCount2Double",
203                    new RendererException("Failed inside GetFlotCount2Double", exc));
204        }
205        return lTotalpts;
206    }
207
208    protected static int GetFlot2Double(POINT2[] vbPoints2, int numPts, int lineType) {
209        int lFlotCounter = 0;
210        try {
211            int j = 0, k = 0, l = 0;
212            int x1 = 0, y1 = 0;
213            int x2 = 0, y2 = 0, z2 = 0;
214            int numSegPts = -1;
215            int z = 0, lFlotCount = 0;
216            int lNumSegs = 0;
217            double dDistance = 0;
218            int[] vbPoints = null;
219            int[] points = null;
220            double dIncrement = 0;
221            POINT2[] style10Points = null;
222            int style10Counter = 0;
223            POINT2 pt0 = new POINT2(), pt1 = new POINT2(), pt2 = new POINT2();
224            POINT2 crossPt1 = new POINT2(), crossPt2 = new POINT2();
225            ref<int[]> bFlip = new ref();
226            ref<int[]> lDirection = new ref();
227            ref<int[]> lLastDirection = new ref();
228
229            bFlip.value=new int[1];
230            lDirection.value=new int[1];
231            lLastDirection.value=new int[1];
232            bFlip.value[0] = -1;
233            lDirection.value[0] = -1;
234            lLastDirection.value[0] = -1;
235            lFlotCount = GetFlotCount2Double(vbPoints2, numPts, lineType);
236            if (lFlotCount <= 0) {
237                return 0;
238            }
239
240            style10Points = new POINT2[lFlotCount];
241            lineutility.InitializePOINT2Array(style10Points);
242            vbPoints = new int[2 * numPts];
243            switch (lineType) {
244                case TacticalLines.WF:
245                case TacticalLines.UWF:
246                    dIncrement = 40;
247                    break;
248                case TacticalLines.WFG:
249                case TacticalLines.WFY:
250                    dIncrement = 60;
251                    break;
252                default:
253                    dIncrement = 20;
254                    break;
255            }
256            for (j = 0; j < numPts; j++)
257            {
258                vbPoints[k] = (int) vbPoints2[j].x;
259                k++;
260                vbPoints[k] = (int) vbPoints2[j].y;
261                k++;
262            }
263            k = 0;
264            //assume caller has dimensioned flotppoints
265            j = 0;
266            //every lSegment has 2 points
267            for (l = 0; l < numPts - 1; l++)
268            {
269                dDistance = lineutility.CalcDistance2(vbPoints[2 * l], vbPoints[2 * l + 1], vbPoints[2 * l + 2], vbPoints[2 * l + 3]);
270                lNumSegs = (int) (dDistance / dIncrement);
271                if (lNumSegs > 0) {
272                    points = new int[lNumSegs * 30];
273                    numSegPts = GetFlotSegment2(vbPoints, l, points, lineType, bFlip, lDirection, lLastDirection);
274                    for (j = 0; j < numSegPts; j++) {
275                        x1 = points[k];
276                        y1 = points[k + 1];
277                        z = points[k + 2];
278                        pt0.x = x1;
279                        pt0.y = y1;
280                        pt0.style = z;
281                        if (j < numSegPts - 1) {        //used by WFZ, WFY only
282                            x2 = points[k + 3];
283                            y2 = points[k + 4];
284                            z2 = points[k + 5];
285                            pt1.x = x2;
286                            pt1.y = y2;
287                            pt1.style = z2;
288                        }
289                        k += 3;
290                        if (lFlotCounter < lFlotCount) {
291                            vbPoints2[lFlotCounter].x = x1;
292                            vbPoints2[lFlotCounter].y = y1;
293                            switch (lineType) {
294                                case TacticalLines.WF:
295                                case TacticalLines.WFG:
296                                case TacticalLines.WFY:
297                                    if ((lFlotCounter + 1) % 10 == 0) {
298                                        vbPoints2[lFlotCounter].style = 10;
299                                        //style10Points are used by WFG and WFY for the mid-segment features
300                                        if (j < numSegPts - 1) {
301                                            style10Points[style10Counter] = new POINT2(vbPoints2[lFlotCounter]);
302                                            style10Points[style10Counter].style = 0;
303                                            style10Counter++;
304                                            if (j < numSegPts - 2)
305                                            {
306                                                if (lineType == TacticalLines.WFG) {
307                                                    pt2 = new POINT2(style10Points[style10Counter - 1]);
308                                                    style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 10, 5);
309                                                    style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 20, 20);
310                                                    style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 30, 0);
311                                                    style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 70, 5);
312                                                }
313                                                if (lineType == TacticalLines.WFY) {
314                                                    pt2 = new POINT2(style10Points[style10Counter - 1]);
315                                                    style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 10, 5);       //pt before 1st break
316                                                    style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 15, 0);       //1st pt after 1st break;
317                                                    crossPt1 = lineutility.ExtendDirectedLine(style10Points[style10Counter - 1], pt1, style10Points[style10Counter - 1], 3, 5, 0);
318                                                    style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 25, 5);       //2nd point after 1st break;
319                                                    crossPt2 = lineutility.ExtendDirectedLine(style10Points[style10Counter - 1], pt1, style10Points[style10Counter - 1], 2, 5, 5);
320                                                    style10Points[style10Counter++] = new POINT2(crossPt1);
321                                                    style10Points[style10Counter++] = new POINT2(crossPt2);
322                                                    style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 30, 0);       //1st pt after 2nd break
323                                                    style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 60, 5);       //2nd pt after 2nd break
324                                                }
325                                            }
326                                        } else {
327                                            pt2.x = vbPoints[2 * l];
328                                            pt2.y = vbPoints[2 * l + 1];
329                                            pt2.style = 0;
330                                            style10Points[style10Counter++] = new POINT2(pt2);
331                                            style10Points[style10Counter++] = lineutility.ExtendAlongLineDouble(pt2, pt1, 40, 5);
332
333                                            pt2.x = vbPoints[2 * l + 2];
334                                            pt2.y = vbPoints[2 * l + 3];
335                                            pt2.style = 5;
336                                            style10Points[style10Counter] = new POINT2(vbPoints2[lFlotCounter]);
337                                            style10Points[style10Counter++].style = 0;
338                                            style10Points[style10Counter++] = new POINT2(pt2);
339                                        }
340                                    } else {
341                                        vbPoints2[lFlotCounter].style = 9;
342                                    }
343                                    break;
344                                default:
345                                    vbPoints2[lFlotCounter].style = 0;
346                                    break;
347                            }
348                            lFlotCounter++;
349                        }
350                    }
351                    switch (lineType)
352                    {
353                        case TacticalLines.WF:
354                        case TacticalLines.WFG:
355                        case TacticalLines.WFY:
356                            vbPoints2[lFlotCounter - 1].style = 10;
357                            break;
358                        default:
359                            vbPoints2[lFlotCounter - 1].style = 5;
360                            break;
361                    }
362                    k = 0;
363                    points = null;
364                }//end if numsegs>0
365                else
366                {
367                    style10Points[style10Counter].x = vbPoints[2 * l];
368                    style10Points[style10Counter].y = vbPoints[2 * l + 1];
369                    style10Points[style10Counter++].style = 0;
370                    style10Points[style10Counter].x = vbPoints[2 * l + 2];
371                    style10Points[style10Counter].y = vbPoints[2 * l + 3];
372                    style10Points[style10Counter++].style = 5;
373                }
374            }
375
376
377            //some do not need additional processing
378            switch (lineType) {
379                case TacticalLines.WFG:
380                case TacticalLines.WFY:
381                    break;
382                default:
383                    vbPoints = null;
384                    return lFlotCounter;
385            }
386            for (j = 0; j < style10Counter; j++)
387            {
388                vbPoints2[lFlotCounter++] = new POINT2(style10Points[j]);
389            }
390
391        } catch (Exception exc) {
392            ErrorLogger.LogException(_className ,"GetFlot2Double",
393                    new RendererException("Failed inside GetFlot2Double", exc));
394        }
395        return lFlotCounter;
396    }
397
398    private static int GetFlotSegment2(int[] vbPoints,
399            int segment,
400            int[] points,
401            int lineType,
402            ref<int[]> bFlip,
403            ref<int[]> lDirection,
404            ref<int[]> lLastDirection) {
405        int nNumSegs = 0;
406        try {
407            int j = 0;
408            double dDistance = 0;
409            int m = 0;
410            int lLocx = 0, lLocy = 0;
411            int lSegCounter = 0;
412            double dAngle = 0;
413            int[] arcpoints = new int[30];
414            double dRemainder = 0;
415            double dNum = 0, dDen = 0;
416            double dIncrement = 0;
417            //end declarations
418
419            switch (lineType) {
420                case TacticalLines.WF:
421                case TacticalLines.UWF:
422                    dIncrement = 40;
423                    break;
424                case TacticalLines.WFG:
425                case TacticalLines.WFY:
426                    dIncrement = 60;
427                    break;
428                case TacticalLines.OCCLUDED:
429                case TacticalLines.UOF:
430                    dIncrement = 50;
431                    break;
432                case TacticalLines.SF:
433                    dIncrement = 50;
434                    break;
435                case TacticalLines.USF:
436                case TacticalLines.SFG:
437                case TacticalLines.SFY:
438                    dIncrement = 80;
439                    break;
440                case TacticalLines.OFY:
441                    dIncrement = 80;
442                    break;
443                default:
444                    dIncrement = 20;
445                    break;
446            }
447
448            lSegCounter = 0;
449            if (segment == 0 && vbPoints[0] >= vbPoints[2])
450            {
451                if (lineType != TacticalLines.SF &&
452                        lineType != TacticalLines.USF &&
453                        lineType != TacticalLines.SFG &&
454                        lineType != TacticalLines.SFY) {
455                    bFlip.value[0] = 1;//TRUE;
456                } 
457                else
458                {
459                    bFlip.value[0] = 0;
460                }
461            }
462            if (segment == 0 && vbPoints[0] < vbPoints[2]) {
463                if (lineType !=  TacticalLines.SF &&
464                        lineType != TacticalLines.USF &&
465                        lineType != TacticalLines.SFG &&
466                        lineType != TacticalLines.SFY) {
467                    bFlip.value[0] = 0;//FALSE;
468                } else {
469                    bFlip.value[0] = 1;
470                }
471            }
472
473            dNum = vbPoints[2 * segment + 3] - vbPoints[2 * segment + 1];
474            dDen = vbPoints[2 * segment + 2] - vbPoints[2 * segment];
475
476            if (dDen == 0) {
477                dAngle = Math.PI / 2;
478            } else {
479                dAngle = Math.abs(Math.atan(dNum / dDen));
480            }
481
482            dAngle = (180 / Math.PI) * dAngle;
483
484            if (vbPoints[2 * segment + 0] <= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] >= vbPoints[2 * segment + 3]) {
485                dAngle = 90 - dAngle;
486            } else if (vbPoints[2 * segment + 0] <= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] <= vbPoints[2 * segment + 3]) {
487                dAngle = dAngle + 90;
488            } else if (vbPoints[2 * segment + 0] >= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] <= vbPoints[2 * segment + 3]) {
489                dAngle = 270 - dAngle;
490            } else if (vbPoints[2 * segment + 0] >= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] >= vbPoints[2 * segment + 3]) {
491                dAngle = 270 + dAngle;
492            }
493
494
495            dDistance = lineutility.CalcDistance2(vbPoints[2 * segment], vbPoints[2 * segment + 1], vbPoints[2 * segment + 2], vbPoints[2 * segment + 3]);
496
497            nNumSegs = (int) (dDistance / dIncrement);
498            dRemainder = nNumSegs * dIncrement - dDistance;
499            dDistance = dDistance + dRemainder;
500
501            //calculate the default dAngle here
502            //also establish the lDirection
503            if (vbPoints[2 * segment] >= vbPoints[2 * segment + 2]) {
504                dAngle = dAngle + 90;
505                lDirection.value[0] = 1;
506            } else {
507                dAngle = dAngle - 90;
508                lDirection.value[0] = 0;
509            }
510
511
512            if (segment > 0 && lDirection.value[0] != lLastDirection.value[0]) {
513                //toggle bflip if the lDirection changes
514                if (bFlip.value[0] == 1) {
515                    bFlip.value[0] = 0;
516                } else {
517                    bFlip.value[0] = 1;
518                }
519            }
520
521            //flip the segment if necessary
522            if (bFlip.value[0] == 1) {
523                dAngle = dAngle + 180;
524            }
525
526            for (m = 0; m < nNumSegs; m++) {
527                lLocx = (int) (vbPoints[2 * segment] + (m + 0.5) * (vbPoints[2 * segment + 2] - vbPoints[2 * segment]) * dIncrement / dDistance);
528                lLocy = (int) (vbPoints[2 * segment + 1] + (m + 0.5) * (vbPoints[2 * segment + 3] - vbPoints[2 * segment + 1]) * dIncrement / dDistance);
529
530                CalcAnglePoints(lLocx, lLocy, dAngle, arcpoints, 10);
531
532                for (j = 0; j < 30; j++) {
533                    points[lSegCounter] = arcpoints[j];
534                    lSegCounter = lSegCounter + 1;
535                }
536            }
537
538            //save last lDirection
539            lLastDirection.value[0] = lDirection.value[0];
540            arcpoints = null;
541        } catch (Exception exc) {
542            ErrorLogger.LogException(_className ,"GetFlotSegment2",
543                    new RendererException("Failed inside GetFlotSegment2", exc));
544        }
545        return nNumSegs * 10;
546    }
547    protected static int GetOFYCountDouble(POINT2[] pLinePoints, int numPts, int lineType) {
548        int lTotalpts = 0;
549        try {
550            int j = 0, lNumSegs = 0;
551            int lNumFlots = 0, lNumSpikes = 0;
552            double dDistance = 0;
553            int nFactor = 3;
554            int interval = 50;
555
556            if (lineType == (int) TacticalLines.OFY) {
557                interval = 80;
558                nFactor = 7;
559            }
560
561            //for each segment
562            for (j = 0; j < numPts - 1; j++) {
563                dDistance = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
564                lNumSegs = (int) (dDistance / interval);   //flot + spike = 60 pixels
565                lNumFlots = lNumSegs;
566                lNumSpikes = lNumSegs;
567                if (lNumFlots < 1) {
568                    lNumFlots = 1;
569                }
570                if (lNumSpikes < 1) {
571                    lNumSpikes = 1;
572                }
573                lTotalpts += lNumFlots * 18; //10 points per flot + 8 per line segment,
574                lTotalpts += lNumSpikes * nFactor; //3 points per spike
575            }
576            if (lTotalpts < (nFactor + 15) * numPts) {
577                lTotalpts = 25 * numPts;
578            }
579
580        } catch (Exception exc) {
581            ErrorLogger.LogException(_className ,"GetOFYCountDoulbe",
582                    new RendererException("Failed inside GetOFYCountDouble", exc));
583        }
584        return lTotalpts;
585    }
586
587    protected static int GetOccludedPointsDouble(POINT2[] pLinePoints,
588            int numPts,
589            int lineType)
590    {
591        int nTotalCounter = 0;
592        try
593        {
594            int j = 0, k = 0, lNumSegs = 0, l = 0;
595            int lNumFlots = 0, lNumSpikes = 0;
596            double dDistance = 0;
597            ref<double[]> m = new ref();
598            int lTotalPoints = 0;
599            int[] points = null;
600            POINT2[] pSpikePoints = null;
601            POINT2 pt0 = new POINT2(), tempPoint = new POINT2();
602            POINT2[] pFlotPoints = null;
603            double dSpikeSize = 20, dIncrement = 50;
604            int[] vbPoints = null;
605            int nFlotCounter = 0, nSpikeCounter = 0;
606            int[] flots = null;
607            int sumOfFlots = 0;
608            double segmentLength = 0, spikeLength = 0;
609            int bolTooLong = 0;
610            double d1 = 0, d2 = 0;
611            int bolVertical = 0;
612            ref<int[]> bFlip = new ref();
613            ref<int[]> lDirection = new ref();
614            ref<int[]> lLastDirection = new ref();
615
616            m.value = new double[1];
617            bFlip.value = new int[1];
618            lDirection.value = new int[1];
619            lLastDirection.value = new int[1];
620            bFlip.value[0] = -1;
621            lDirection.value[0] = -1;
622            lLastDirection.value[0] = -1;
623            lTotalPoints = GetOccludedCountDouble(pLinePoints, numPts);
624
625            vbPoints = new int[numPts * 2];
626
627            pSpikePoints = new POINT2[3 * lTotalPoints / 13];
628            pFlotPoints = new POINT2[10 * lTotalPoints / 13];
629            int n=pSpikePoints.length;
630            //for (j = 0; j < pSpikePoints.length; j++)
631            for (j = 0; j < n; j++)
632            {
633                pSpikePoints[j] = new POINT2(pLinePoints[0]);
634                pSpikePoints[j].style = 5;
635            }
636            n=pFlotPoints.length;
637            //for (j = 0; j < pFlotPoints.length; j++)
638            for (j = 0; j < n; j++)
639            {
640                pFlotPoints[j] = new POINT2(pLinePoints[0]);
641                pFlotPoints[j].style = 5;
642            }
643            flots = new int[numPts + 1];
644            //the vbPoints long array gets used by GetFlotSegment
645            //and is based on the original points
646            for (j = 0; j < numPts; j++) {
647                vbPoints[k] = (int) pLinePoints[j].x;
648                k++;
649                vbPoints[k] = (int) pLinePoints[j].y;
650                k++;
651            }
652            k = 0;
653            //initialize flots
654            flots[0] = 0;
655            for (j = 0; j < numPts; j++)
656            {
657                flots[j + 1] = 0;
658            }
659
660            for (j = 0; j < numPts - 1; j++) {
661                bolVertical = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
662                m.value[0] = -m.value[0];       //reverse the direction
663                dDistance = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
664                lNumSegs = (int) (dDistance / dIncrement);   //flot(20) + spike(20) = 60 pixels
665                lNumFlots = lNumSegs;
666                lNumSpikes = lNumSegs;
667                flots[j + 1] = lNumSegs;
668
669                //get the flot segments for this line segment
670                //flot segments are 30 pixels wide with the flots in the middle, 20 pixels wide
671                k = 0;
672                if (lNumFlots > 0) {
673                    points = new int[lNumFlots * 30];
674                    GetFlotSegment2(vbPoints, j, points, lineType, bFlip, lDirection, lLastDirection);
675                    for (l = 0; l < lNumFlots * 10; l++)
676                    {
677                        pFlotPoints[nFlotCounter].x = points[k];
678                        pFlotPoints[nFlotCounter].y = points[k + 1];
679                        pFlotPoints[nFlotCounter].style = 9;
680                        //straighten out the flots
681                        if ((nFlotCounter) % 10 == 0)
682                        {
683                            d1 = lineutility.CalcDistanceDouble(pLinePoints[j], pFlotPoints[nFlotCounter]);
684                            d2 = lineutility.CalcDistanceDouble(pLinePoints[j + 1], pFlotPoints[nFlotCounter]);
685                            if (d2 > d1)
686                            {
687                                pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j + 1], pLinePoints[j], -d1);
688                            } 
689                            else
690                            {
691                                pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j], pLinePoints[j + 1], -d2);
692                            }
693                            pFlotPoints[nFlotCounter].style = 9;
694                            if (lineType == (long) TacticalLines.UOF) {
695                                pFlotPoints[nFlotCounter].style = 0;
696                            }
697                        }
698
699                        if ((nFlotCounter + 1) % 10 == 0) {
700                            if (lineType == (long) TacticalLines.OCCLUDED ||
701                                    lineType == (long) TacticalLines.UOF) {
702                                d1 = lineutility.CalcDistanceDouble(pLinePoints[j], pFlotPoints[nFlotCounter - 9]);
703                                d2 = lineutility.CalcDistanceDouble(pLinePoints[j + 1], pFlotPoints[nFlotCounter - 9]);
704                                if (d2 > d1) {
705                                    pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j + 1], pLinePoints[j], -d1 - 20);
706                                } else {
707                                    pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j], pLinePoints[j + 1], -d2 + 20);
708                                }
709                                if (lineType == (long) TacticalLines.OCCLUDED) {
710                                    pFlotPoints[nFlotCounter].style = 10;
711                                }
712                                if (lineType == (long) TacticalLines.UOF) {
713                                    pFlotPoints[nFlotCounter].style = 5;
714                                }
715                            }
716                            if (lineType == (long) TacticalLines.SF) {
717                                pFlotPoints[nFlotCounter].style = 23;   //red fill
718                            }
719                        }
720                        k += 3;
721                        nFlotCounter++;
722                    }
723                    points = null;
724                }
725
726                //for each spike in the line segment
727                //spikes segments are 30 pixels wide with the spikes in the middle, 20 pixels wide
728                segmentLength = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
729                for (k = 0; k < lNumSpikes - 1; k++) //get the spike
730                {
731                    //the first spike base point
732                    //has to be based on the preceding flot
733                    //if the distance goes past the end of the line segment then set the point to the
734                    //end of the line segment
735                    bolTooLong = 0;
736                    sumOfFlots = 0;
737                    for (l = 0; l <= j; l++) {
738                        sumOfFlots += flots[l];
739                    }
740
741                    //for the greatest accuracy
742                    d1 = lineutility.CalcDistanceDouble(pLinePoints[j], pFlotPoints[sumOfFlots * 10 + 10 * k]);
743                    d2 = lineutility.CalcDistanceDouble(pLinePoints[j + 1], pFlotPoints[sumOfFlots * 10 + 10 * k]);
744                    switch (lineType) {
745                        case TacticalLines.OCCLUDED:
746                        case TacticalLines.UOF:
747                            if (d2 > d1) {
748                                tempPoint = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -d1 - dIncrement / 2, 0);
749                            } else {
750                                tempPoint = lineutility.ExtendLine2Double(pLinePoints[j], pLinePoints[j + 1], -d2 + dIncrement / 2, 0);
751                            }
752                            break;
753                        case TacticalLines.SF:
754                            if (d2 > d1) {
755                                tempPoint = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -d1 - dIncrement / 8, 0);
756                            } else {
757                                tempPoint = lineutility.ExtendLine2Double(pLinePoints[j], pLinePoints[j + 1], -d2 + dIncrement / 8, 0);
758                            }
759                            break;
760                        default:
761                            break;
762                    }
763                    spikeLength = lineutility.CalcDistanceDouble(pLinePoints[j], tempPoint);
764                    if (spikeLength + dSpikeSize < segmentLength) {
765                        pSpikePoints[nSpikeCounter] = new POINT2(tempPoint);
766                    } else {
767                        pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
768                        bolTooLong = 1;
769                    }
770
771                    pSpikePoints[nSpikeCounter].style = 9;
772                    nSpikeCounter++;
773
774                    //extend half the spike size from the last point
775                    //do this for the accuracy of the spike point base
776                    d1 = lineutility.CalcDistanceDouble(pLinePoints[j], pSpikePoints[nSpikeCounter - 1]);
777                    d2 = lineutility.CalcDistanceDouble(pLinePoints[j + 1], pSpikePoints[nSpikeCounter - 1]);
778                    if (d1 > d2) {
779                        pt0 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nSpikeCounter - 1], dSpikeSize / 2);
780                    } else {
781                        pt0 = lineutility.ExtendLineDouble(pLinePoints[j + 1], pSpikePoints[nSpikeCounter - 1], -dSpikeSize / 2);
782                    }
783                    //the spike end (perpendicular) point
784                    if (bolTooLong == 0) {
785                        if (bolVertical != 0) //segment is not vertical
786                        {
787                            if (pLinePoints[j].x < pLinePoints[j + 1].x) {
788                                pSpikePoints[nSpikeCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 2, dSpikeSize);   //extennd above the line
789                            } else {
790                                pSpikePoints[nSpikeCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 3, dSpikeSize);   //extend below the line
791                            }
792                            pSpikePoints[nSpikeCounter].style = 0;
793                            nSpikeCounter++;
794                        } else //vertical segment
795                        {
796                            if (pLinePoints[j].y > pLinePoints[j + 1].y) {
797                                pSpikePoints[nSpikeCounter].x = pt0.x - dSpikeSize;
798                            } else {
799                                pSpikePoints[nSpikeCounter].x = pt0.x + dSpikeSize;
800                            }
801
802                            pSpikePoints[nSpikeCounter].y = pt0.y;
803                            nSpikeCounter++;
804                        }
805                    } else //too long
806                    {
807                        pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
808                        nSpikeCounter++;
809                    }
810                    pSpikePoints[nSpikeCounter - 1].style = 9;
811
812                    //the second spike base point. this is the third spike point
813                    if (bolTooLong == 0) {
814                        d1 = lineutility.CalcDistanceDouble(pLinePoints[j], pSpikePoints[nSpikeCounter - 2]);
815                        d2 = lineutility.CalcDistanceDouble(pLinePoints[j + 1], pSpikePoints[nSpikeCounter - 2]);
816                        if (d1 > d2) {
817                            pSpikePoints[nSpikeCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nSpikeCounter - 2], dSpikeSize, 0);
818                        } else {
819                            pSpikePoints[nSpikeCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pSpikePoints[nSpikeCounter - 2], -dSpikeSize, 0);
820                        }
821                        if (lineType == (long) TacticalLines.OCCLUDED) {
822                            pSpikePoints[nSpikeCounter].style = 10;
823                        }
824                        if (lineType == (long) TacticalLines.UOF) {
825                            pSpikePoints[nSpikeCounter].style = 5;
826                        }
827                        if (lineType == (long) TacticalLines.SF) {
828                            pSpikePoints[nSpikeCounter].style = 24;
829                        }
830                    } else {
831                        pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
832                        pSpikePoints[nSpikeCounter].style = 5;
833                    }
834                    nSpikeCounter++;
835                }//for k= 0 to numSpikes-1
836                if (nSpikeCounter == 0) {
837                    pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j]);
838                    pSpikePoints[nSpikeCounter].style = 5;
839                    nSpikeCounter++;
840                    pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
841                    pSpikePoints[nSpikeCounter].style = 5;
842                    nSpikeCounter++;
843                    //added 6-1-05 M. Deutch
844                    pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
845                    pSpikePoints[nSpikeCounter].style = 5;
846                    nSpikeCounter++;
847                } else {
848                    pSpikePoints[nSpikeCounter] = new POINT2(pSpikePoints[nSpikeCounter - 1]);
849                    pSpikePoints[nSpikeCounter].style = 5;
850                    pSpikePoints[nSpikeCounter + 1] = new POINT2(pSpikePoints[nSpikeCounter - 1]);
851                    pSpikePoints[nSpikeCounter + 1].style = 5;
852                    pSpikePoints[nSpikeCounter + 2] = new POINT2(pSpikePoints[nSpikeCounter - 1]);
853                    pSpikePoints[nSpikeCounter + 2].style = 5;
854                    nSpikeCounter += 3;
855                }
856            }
857
858            for (j = 0; j < pLinePoints.length; j++) {
859                pLinePoints[j] = new POINT2(pSpikePoints[0]);
860                pLinePoints[j].style = 5;
861            }
862            //load the spike points into the array
863            nFlotCounter = 0;
864            nSpikeCounter = 0;
865            for (j = 0; j < lTotalPoints / 13; j++) {
866                //get the flots
867                for (k = 0; k < 10; k++) {
868                    pLinePoints[nTotalCounter] = new POINT2(pFlotPoints[j * 10 + k]);
869                    nTotalCounter++;
870                    nFlotCounter++;
871                }
872                //get the spikes
873                for (k = 0; k < 3; k++) {
874                    pLinePoints[nTotalCounter] = new POINT2(pSpikePoints[j * 3 + k]);
875                    nTotalCounter++;
876                    nSpikeCounter++;
877                }
878            }
879            n=pLinePoints.length;
880            for (j = nTotalCounter; j < n; j++) 
881            {
882                pLinePoints[j] = new POINT2(pLinePoints[nTotalCounter - 1]);
883            }
884        } catch (Exception exc) {
885            ErrorLogger.LogException(_className ,"GetOccludedPointsDouble",
886                    new RendererException("Failed inside GetOccludedPointsDouble", exc));
887        }
888        return nTotalCounter;
889    }
890
891    protected static int GetOccludedCountDouble(POINT2[] pLinePoints, int numPts) {
892        int lTotalpts = 0;
893        try {
894            int j = 0, lNumSegs = 0;
895            int lNumFlots = 0, lNumSpikes = 0;
896            double dDistance = 0;
897
898            //for each segment
899            for (j = 0; j < numPts - 1; j++) {
900                dDistance = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
901                lNumSegs = (int) (dDistance / 50);   //flot + spike = 60 pixels
902                lNumFlots = lNumSegs;
903                lNumSpikes = lNumSegs;
904                if (lNumFlots < 1) {
905                    lNumFlots = 1;
906                }
907                if (lNumSpikes < 1) {
908                    lNumSpikes = 1;
909                }
910                lTotalpts += lNumFlots * 10; //10 points per flot,
911                lTotalpts += lNumSpikes * 3; //3 points per spike
912            }
913            if (lTotalpts < 13 * numPts) {
914                lTotalpts = 13 * numPts;
915            }
916
917            if (lTotalpts < numPts) {
918                lTotalpts = numPts;
919            }
920
921        } catch (Exception exc) {
922            ErrorLogger.LogException(_className ,"GetOccludedCountDouble",
923                    new RendererException("Failed inside GetOccludedCountDouble", exc));
924        }
925        return lTotalpts;
926    }
927
928    private static int CalcNewPoint(int locx,
929            int locY,
930            double angle,
931            int[] point,
932            double dist) {
933        try {
934            double m = 0;
935            double deltaX = 0, deltaY = 0;
936            double dx = 0, dy = 0;
937            int nQuadrant = -1;
938
939            if (angle < 0) {
940                angle = angle + 360;
941            }
942
943            if (angle > 360) {
944                angle = angle - 360;
945            }
946
947            if (0 <= angle && angle <= 90) {
948                nQuadrant = 0;
949                angle = 90 - angle;
950                angle = Math.abs(angle) * (Math.PI / 180);
951            }
952
953            if (90 < angle && angle <= 180) {
954                nQuadrant = 1;
955                angle = angle - 90;
956                angle = Math.abs(angle) * (Math.PI / 180);
957            }
958
959            if (180 < angle && angle <= 270) {
960                nQuadrant = 2;
961                angle = 270 - angle;
962                angle = Math.abs(angle) * (Math.PI / 180);
963            }
964
965            if (270 < angle && angle <= 360) {
966                nQuadrant = 3;
967                angle = angle - 270;
968                angle = Math.abs(angle) * (Math.PI / 180);
969            }
970
971            m = Math.abs(Math.tan(angle));
972            deltaX = Math.abs(dist / Math.sqrt(1 + m * m));
973            deltaY = Math.abs(m * deltaX);
974
975            switch (nQuadrant) {
976                case 0:
977                    dx = locx + deltaX;
978                    dy = locY - deltaY;
979                    break;
980                case 1:
981                    dx = locx + deltaX;
982                    dy = locY + deltaY;
983                    break;
984                case 2:
985                    dx = locx - deltaX;
986                    dy = locY + deltaY;
987                    break;
988                case 3:
989                    dx = locx - deltaX;
990                    dy = locY - deltaY;
991                    break;
992                default:
993                    break;
994            }
995
996            point[0] = (int) dx;
997            point[1] = (int) dy;
998
999        } catch (Exception exc) {
1000            ErrorLogger.LogException(_className ,"CalcNewPoint",
1001                    new RendererException("Failed inside CalcNewPoint", exc));
1002        }
1003        return 1;
1004    }
1005    /**
1006     * Calculates points for a flot segment. Assumes the caller allocated the points array
1007     * @param vbPoints the client points
1008     * @param segment the segment index
1009     * @param points the returned points
1010     * @return the number of points
1011     */
1012    private static int GetFlotSegment(int[] vbPoints,
1013            int segment,
1014            int[] points,
1015            ref<int[]> bFlip,
1016            ref<int[]> lDirection,
1017            ref<int[]> lLastDirection) {
1018        int nNumSegs = 0;
1019        try {
1020            int j = 0;
1021            double dDistance = 0;
1022            int m = 0;
1023            int lLocx = 0, lLocy = 0;
1024            int lSegCounter = 0;
1025            double dAngle = 0;
1026            int[] arcPoints = new int[30];
1027            double dRemainder = 0;
1028            double dNum = 0, dDen = 0;
1029            //end declarations
1030            lSegCounter = 0;
1031            if (segment == 0 && vbPoints[0] >= vbPoints[2]) {
1032                bFlip.value[0] = 1;//TRUE;
1033            }
1034            if (segment == 0 && vbPoints[0] < vbPoints[2]) {
1035                bFlip.value[0] = 0;//FALSE;
1036            }
1037
1038            dNum = vbPoints[2 * segment + 3] - vbPoints[2 * segment + 1];
1039            dDen = vbPoints[2 * segment + 2] - vbPoints[2 * segment];
1040
1041            //for some reason this did not blow up before I put the if/else
1042            //instead it would assign pi/2 to dAngle when dDen=0
1043            if (dDen == 0) {
1044                dAngle = Math.PI / 2;
1045                
1046            } else {
1047                dAngle = Math.abs(Math.atan(dNum / dDen));
1048
1049                //convert to degrees
1050                
1051            }
1052            dAngle = (180 / Math.PI) * dAngle;
1053
1054            if (vbPoints[2 * segment + 0] <= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] >= vbPoints[2 * segment + 3]) {
1055                dAngle = 90 - dAngle;
1056            } else if (vbPoints[2 * segment + 0] <= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] <= vbPoints[2 * segment + 3]) {
1057                dAngle = dAngle + 90;
1058            } else if (vbPoints[2 * segment + 0] >= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] <= vbPoints[2 * segment + 3]) {
1059                dAngle = 270 - dAngle;
1060            } else if (vbPoints[2 * segment + 0] >= vbPoints[2 * segment + 2] && vbPoints[2 * segment + 1] >= vbPoints[2 * segment + 3]) {
1061                dAngle = 270 + dAngle;
1062            }
1063
1064            dDistance = lineutility.CalcDistance2(vbPoints[2 * segment], vbPoints[2 * segment + 1], vbPoints[2 * segment + 2], vbPoints[2 * segment + 3]);
1065
1066            nNumSegs = (int) (dDistance / 20);
1067
1068            dRemainder = nNumSegs * 20 - dDistance;
1069            dDistance = dDistance + dRemainder;
1070
1071            //calculate the default dAngle here
1072            //also establish the lDirection
1073            if (vbPoints[2 * segment] >= vbPoints[2 * segment + 2]) {
1074                dAngle = dAngle + 90;
1075                lDirection.value[0] = 1;
1076            } else {
1077                dAngle = dAngle - 90;
1078                lDirection.value[0] = 0;
1079            }
1080
1081            if (segment > 0 && lDirection.value[0] != lLastDirection.value[0]) {
1082                //'toggle bflip if the lDirection changes
1083                if (bFlip.value[0] == 1) {
1084                    bFlip.value[0] = 0;
1085                    
1086                } else {
1087                    bFlip.value[0] = 1;
1088                    
1089                }
1090            }
1091
1092            //'flip the segment if necessary
1093            if (bFlip.value[0] == 1) {
1094                dAngle = dAngle + 180;
1095
1096
1097            }
1098            for (m = 0; m < nNumSegs; m++) {
1099                lLocx = (int) (vbPoints[2 * segment] + (m + 0.5) * (vbPoints[2 * segment + 2] - vbPoints[2 * segment]) * 20 / dDistance);
1100                lLocy = (int) (vbPoints[2 * segment + 1] + (m + 0.5) * (vbPoints[2 * segment + 3] - vbPoints[2 * segment + 1]) * 20 / dDistance);
1101
1102                CalcAnglePoints(lLocx, lLocy, dAngle, arcPoints, dDistance / (nNumSegs * 2));
1103                
1104                //9-12-12
1105                //points were set to null by the caller if the segment distance was too short
1106                //in which case GetflotSegment still must be called to set bFlip, lDirection, lLastDirection
1107                if(points!=null)
1108                {
1109                    for (j = 0; j < 30; j++) 
1110                    {
1111                        points[lSegCounter] = arcPoints[j];
1112                        lSegCounter = lSegCounter + 1;
1113                    }
1114                }
1115            }
1116
1117            //save last lDirection
1118            lLastDirection.value[0] = lDirection.value[0];
1119            arcPoints = null;
1120        } catch (Exception exc) {
1121            ErrorLogger.LogException(_className ,"GetFlotSegment",
1122                    new RendererException("Failed inside GetFlotSegment", exc));
1123        }
1124        return nNumSegs * 10;
1125    }
1126    /**
1127     * Calculates the points for FLOT, LC
1128     * @param vbPoints2 OUT the clinet points also used for the return points
1129     * @param numPts
1130     * @return
1131     */
1132    protected static int GetFlotDouble(POINT2[] vbPoints2, int numPts) {
1133        int lFlotCounter = 0;
1134        try {            
1135            ref<int[]> bFlip=new ref();bFlip.value=new int[1];bFlip.value[0]=-1;   //-1
1136            ref<int[]> lDirection=new ref();lDirection.value=new int[1];lDirection.value[0]=-1;//-1;
1137            ref<int[]> lLastDirection=new ref();lLastDirection.value=new int[1];lLastDirection.value[0]=-1;//-1;
1138            int j = 0, k = 0, l = 0, m = 0;
1139            int x1 = 0, y1 = 0;
1140            int numSegPts = -1;
1141            int z = 0, lFlotCount = 0;
1142            int lNumSegs = 0;
1143            double dDistance = 0;
1144            int[] vbPoints = null;
1145            int[] points = null;
1146
1147            lFlotCount = GetFlotCountDouble(vbPoints2, numPts);
1148
1149            vbPoints = new int[2 * numPts];
1150            //lineutility.BoundPoints(ref vbPoints2,numPts,ref segments);
1151            //BoundPoints returns a segments array of booleans
1152            //which determines whether each segment should be drawn
1153
1154            for (j = 0; j < numPts; j++) {
1155                vbPoints[k] = (int) vbPoints2[j].x;
1156                k++;
1157                vbPoints[k] = (int) vbPoints2[j].y;
1158                k++;
1159            }
1160            k = 0;
1161            //assume caller has dimensioned flotpoints
1162
1163            //every lSegment has 2 points
1164            for (l = 0; l < numPts - 1; l++) {
1165                dDistance = lineutility.CalcDistance2(vbPoints[m], vbPoints[m + 1], vbPoints[m + 2], vbPoints[m + 3]);
1166                m += 2;
1167                lNumSegs = (int) (dDistance / 20);
1168                if (lNumSegs > 0) {
1169                    points = new int[lNumSegs * 30];
1170                    numSegPts = GetFlotSegment(vbPoints, l, points,bFlip,lDirection,lLastDirection);
1171                    for (j = 0; j < numSegPts; j++) {
1172                        x1 = points[k];
1173                        y1 = points[k + 1];
1174                        z = points[k + 2];
1175                        k = k + 3;
1176                        if (lFlotCounter < lFlotCount) {
1177                            vbPoints2[lFlotCounter].x = x1;
1178                            vbPoints2[lFlotCounter].y = y1;
1179                            lFlotCounter++;
1180                        }
1181                    }
1182                    k = 0;
1183                    points = null;
1184                } 
1185                else 
1186                {
1187                    ///added section 9-12-12
1188                    //these points are not used but bFlip, lDirection, lLastDirection
1189                    //must be maintained between segments
1190                    points=null;
1191                    numSegPts = GetFlotSegment(vbPoints, l, points,bFlip,lDirection,lLastDirection);
1192                    //end section
1193                    if (lFlotCounter < lFlotCount) 
1194                    {
1195                        vbPoints2[lFlotCounter].x = vbPoints[2 * l];
1196                        vbPoints2[lFlotCounter].y = vbPoints[2 * l + 1];
1197                        lFlotCounter++;
1198                    }
1199                }
1200            }
1201            int n=vbPoints2.length;
1202            for (j = lFlotCounter - 1; j < n; j++) 
1203            {
1204                vbPoints2[j].style = 5;
1205            }
1206            vbPoints = null;
1207        } catch (Exception exc) {
1208            ErrorLogger.LogException(_className ,"GetFlotDouble",
1209                    new RendererException("Failed inside GetFlotDouble", exc));
1210        }
1211        return lFlotCounter;
1212    }
1213
1214    private static int CalcAnglePoints(int locx,
1215            int locY,
1216            double angle,
1217            int[] points,
1218            double dist) {
1219        try {
1220            int j = 0, k = 0;
1221            int[] lTemp = new int[2];
1222
1223            for (j = 0; j < 10; j++) {
1224                CalcNewPoint(locx, locY, angle - 90 + 20 * j, lTemp, dist);
1225                points[k] = lTemp[0];
1226                points[k + 1] = lTemp[1];
1227
1228                k += 3;
1229            }
1230            lTemp = null;
1231        } catch (Exception exc) {
1232            ErrorLogger.LogException(_className ,"CalcAnglePoints",
1233                    new RendererException("Failed inside CalcAnglePoints", exc));
1234        }
1235        return 1;
1236    }
1237    /**
1238     * Calculates the number of points required for a flot
1239     * @param vbPoints the clinet points
1240     * @param numPts the number of client points
1241     * @return the number of points required
1242     */
1243    protected static int GetFlotCountDouble(POINT2[] vbPoints, int numPts) {
1244        int lTotalpts = 0;
1245        try {
1246            int j = 0, lNumSegs = 0;
1247            double dDistance = 0;
1248            POINT2[] vbPoints2 = null;
1249
1250            vbPoints2 = new POINT2[numPts];
1251            for (j = 0; j < numPts; j++) {
1252                vbPoints2[j] = vbPoints[j];
1253            }
1254            for (j = 0; j < numPts - 1; j++) {
1255                dDistance = lineutility.CalcDistanceDouble(vbPoints2[j], vbPoints2[j + 1]);
1256                lNumSegs = (int) (dDistance / 20);   //flot diameter is 20
1257                if (lNumSegs > 0) {
1258                    lTotalpts += lNumSegs * 10; //10 points per flot
1259                } else {
1260                    lTotalpts += 1;
1261                }
1262            }
1263            lTotalpts += 1;
1264
1265        } catch (Exception exc) {
1266            ErrorLogger.LogException(_className ,"GetFlotCountDouble",
1267                    new RendererException("Failed inside GetFlotCountDouble", exc));
1268        }
1269        return (lTotalpts);
1270    }
1271                
1272    protected static int GetOFYPointsDouble(POINT2[] pLinePoints,
1273            int numPts,
1274            int lineType)
1275    {
1276        int nTotalCounter = 0;
1277        try
1278        {
1279            int j = 0, k = 0, lNumSegs = 0, l = 0;
1280            int lNumFlots = 0, lNumSpikes = 0;
1281            double dDistance = 0;
1282            ref<double[]> m = new ref();
1283            int lTotalPoints = 0;
1284            int[] points = null;
1285            POINT2[] pSpikePoints = null;
1286            POINT2 pt0 = new POINT2(), tempPoint = new POINT2();
1287            POINT2[] pFlotPoints = null;
1288            POINT2[] pSegmentPoints = null;
1289            double dSpikeSize = 20;
1290            double dIncrement = 80;     //was 70
1291            int[] vbPoints = null;
1292            int nFlotCounter = 0, nSpikeCounter = 0, nSegmentCounter = 0;
1293            int[] flots = null;
1294            double segmentLength = 0, spikeLength = 0;
1295            int bolTooLong = 0;
1296            double d1 = 0, d2 = 0;
1297            int bolVertical = 0;
1298            POINT2[] pFlotStart = null;
1299            POINT2[] pFlotEnd = null;
1300            POINT2[] pSpikeStart = null;
1301            POINT2[] pSpikeEnd = null;
1302            int nSpikeEndCounter = 0;
1303            int nFlotEndCounter = 0;
1304            ref<int[]> bFlip = new ref();
1305            ref<int[]> lDirection = new ref();
1306            ref<int[]> lLastDirection = new ref();
1307
1308            m.value = new double[1];
1309            bFlip.value = new int[1];
1310            lDirection.value = new int[1];
1311            lLastDirection.value = new int[1];
1312            lTotalPoints = GetOFYCountDouble(pLinePoints, numPts, (int) lineType);
1313
1314            vbPoints = new int[numPts * 2];
1315
1316            pSpikePoints = new POINT2[lTotalPoints];
1317            pFlotPoints = new POINT2[lTotalPoints];
1318            pSegmentPoints = new POINT2[lTotalPoints];
1319            int n=pSpikePoints.length;
1320            //for (j = 0; j < pSpikePoints.length; j++) 
1321            for (j = 0; j < n; j++) 
1322            {
1323                pSpikePoints[j] = new POINT2(pLinePoints[0]);
1324                pSpikePoints[j].style = 5;
1325            }
1326            n=pFlotPoints.length;
1327            //for (j = 0; j < pFlotPoints.length; j++) 
1328            for (j = 0; j < n; j++) 
1329            {
1330                pFlotPoints[j] = new POINT2(pLinePoints[0]);
1331                pFlotPoints[j].style = 5;
1332            }
1333            lineutility.InitializePOINT2Array(pSegmentPoints);
1334
1335            flots = new int[numPts + 1];
1336            //the vbPoints long array gets used by GetFlotSegment
1337            //and is based on the original points
1338            for (j = 0; j < numPts; j++) {
1339                vbPoints[k] = (int) pLinePoints[j].x;
1340                k++;
1341                vbPoints[k] = (int) pLinePoints[j].y;
1342                k++;
1343            }
1344            k = 0;
1345            //initialize flots
1346            flots[0] = 0;
1347            for (j = 0; j < numPts; j++) {
1348                flots[j + 1] = 0;
1349            }
1350
1351            for (j = 0; j < numPts - 1; j++) {
1352                //initialize spike end counter and flot end counter for each segment
1353                nSpikeEndCounter = 0;
1354                nFlotEndCounter = 0;
1355                bolVertical = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
1356                m.value[0] = -m.value[0];       //reverse the direction
1357                dDistance = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
1358                lNumSegs = (int) (dDistance / dIncrement);   //flot(20) + spike(20) = 60 pixels
1359                lNumFlots = lNumSegs;
1360                lNumSpikes = lNumSegs;
1361                flots[j + 1] = lNumSegs;
1362
1363                //get the flot segments for this line segment
1364                //flot segments are 30 pixels wide with the flots in the middle, 20 pixels wide
1365                k = 0;
1366                if (lNumFlots > 0) {
1367                    points = new int[lNumFlots * 30];
1368                    pFlotStart = new POINT2[lNumFlots];
1369                    pFlotEnd = new POINT2[lNumFlots];
1370                    GetFlotSegment2(vbPoints, j, points, lineType, bFlip, lDirection, lLastDirection);
1371                    for (l = 0; l < lNumFlots * 10; l++) {
1372                        pFlotPoints[nFlotCounter].x = points[k];
1373                        pFlotPoints[nFlotCounter].y = points[k + 1];
1374                        pFlotPoints[nFlotCounter].style = 9;
1375                        //straighten out the flots
1376                        if ((nFlotCounter) % 10 == 0) {
1377                            pFlotStart[l / 10] = new POINT2(pFlotPoints[nFlotCounter]);
1378                            d1 = lineutility.CalcDistanceDouble(pLinePoints[j], pFlotPoints[nFlotCounter]);
1379                            d2 = lineutility.CalcDistanceDouble(pLinePoints[j + 1], pFlotPoints[nFlotCounter]);
1380                            if (d2 > d1) {
1381                                pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j + 1], pLinePoints[j], -d1);
1382                            } else {
1383                                pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j], pLinePoints[j + 1], -d2);
1384                            }
1385                            pFlotPoints[nFlotCounter].style = 9;
1386                        }
1387                        if ((nFlotCounter + 1) % 10 == 0) {
1388                            if (lineType == (long) TacticalLines.OFY) {
1389                                pFlotEnd[l / 10] = new POINT2(pFlotPoints[nFlotCounter]);
1390                                nFlotEndCounter++;
1391                                d1 = lineutility.CalcDistanceDouble(pLinePoints[j], pFlotPoints[nFlotCounter - 9]);
1392                                d2 = lineutility.CalcDistanceDouble(pLinePoints[j + 1], pFlotPoints[nFlotCounter - 9]);
1393                                if (d2 > d1) {
1394                                    pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j + 1], pLinePoints[j], -d1 - 20);
1395                                } else {
1396                                    pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j], pLinePoints[j + 1], -d2 + 20);
1397                                }
1398
1399                                pFlotPoints[nFlotCounter].style = 10;
1400                            }
1401                        }
1402                        k += 3;
1403                        nFlotCounter++;
1404                    }
1405                    points = null;
1406                }// end if num flots>0
1407                else //segment too short
1408                {
1409                    pSegmentPoints[nSegmentCounter] = new POINT2(pLinePoints[j]);
1410                    pSegmentPoints[nSegmentCounter++].style = 0;
1411                    pSegmentPoints[nSegmentCounter] = new POINT2(pLinePoints[j + 1]);
1412                    pSegmentPoints[nSegmentCounter++].style = 5;
1413                }
1414
1415                //for each spike in the line segment
1416                //spikes segments are 30 pixels wide with the spikes in the middle, 20 pixels wide
1417                segmentLength = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
1418                pSpikeStart = new POINT2[lNumSpikes];
1419                pSpikeEnd = new POINT2[lNumSpikes];
1420                for (k = 0; k < lNumSpikes - 1; k++) //get the spike
1421                {
1422                    //the first spike base point
1423                    //has to be based on the preceding flot
1424                    //if the distance goes past the end of the line segment then set the point to the
1425                    //end of the line segment
1426                    bolTooLong = 0;
1427
1428                    //for the greatest accuracy
1429                    d1 = lineutility.CalcDistanceDouble(pFlotEnd[k], pFlotEnd[k + 1]);
1430                    d1 = d1 / 2 - dSpikeSize;
1431                    tempPoint = lineutility.ExtendAlongLineDouble(pFlotEnd[k], pLinePoints[j + 1], d1, 0);
1432                    spikeLength = lineutility.CalcDistanceDouble(pLinePoints[j], tempPoint);
1433                    if (spikeLength + dSpikeSize < segmentLength) {
1434                        pSpikePoints[nSpikeCounter] = new POINT2(tempPoint);
1435                        pSpikeStart[k] = new POINT2(tempPoint);
1436                    } else {
1437                        pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1438                        bolTooLong = 1;
1439                    }
1440
1441                    pSpikePoints[nSpikeCounter].style = 9;
1442                    nSpikeCounter++;
1443
1444                    pt0 = lineutility.ExtendAlongLineDouble(pSpikePoints[nSpikeCounter - 1], pLinePoints[j + 1], dSpikeSize / 2);
1445
1446                    //the spike end (perpendicular) point
1447                    if (bolTooLong == 0) {
1448                        if (bolVertical != 0) //segment is not vertical
1449                        {
1450                            if (pLinePoints[j].x < pLinePoints[j + 1].x) {
1451                                pSpikePoints[nSpikeCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 2, dSpikeSize);   //extennd above the line
1452                            } else {
1453                                pSpikePoints[nSpikeCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 3, dSpikeSize);   //extend below the line
1454                            }
1455                            pSpikePoints[nSpikeCounter].style = 0;
1456                            nSpikeCounter++;
1457                        } else //vertical segment
1458                        {
1459                            if (pLinePoints[j].y > pLinePoints[j + 1].y) {
1460                                pSpikePoints[nSpikeCounter].x = pt0.x - dSpikeSize;
1461                            } else {
1462                                pSpikePoints[nSpikeCounter].x = pt0.x + dSpikeSize;
1463                            }
1464
1465                            pSpikePoints[nSpikeCounter].y = pt0.y;
1466                            nSpikeCounter++;
1467                        }
1468                    } else //too long
1469                    {
1470                        pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1471                        nSpikeCounter++;
1472                    }
1473                    pSpikePoints[nSpikeCounter - 1].style = 9;
1474
1475                    //the second spike base point. this is the third spike point
1476                    if (bolTooLong == 0) {
1477                        d1 = lineutility.CalcDistanceDouble(pLinePoints[j], pSpikePoints[nSpikeCounter - 2]);
1478                        d2 = lineutility.CalcDistanceDouble(pLinePoints[j + 1], pSpikePoints[nSpikeCounter - 2]);
1479                        if (d1 > d2) {
1480                            pSpikePoints[nSpikeCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nSpikeCounter - 2], dSpikeSize, 0);
1481                        } else {
1482                            pSpikePoints[nSpikeCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pSpikePoints[nSpikeCounter - 2], -dSpikeSize, 0);
1483                        }
1484
1485                        pSpikeEnd[k] = new POINT2(pSpikePoints[nSpikeCounter]);
1486                        nSpikeEndCounter++;
1487                        if (lineType == (long) TacticalLines.OFY) {
1488                            pSpikePoints[nSpikeCounter].style = 10;
1489                        }
1490                    } else {
1491                        pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1492                        pSpikePoints[nSpikeCounter].style = 5;
1493                    }
1494                    nSpikeCounter++;
1495                }//end for k= 0 to numSpikes-1
1496                //if there are no spikes
1497                if (nSpikeEndCounter == 0 && nFlotEndCounter == 1) {
1498                    pSegmentPoints[nSegmentCounter] = new POINT2(pLinePoints[j]);
1499                    pSegmentPoints[nSegmentCounter++].style = 0;
1500                    pSegmentPoints[nSegmentCounter] = new POINT2(pFlotStart[0]);
1501                    pSegmentPoints[nSegmentCounter++].style = 5;
1502
1503                    pSegmentPoints[nSegmentCounter] = new POINT2(pLinePoints[j + 1]);
1504                    pSegmentPoints[nSegmentCounter++].style = 0;
1505                    pSegmentPoints[nSegmentCounter] = new POINT2(pFlotEnd[0]);
1506                    pSegmentPoints[nSegmentCounter++].style = 5;
1507                }
1508                //put a loop here for the segment points
1509                for (l = 0; l < nSpikeEndCounter; l++) {
1510                    if (l == 0) {
1511                        pSegmentPoints[nSegmentCounter] = new POINT2(pLinePoints[j]);
1512                        pSegmentPoints[nSegmentCounter++].style = 0;
1513                        pSegmentPoints[nSegmentCounter] = new POINT2(pFlotStart[0]);
1514                        pSegmentPoints[nSegmentCounter++].style = 5;
1515                    }
1516                    if (l == nSpikeEndCounter - 1) //the last spike
1517                    {
1518                        pSegmentPoints[nSegmentCounter] = new POINT2(pLinePoints[j + 1]);
1519                        pSegmentPoints[nSegmentCounter++].style = 0;
1520                        pSegmentPoints[nSegmentCounter] = new POINT2(pFlotEnd[l + 1]);
1521                        pSegmentPoints[nSegmentCounter++].style = 5;
1522                    }
1523                    //put the cross point segments between the flots and spikes
1524                    //segment before the spike is just a line
1525                    pSegmentPoints[nSegmentCounter] = new POINT2(pSpikeEnd[l]);
1526                    pSegmentPoints[nSegmentCounter++].style = 0;
1527                    pSegmentPoints[nSegmentCounter] = new POINT2(pFlotStart[l + 1]);
1528                    pSegmentPoints[nSegmentCounter++].style = 5;
1529
1530                    //the cross points
1531                    d1 = lineutility.CalcDistanceDouble(pSpikeStart[l], pFlotEnd[l]);
1532                    pSegmentPoints[nSegmentCounter++] = lineutility.ExtendAlongLineDouble(pSpikeStart[l], pLinePoints[j], d1 / 3, 0);
1533                    pSegmentPoints[nSegmentCounter++] = lineutility.ExtendAlongLineDouble(pSpikeStart[l], pLinePoints[j], 2 * d1 / 3, 5);
1534                    tempPoint = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pSegmentPoints[nSegmentCounter - 2], 2, 5, 0);
1535                    pSegmentPoints[nSegmentCounter++] = new POINT2(tempPoint);
1536                    tempPoint = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pSegmentPoints[nSegmentCounter - 2], 3, 5, 5);
1537                    pSegmentPoints[nSegmentCounter++] = new POINT2(tempPoint);
1538                }
1539                if (nSpikeCounter == 0) {
1540                    pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j]);
1541                    pSpikePoints[nSpikeCounter].style = 5;
1542                    nSpikeCounter++;
1543                    pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1544                    pSpikePoints[nSpikeCounter].style = 5;
1545                    nSpikeCounter++;
1546                    pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1547                    pSpikePoints[nSpikeCounter].style = 5;
1548                    nSpikeCounter++;
1549                } else {
1550                    pSpikePoints[nSpikeCounter] = new POINT2(pSpikePoints[nSpikeCounter - 1]);
1551                    pSpikePoints[nSpikeCounter].style = 5;
1552                    pSpikePoints[nSpikeCounter + 1] = new POINT2(pSpikePoints[nSpikeCounter - 1]);
1553                    pSpikePoints[nSpikeCounter + 1].style = 5;
1554                    pSpikePoints[nSpikeCounter + 2] = new POINT2(pSpikePoints[nSpikeCounter - 1]);
1555                    pSpikePoints[nSpikeCounter + 2].style = 5;
1556                    nSpikeCounter += 3;
1557                }
1558            }
1559
1560            //load the spike points into the array
1561            nTotalCounter = 0;
1562            for (j = 0; j < nFlotCounter; j++) {
1563                pLinePoints[nTotalCounter++] = new POINT2(pFlotPoints[j]);
1564            }
1565            for (j = 0; j < nSpikeCounter; j++) {
1566                pLinePoints[nTotalCounter++] = new POINT2(pSpikePoints[j]);
1567            }
1568            for (j = 0; j < nSegmentCounter; j++) {
1569                pLinePoints[nTotalCounter++] = new POINT2(pSegmentPoints[j]);
1570            }
1571            n=pLinePoints.length;
1572            //for (j = nTotalCounter; j < pLinePoints.length; j++) 
1573            for (j = nTotalCounter; j < n; j++) 
1574            {
1575                pLinePoints[j] = new POINT2(pLinePoints[nTotalCounter - 1]);
1576            }
1577        } catch (Exception exc) {
1578            ErrorLogger.LogException(_className ,"GetOFYPointsDouble",
1579                    new RendererException("Failed inside GetOFYPointsDouble", exc));
1580        }
1581        return nTotalCounter;
1582    }
1583    protected static int GetSFPointsDouble(POINT2[] pLinePoints,
1584            int numPts,
1585            int lineType) {
1586        int nTotalCounter = 0;
1587        try {
1588            int lTotalPoints = 0;
1589            int j = 0, k = 0, lNumSegs = 0, l = 0;
1590            int lNumFlots = 0, lNumSpikes = 0;
1591            double dDistance = 0;
1592            ref<double[]> m = new ref();
1593            int[] points = null;
1594            POINT2[] pSpikePoints = null;
1595            POINT2 pt0 = new POINT2(), tempPoint = new POINT2();
1596            POINT2[] pFlotPoints = null;
1597            double dSpikeSize = 20, dIncrement = 80;
1598            int[] vbPoints = null;
1599            int nFlotCounter = 0, nSpikeCounter = 0, nSegCounter = 0;
1600            int[] flots = null;
1601            //int sumOfFlots = 0;
1602            double segmentLength = 0, spikeLength = 0;
1603            int bolTooLong = 0;
1604            double d1 = 0, d2 = 0;
1605            int bolVertical = 0;
1606            POINT2[] pFlotStart = null;
1607            POINT2[] pFlotEnd = null;
1608            POINT2[] pSpikeStart = null;
1609            POINT2[] pSpikeEnd = null;
1610            POINT2[] pSegPoints = null;
1611            ref<int[]> bFlip = new ref();
1612            ref<int[]> lDirection = new ref();
1613            ref<int[]> lLastDirection = new ref();
1614
1615            lTotalPoints = GetSFCountDouble(pLinePoints, numPts);
1616            m.value = new double[1];
1617            lDirection.value = new int[1];
1618            lDirection.value[0] = -1;
1619            lLastDirection.value = new int[1];
1620            lLastDirection.value[0] = -1;
1621            bFlip.value = new int[1];
1622            bFlip.value[0] = -1;
1623
1624            vbPoints = new int[numPts * 2];
1625            pSpikePoints = new POINT2[lTotalPoints];
1626            pFlotPoints = new POINT2[lTotalPoints];
1627            int n=pSpikePoints.length;
1628            //for (j = 0; j < pSpikePoints.length; j++) 
1629            for (j = 0; j < n; j++) 
1630            {
1631                pSpikePoints[j] = new POINT2(pLinePoints[0]);
1632                pSpikePoints[j].style = 5;
1633            }
1634            n=pFlotPoints.length;
1635            //for (j = 0; j < pFlotPoints.length; j++) 
1636            for (j = 0; j < n; j++) 
1637            {
1638                pFlotPoints[j] = new POINT2(pLinePoints[0]);
1639                pFlotPoints[j].style = 5;
1640            }
1641            pSegPoints = new POINT2[4 * (numPts - 1)];
1642            lineutility.InitializePOINT2Array(pSegPoints);
1643
1644            flots = new int[numPts + 1];
1645            //the vbPoints long array gets used by GetFlotSegment
1646            //and is based on the original points
1647            //for(j=0;j<numPts;j++)
1648            for (j = 0; j < numPts; j++) {
1649                vbPoints[k] = (int) pLinePoints[j].x;
1650                k++;
1651                vbPoints[k] = (int) pLinePoints[j].y;
1652                k++;
1653            }
1654            k = 0;
1655            //initialize flots
1656            flots[0] = 0;
1657            for (j = 0; j < numPts; j++) {
1658                flots[j + 1] = 0;
1659            }
1660
1661            for (j = 0; j < numPts - 1; j++) {
1662                bolVertical = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
1663                m.value[0] = -m.value[0];       //reverse the direction
1664                dDistance = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
1665                lNumSegs = (int) (dDistance / dIncrement);
1666                lNumFlots = lNumSegs;
1667                lNumSpikes = lNumSegs;
1668                flots[j + 1] = lNumSegs;
1669
1670                //get the flot segments for this line segment
1671                //flot segments are 30 pixels wide with the flots in the middle, 20 pixels wide
1672                k = 0;
1673                if (lNumFlots > 0) {
1674                    points = new int[lNumFlots * 30];
1675                    pFlotStart = new POINT2[lNumFlots];
1676                    lineutility.InitializePOINT2Array(pFlotStart);
1677                    pFlotEnd = new POINT2[lNumFlots];
1678                    lineutility.InitializePOINT2Array(pFlotEnd);
1679                    GetFlotSegment2(vbPoints, j, points, lineType, bFlip, lDirection, lLastDirection);
1680                    for (l = 0; l < lNumFlots * 10; l++) {
1681                        pFlotPoints[nFlotCounter].x = points[k];
1682                        pFlotPoints[nFlotCounter].y = points[k + 1];
1683
1684                        if (lineType == (long) TacticalLines.USF) {
1685                            pFlotPoints[nFlotCounter].style = 19;
1686                        } else {
1687                            pFlotPoints[nFlotCounter].style = 9;
1688                        }
1689
1690                        //straighten out the flots
1691                        if ((nFlotCounter) % 10 == 0) {
1692                            pFlotStart[l / 10] = pFlotPoints[nFlotCounter];
1693                            d1 = lineutility.CalcDistanceDouble(pLinePoints[j], pFlotPoints[nFlotCounter]);
1694                            d2 = lineutility.CalcDistanceDouble(pLinePoints[j + 1], pFlotPoints[nFlotCounter]);
1695                            if (d2 > d1) {
1696                                pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j + 1], pLinePoints[j], -d1);
1697                            } else {
1698                                pFlotPoints[nFlotCounter] = lineutility.ExtendLineDouble(pLinePoints[j], pLinePoints[j + 1], -d2);
1699                            }
1700
1701                            if (lineType == (long) TacticalLines.USF) {
1702                                pFlotPoints[nFlotCounter].style = 19;
1703                            } else {
1704                                pFlotPoints[nFlotCounter].style = 9;
1705                            }
1706                        }
1707
1708                        if ((nFlotCounter + 1) % 10 == 0) {
1709                            if (lineType == (long) TacticalLines.USF) {
1710                                pFlotPoints[nFlotCounter].style = 5;    //end of flot
1711                            } else {
1712                                pFlotPoints[nFlotCounter].style = 23;   //red fill
1713                            }
1714                            pFlotEnd[l / 10] = new POINT2(pFlotPoints[nFlotCounter]);
1715                        }
1716                        if (l == 0) {
1717                            pSegPoints[nSegCounter] = new POINT2(pLinePoints[j]);
1718                            pSegPoints[nSegCounter++].style = 19;
1719                            pSegPoints[nSegCounter] = new POINT2(pFlotStart[l]);
1720                            pSegPoints[nSegCounter++].style = 5;
1721                        }
1722                        if (l == lNumFlots * 10 - 1) {
1723                            pSegPoints[nSegCounter] = new POINT2(pLinePoints[j + 1]);
1724                            pSegPoints[nSegCounter++].style = 19;
1725                            pSegPoints[nSegCounter] = new POINT2(pFlotStart[l / 10]);
1726                            pSegPoints[nSegCounter++].style = 5;
1727                        }
1728                        k += 3;
1729                        nFlotCounter++;
1730                    }
1731                    points = null;
1732                }//end if num flots>0
1733                else //segment too short
1734                {
1735                    pSegPoints[nSegCounter] = new POINT2(pLinePoints[j]);
1736                    pSegPoints[nSegCounter++].style = 0;
1737                    pSegPoints[nSegCounter] = new POINT2(pLinePoints[j + 1]);
1738                    pSegPoints[nSegCounter++].style = 5;
1739                }
1740
1741                //for each spike in the line segment
1742                //spikes segments are 30 pixels wide with the spikes in the middle, 20 pixels wide
1743                segmentLength = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
1744                pSpikeStart = new POINT2[lNumSpikes];
1745                lineutility.InitializePOINT2Array(pSpikeStart);
1746                pSpikeEnd = new POINT2[lNumSpikes];
1747                lineutility.InitializePOINT2Array(pSpikeEnd);
1748                for (k = 0; k < lNumSpikes - 1; k++) //get the spike
1749                {
1750                    //the first spike base point
1751                    //has to be based on the preceding flot
1752                    //if the distance goes past the end of the line segment then set the point to the
1753                    //end of the line segment
1754                    bolTooLong = 0;
1755
1756                    d1 = lineutility.CalcDistanceDouble(pFlotStart[k], pFlotStart[k + 1]);
1757                    d1 = d1 / 2 - dSpikeSize;
1758                    tempPoint = lineutility.ExtendAlongLineDouble(pFlotStart[k], pLinePoints[j + 1], d1, 0);
1759
1760                    spikeLength = lineutility.CalcDistanceDouble(pLinePoints[j], tempPoint);
1761                    if (spikeLength + dSpikeSize < segmentLength) {
1762                        pSpikePoints[nSpikeCounter] = new POINT2(tempPoint);
1763                        pSpikeStart[k] = new POINT2(tempPoint);
1764                    } else {
1765                        pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1766                        bolTooLong = 1;
1767                    }
1768
1769                    if (lineType == (long) TacticalLines.USF) {
1770                        pSpikePoints[nSpikeCounter].style = 25;
1771                    } else {
1772                        pSpikePoints[nSpikeCounter].style = 9;
1773                    }
1774
1775                    nSpikeCounter++;
1776
1777                    pt0 = lineutility.ExtendAlongLineDouble(pSpikePoints[nSpikeCounter - 1], pLinePoints[j + 1], dSpikeSize / 2);
1778                    //the spike end (perpendicular) point
1779                    if (bolTooLong == 0) {
1780                        if (bolVertical != 0) //segment is not vertical
1781                        {
1782                            if (pLinePoints[j].x < pLinePoints[j + 1].x) {
1783                                pSpikePoints[nSpikeCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 2, dSpikeSize);   //extennd above the line
1784                            } else {
1785                                pSpikePoints[nSpikeCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 3, dSpikeSize);   //extend below the line
1786                            }
1787                            pSpikePoints[nSpikeCounter].style = 0;
1788                            //pSpikeEnd[k]=pSpikePoints[nSpikeCounter];
1789                            nSpikeCounter++;
1790                        } else //vertical segment
1791                        {
1792                            if (pLinePoints[j].y > pLinePoints[j + 1].y) {
1793                                pSpikePoints[nSpikeCounter].x = pt0.x - dSpikeSize;
1794                            } else {
1795                                pSpikePoints[nSpikeCounter].x = pt0.x + dSpikeSize;
1796                            }
1797
1798                            pSpikePoints[nSpikeCounter].y = pt0.y;
1799                            nSpikeCounter++;
1800                        }
1801                    } else //too long
1802                    {
1803                        pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1804                        nSpikeCounter++;
1805                    }
1806
1807                    if (lineType == (long) TacticalLines.USF) {
1808                        pSpikePoints[nSpikeCounter - 1].style = 25;
1809                    } else {
1810                        pSpikePoints[nSpikeCounter - 1].style = 9;
1811                    }
1812
1813                    //the second spike base point. this is the third spike point
1814                    if (bolTooLong == 0) {
1815                        pSpikePoints[nSpikeCounter] = lineutility.ExtendAlongLineDouble(pSpikePoints[nSpikeCounter - 2], pLinePoints[j + 1], dSpikeSize);
1816
1817                        if (lineType == (long) TacticalLines.USF) {
1818                            pSpikePoints[nSpikeCounter].style = 5;
1819                        } else {
1820                            pSpikePoints[nSpikeCounter].style = 24;
1821                        }
1822
1823                        pSpikeEnd[k] = new POINT2(pSpikePoints[nSpikeCounter]);
1824                    } else {
1825                        pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1826                        pSpikePoints[nSpikeCounter].style = 5;
1827                    }
1828                    nSpikeCounter++;
1829                    //the segment feature points, for SF they are just lines
1830                    if (lineType == (long) TacticalLines.SF ||
1831                            lineType == (long) TacticalLines.USF) {
1832                        d1 = lineutility.CalcDistanceDouble(pFlotStart[k], pSpikeStart[k]);
1833                        pSpikePoints[nSpikeCounter] = new POINT2(pFlotStart[k]);
1834                        pSpikePoints[nSpikeCounter++].style = 19;
1835                        pSpikePoints[nSpikeCounter++] = lineutility.ExtendAlongLineDouble(pFlotStart[k], pLinePoints[j + 1], d1 / 2, 5);
1836
1837                        pSpikePoints[nSpikeCounter] = new POINT2(pFlotEnd[k]);
1838                        pSpikePoints[nSpikeCounter++].style = 19;
1839                        pSpikePoints[nSpikeCounter++] = lineutility.ExtendAlongLineDouble(pFlotEnd[k], pLinePoints[j], d1 / 2, 5);
1840
1841                        if (k == lNumSpikes - 2) {
1842                            pSpikePoints[nSpikeCounter] = new POINT2(pFlotStart[k + 1]);
1843                            pSpikePoints[nSpikeCounter++].style = 19;
1844                            pSpikePoints[nSpikeCounter++] = lineutility.ExtendAlongLineDouble(pFlotStart[k + 1], pLinePoints[j + 1], d1 / 2, 5);
1845
1846                            pSpikePoints[nSpikeCounter] = new POINT2(pFlotEnd[k + 1]);
1847                            pSpikePoints[nSpikeCounter++].style = 19;
1848                            pSpikePoints[nSpikeCounter++] = lineutility.ExtendAlongLineDouble(pFlotEnd[k + 1], pLinePoints[j], d1 / 2, 5);
1849
1850                        }
1851
1852                        pSpikePoints[nSpikeCounter] = new POINT2(pSpikeStart[k]);
1853                        pSpikePoints[nSpikeCounter++].style = 25;
1854                        pSpikePoints[nSpikeCounter++] = lineutility.ExtendAlongLineDouble(pSpikeStart[k], pLinePoints[j], d1 / 2, 5);
1855
1856                        pSpikePoints[nSpikeCounter] = new POINT2(pSpikeEnd[k]);
1857                        pSpikePoints[nSpikeCounter++].style = 25;
1858                        pSpikePoints[nSpikeCounter++] = lineutility.ExtendAlongLineDouble(pSpikeEnd[k], pLinePoints[j + 1], d1 / 2, 5);
1859
1860                        if (lineType == (long) TacticalLines.USF) {
1861                            pSpikePoints[nSpikeCounter] = new POINT2(pFlotEnd[k]);
1862                            pSpikePoints[nSpikeCounter++].style = 19;
1863                            pSpikePoints[nSpikeCounter] = new POINT2(pFlotStart[k]);
1864                            pSpikePoints[nSpikeCounter++].style = 5;
1865
1866                            if (k == lNumSpikes - 2) {
1867                                pSpikePoints[nSpikeCounter] = new POINT2(pFlotEnd[k + 1]);
1868                                pSpikePoints[nSpikeCounter++].style = 19;
1869                                pSpikePoints[nSpikeCounter] = new POINT2(pFlotStart[k + 1]);
1870                                pSpikePoints[nSpikeCounter++].style = 5;
1871                            }
1872
1873                            pSpikePoints[nSpikeCounter] = new POINT2(pSpikeEnd[k]);
1874                            pSpikePoints[nSpikeCounter++].style = 25;
1875                            pSpikePoints[nSpikeCounter] = new POINT2(pSpikeStart[k]);
1876                            pSpikePoints[nSpikeCounter++].style = 5;
1877                        }
1878                    }
1879                    if (lineType == (long) TacticalLines.SFG) {
1880                        pSpikePoints[nSpikeCounter++] = lineutility.ExtendAlongLineDouble(pSpikeStart[k], pLinePoints[j], dSpikeSize / 2, 22);
1881                        pSpikePoints[nSpikeCounter++] = lineutility.ExtendAlongLineDouble(pSpikeEnd[k], pLinePoints[j + 1], dSpikeSize / 2, 20);
1882                    }
1883                    if (lineType == (long) TacticalLines.SFY) {
1884
1885                        d1 = lineutility.CalcDistanceDouble(pFlotStart[k], pSpikeStart[k]);
1886                        pSpikePoints[nSpikeCounter] = lineutility.ExtendAlongLineDouble(pSpikeStart[k], pLinePoints[j], d1 / 4);        //was dSpikeSize/4
1887                        pSpikePoints[nSpikeCounter].style = 25; //blue
1888                        pSpikePoints[nSpikeCounter + 1] = lineutility.ExtendAlongLineDouble(pSpikeStart[k], pLinePoints[j], d1 / 2);    //was dSpikeSize/2
1889                        pSpikePoints[nSpikeCounter + 1].style = 5;      //end of blue part
1890                        pSpikePoints[nSpikeCounter + 2] = lineutility.ExtendAlongLineDouble(pSpikeStart[k], pLinePoints[j], d1 / 2);    //was dSpikeSize/2
1891                        pSpikePoints[nSpikeCounter + 2].style = 19;     //red
1892                        pSpikePoints[nSpikeCounter + 3] = lineutility.ExtendAlongLineDouble(pSpikeStart[k], pLinePoints[j], 3 * d1 / 4);                //was 1.5*dSpikeSize/2
1893                        pSpikePoints[nSpikeCounter + 3].style = 5;      //end of red part
1894                        //the cross points
1895                        pSpikePoints[nSpikeCounter + 4] = lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter], pLinePoints[j], pSpikePoints[nSpikeCounter], 2, 5, 25);
1896                        pSpikePoints[nSpikeCounter + 5] = lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter + 3], pLinePoints[j], pSpikePoints[nSpikeCounter + 3], 3, 5, 5);
1897                        nSpikeCounter += 6;
1898
1899                        d1 = lineutility.CalcDistanceDouble(pFlotEnd[k + 1], pSpikeEnd[k]);
1900                        pSpikePoints[nSpikeCounter] = lineutility.ExtendAlongLineDouble(pSpikeEnd[k], pLinePoints[j + 1], d1 / 4);
1901                        pSpikePoints[nSpikeCounter].style = 25;
1902                        pSpikePoints[nSpikeCounter + 1] = lineutility.ExtendAlongLineDouble(pSpikeEnd[k], pLinePoints[j + 1], d1 / 2);
1903                        pSpikePoints[nSpikeCounter + 1].style = 5;
1904                        pSpikePoints[nSpikeCounter + 2] = lineutility.ExtendAlongLineDouble(pSpikeEnd[k], pLinePoints[j + 1], d1 / 2);
1905                        pSpikePoints[nSpikeCounter + 2].style = 19;
1906                        pSpikePoints[nSpikeCounter + 3] = lineutility.ExtendAlongLineDouble(pSpikeEnd[k], pLinePoints[j + 1], 3 * d1 / 4);
1907                        pSpikePoints[nSpikeCounter + 3].style = 5;
1908                        //the cross points
1909                        pSpikePoints[nSpikeCounter + 4] = lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter], pLinePoints[j + 1], pSpikePoints[nSpikeCounter], 3, 5, 19);
1910                        pSpikePoints[nSpikeCounter + 5] = lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter + 3], pLinePoints[j + 1], pSpikePoints[nSpikeCounter + 3], 2, 5, 5);
1911                        nSpikeCounter += 6;
1912
1913                    }
1914                }//for k= 0 to numSpikes-1
1915                if (nSpikeCounter == 0) {
1916                    pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j]);
1917                    pSpikePoints[nSpikeCounter].style = 5;
1918                    nSpikeCounter++;
1919                    pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1920                    pSpikePoints[nSpikeCounter].style = 5;
1921                    nSpikeCounter++;
1922                    //added 6-1-05 M. Deutch
1923                    pSpikePoints[nSpikeCounter] = new POINT2(pLinePoints[j + 1]);
1924                    pSpikePoints[nSpikeCounter].style = 5;
1925                    nSpikeCounter++;
1926                } else {
1927                    pSpikePoints[nSpikeCounter] = new POINT2(pSpikePoints[nSpikeCounter - 1]);
1928                    pSpikePoints[nSpikeCounter].style = 5;
1929                    pSpikePoints[nSpikeCounter + 1] = new POINT2(pSpikePoints[nSpikeCounter - 1]);
1930                    pSpikePoints[nSpikeCounter + 1].style = 5;
1931                    pSpikePoints[nSpikeCounter + 2] = new POINT2(pSpikePoints[nSpikeCounter - 1]);
1932                    pSpikePoints[nSpikeCounter + 2].style = 5;
1933                    nSpikeCounter += 3;
1934                }
1935            }
1936            n=pLinePoints.length;
1937            //for (j = 0; j < pLinePoints.length; j++) 
1938            for (j = 0; j < n; j++) 
1939            {
1940                pLinePoints[j] = new POINT2(pSpikePoints[0]);
1941                pLinePoints[j].style = 5;
1942            }
1943            //load the spike points into the array
1944            nTotalCounter = 0;
1945            for (j = 0; j < nFlotCounter; j++) {
1946                pLinePoints[nTotalCounter++] = new POINT2(pFlotPoints[j]);
1947            }
1948            for (j = 0; j < nSpikeCounter; j++) {
1949                pLinePoints[nTotalCounter++] = new POINT2(pSpikePoints[j]);
1950            }
1951            for (j = 0; j < nSegCounter; j++) {
1952                pLinePoints[nTotalCounter++] = new POINT2(pSegPoints[j]);
1953            }
1954            n=pLinePoints.length;
1955            //for (j = nTotalCounter; j < pLinePoints.length; j++) 
1956            for (j = nTotalCounter; j < n; j++) 
1957            {
1958                pLinePoints[j] = new POINT2(pLinePoints[nTotalCounter - 1]);
1959            }
1960
1961        } catch (Exception exc) {
1962            ErrorLogger.LogException(_className ,"GetSFPointsDouble",
1963                    new RendererException("Failed inside GetSFPointsDouble", exc));
1964        }
1965        return nTotalCounter;
1966    }
1967
1968    protected static int GetSFCountDouble(POINT2[] pLinePoints, int numPts) {
1969        int lTotalpts = 0;
1970        try {
1971            int j = 0, lNumSegs = 0;
1972            int lNumFlots = 0, lNumSpikes = 0;
1973            double dDistance = 0;
1974            //end declarations
1975
1976            //for each segment
1977            for (j = 0; j < numPts - 1; j++) {
1978                dDistance = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
1979                lNumSegs = (int) (dDistance / 80);
1980                lNumFlots = lNumSegs;
1981                lNumSpikes = lNumSegs;
1982                if (lNumFlots < 1) {
1983                    lNumFlots = 1;
1984                }
1985                if (lNumSpikes < 1) {
1986                    lNumSpikes = 1;
1987                }
1988                lTotalpts += lNumFlots * 10; //10 points per flot,
1989                lTotalpts += lNumSpikes * 3; //3 points per spike
1990                lTotalpts += lNumSegs * 16;     // points for line features
1991                lTotalpts += numPts * 4;
1992            }
1993            if (lTotalpts < 25 * numPts) {
1994                lTotalpts = 25 * numPts;
1995            }
1996
1997            if (lTotalpts < numPts) {
1998                lTotalpts = numPts;
1999            }
2000
2001        } catch (Exception exc) {
2002            ErrorLogger.LogException(_className ,"GetSFCountDouble",
2003                    new RendererException("Failed inside GetSFCountDouble", exc));
2004        }
2005        return lTotalpts;
2006    }
2007}