001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005
006package armyc2.c5isr.JavaLineArray;
007
008import java.util.ArrayList;
009import java.util.Arrays;
010
011import armyc2.c5isr.JavaTacticalRenderer.TGLight;
012import armyc2.c5isr.JavaTacticalRenderer.clsUtility;
013import armyc2.c5isr.graphics2d.BasicStroke;
014import armyc2.c5isr.graphics2d.Font;
015import armyc2.c5isr.graphics2d.Rectangle2D;
016import armyc2.c5isr.renderer.utilities.ErrorLogger;
017import armyc2.c5isr.renderer.utilities.RendererException;
018import armyc2.c5isr.renderer.utilities.RendererSettings;
019
020/**
021 * A class which imported many of the C++ functions from Trident
022 * Systems Dismounted Intelligence Situational Awareness System (DISM) for
023 * rendering Mil-Standard-2525 tactical lines. This class does not get instantiated
024 * Much of the code is still the original DISM code.
025 */
026public final class DISMSupport
027{
028    private static final int LEFT_SIDE=0;
029    private static final int RIGHT_SIDE=1;
030    private static final int COLINEAR=2;
031
032    private static final double CONST_PI = Math.PI;
033    private static final double maxLength=100;
034    private static final double minLength=2.5;    //was 5
035    private static final String _className="DISMSupport";
036    
037//    protected static void setMinLength(double mLength)
038//    {
039//        minLength=mLength;
040//    }
041    private static double GetTGFontSize(double iLength)
042    {
043        double result=-1;
044        try
045        {
046            if (iLength < 20)
047                result = 0;
048            else if (iLength < 50)
049                result = 1;
050            else if (iLength > 250)
051                result = 3;
052            else
053                result = 2;
054        }
055        catch(Exception exc)
056        {
057            ErrorLogger.LogException(_className ,"GetTGFontSize",
058                    new RendererException("Failed inside GetTGFontSize", exc));
059        }
060        return result;
061    }
062    private static void ArcApproximationDouble(double left, double top, double right, double bottom,
063            double startx, double starty, double endx, double endy, POINT2[] lpoints)
064    {
065
066        try
067        {
068            double dstartx = startx;
069            double dstarty = starty;
070            double dendx = endx;
071            double dendy = endy;
072            double a = 0;
073            double b = 0;
074            double ctrX = 0;
075            double ctrY = 0;
076            double x1, y1, x2, y2;
077            double startAngle, endAngle;
078            double angleIncrement = 0;
079            double t=0;
080
081            int i = 0;
082            if (left > right)
083            {
084                double temp = left;
085                left = right;
086                right = temp;
087            }
088            if (top > bottom)
089            {
090                double temp = top;
091                top = bottom;
092                bottom = temp;
093            }
094
095            a = (right - left) / 2.0;
096            b = (bottom - top) / 2.0;
097            ctrX = left + a;
098            ctrY = top + b;
099
100            x1 = dstartx - ctrX;
101            x2 = dendx - ctrX;
102            y1 = ctrY - dstarty;
103            y2 = ctrY - dendy;
104
105            if (y1 == 0)
106            {
107                if (x1 > 0) startAngle = 0;
108                else startAngle = CONST_PI;
109            }
110            else if (x1 == 0)
111            {
112                if (y1 > 0) startAngle = CONST_PI * 0.5;
113                else startAngle = CONST_PI * -0.5;
114            }
115            else startAngle = Math.atan2(y1, x1);
116
117            if (y2 == 0)
118            {
119                if (x2 > 0) endAngle = 0;
120                else endAngle = CONST_PI;
121            }
122            else if (x2 == 0)
123            {
124                if (y2 > 0) endAngle = CONST_PI * 0.5;
125                else endAngle = CONST_PI * -0.5;
126            }
127            else endAngle = Math.atan2(y2, x2);
128
129            if (endAngle <= startAngle) endAngle += 2 * CONST_PI;
130            angleIncrement = (endAngle - startAngle) / 16.0;
131
132            for (t = startAngle; i < 17; t += angleIncrement, i++)
133            {
134                lpoints[i].x = ctrX + a * Math.cos(t);
135                lpoints[i].y = ctrY - b * Math.sin(t);
136            }
137            return;
138        }
139        catch(Exception exc)
140        {
141            ErrorLogger.LogException(_className ,"ArcApproximationDouble",
142                    new RendererException("Failed inside ArcApproximationDouble", exc));
143        }
144    }
145    private static void DrawOpenRectangleDouble(POINT2[] points, POINT2[] pointsCorner, POINT2[] resultpts) {
146        try {
147            // draw open-ended rectangle
148            POINT2 point_mid = new POINT2();
149            int j = 0;
150            //  POINT1 pts[4];
151            point_mid.x = (points[0].x + points[1].x) / 2;
152            point_mid.y = (points[0].y + points[1].y) / 2;
153            pointsCorner[0].x = points[0].x - point_mid.x + points[2].x;
154            pointsCorner[0].y = points[0].y - point_mid.y + points[2].y;
155            pointsCorner[1].x = points[1].x - point_mid.x + points[2].x;
156            pointsCorner[1].y = points[1].y - point_mid.y + points[2].y;
157            resultpts[0] = new POINT2(points[1]);
158            resultpts[1] = new POINT2(pointsCorner[1]);
159            resultpts[2] = new POINT2(pointsCorner[0]);
160            resultpts[3] = new POINT2(points[0]);
161            for (j = 0; j < 4; j++) {
162                resultpts[j].style = 0;
163            }
164            resultpts[3].style = 5;
165            
166        } catch (Exception exc) {
167            ErrorLogger.LogException(_className ,"DrawOpenRectangleDouble",
168                    new RendererException("Failed inside DrawOpenRectangleDouble", exc));
169        }
170        return;
171    }
172    private static int DetermineDirectionDouble(POINT2[] points) {
173        int result=0;
174        try {
175            double dP0P1M = 0;
176            double iP0P1B = 0;
177            if (points[0].x == points[1].x) {
178                if (points[2].x < points[0].x) {
179                    return 1;
180                } else {
181                    return 0;
182                }
183            } else {
184                // dP0P1M = slope of line between Point0 and Point1
185                dP0P1M = (double) (points[0].y - points[1].y) / (double) (points[0].x - points[1].x);
186                // iP0P1B = b component of y=mx+b equation of line
187                iP0P1B = (points[0].y - dP0P1M * points[0].x);
188                if (((points[2].y - iP0P1B) / dP0P1M) > points[2].x) {
189                    return 1;
190                } else {
191                    return 0;
192                }
193            }
194        } catch (Exception exc) {
195            ErrorLogger.LogException(_className ,"DetermineDirectionDouble",
196                    new RendererException("Failed inside DetermineDirectionDouble", exc));
197        }
198        return result;
199    }
200    private static void CalcEndpieceDeltasDouble(POINT2[] points, ref
201        <double[]> piDeltaX, ref <double[]> piDeltaY,
202        double dAngleDelta
203               )
204    {
205        try {
206            // find midpoint between point0 and point1
207            POINT2 pntMid = new POINT2();
208            double iDiagEOL_length = 0;
209            double dAngle1 = 0;
210
211            pntMid.x = (points[0].x + points[1].x) / 2;
212            pntMid.y = (points[0].y + points[1].y) / 2;
213            // iDiagEOL_length = length of the diagonal on end of line from line out to endpoint
214            iDiagEOL_length =  ((Math.sqrt // height of graphic
215                    (
216                    (points[1].x - points[0].x) * (points[1].x - points[0].x) +
217                    (points[1].y - points[0].y) * (points[1].y - points[0].y)) +
218                    Math.sqrt // length of graphic
219                    (
220                    (points[2].x - pntMid.x) * (points[2].x - pntMid.x) +
221                    (points[2].y - pntMid.y) * (points[2].y - pntMid.y))) / 20);
222
223            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
224            if ((double) iDiagEOL_length > maxLength/5 * DPIScaleFactor) {
225                iDiagEOL_length = maxLength/5 * DPIScaleFactor;
226            }
227            if ((double) iDiagEOL_length < minLength * DPIScaleFactor) {
228                iDiagEOL_length = minLength * DPIScaleFactor;
229            }
230
231            // dAngle1 = angle used to calculate the end-piece deltas
232            dAngle1 = Math.atan2(points[2].y - pntMid.y, points[2].x - pntMid.x) + dAngleDelta;
233            //  dAngle1 = atan2(points[2].y - pntMid.y, points[2].x - pntMid.x) + dAngleDelta;
234            piDeltaX.value=new double[1];
235            piDeltaY.value=new double[1];
236            piDeltaX.value[0] =  (iDiagEOL_length * Math.cos(dAngle1));
237            piDeltaY.value[0] = (iDiagEOL_length * Math.sin(dAngle1));
238            return;
239        } catch (Exception exc) {
240            ErrorLogger.LogException(_className ,"CalcEndpieceDeltasDouble",
241                    new RendererException("Failed inside CalcEndpieceDeltasDouble", exc));
242        }
243    }
244    /**
245     * Calculates the points for line24 and line33 (DELAY, WITHDRAW, DISENGAGE, WDRAWUP, RETIRE, FPOL, RPOL, PURSUIT)
246     *
247     * @param points OUT - the client points, also used for the returned points.
248     */
249    protected static int GetDelayGraphicEtcDouble(POINT2[] points, int lineType) {
250        int counter=0;
251        try {
252            POINT2[] savepoints = new POINT2[3];
253            double iLength = 0;
254            double iRadius = 0;
255            double iDiagEOL_length = 0;
256            double dAngle1 = 0;
257            double iDeltaX1 = 0;
258            double iDeltaY1 = 0;
259            double iDeltaX2 = 0;
260            double iDeltaY2 = 0;
261            POINT2 ptArcCenter = new POINT2();
262            POINT2[] arcpoints = new POINT2[17];
263            POINT2[] deltapoints = new POINT2[4];
264            int j = 0;
265
266            // Make arc perpendicular to line
267            points[2] = lineutility.PointRelativeToLine(points[0], points[1], points[1], points[2]);
268
269            for (j = 0; j < 3; j++) {
270                savepoints[j] = new POINT2(points[j]);
271            }
272
273            lineutility.InitializePOINT2Array(arcpoints);
274            lineutility.InitializePOINT2Array(deltapoints);
275
276            points[counter] = new POINT2(savepoints[0]);
277            points[counter].style = 14;
278            counter++;
279            points[counter] = new POINT2(savepoints[1]);
280            points[counter].style = 5;
281            counter++;
282
283            iLength = Math.sqrt((savepoints[1].x - savepoints[0].x) * (savepoints[1].x - savepoints[0].x) +
284                    (savepoints[1].y - savepoints[0].y) * (savepoints[1].y - savepoints[0].y));
285            iRadius = Math.sqrt((savepoints[2].x - savepoints[1].x) * (savepoints[2].x - savepoints[1].x) +
286                    (savepoints[2].y - savepoints[1].y) * (savepoints[2].y - savepoints[1].y)) / 2;
287            iDiagEOL_length = (iLength + iRadius * 2) / 20;
288            if (lineType == TacticalLines.PURSUIT)
289                dAngle1 = Math.atan2(points[2].y - points[1].y, points[2].x - points[1].x);
290            else
291                dAngle1 = Math.atan2(points[1].y - points[0].y, points[1].x - points[0].x);
292
293            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
294            if ((double) iDiagEOL_length > maxLength * DPIScaleFactor) {
295                iDiagEOL_length = maxLength * DPIScaleFactor;
296            }
297            if ((double) iDiagEOL_length < minLength * DPIScaleFactor) {   //was minLength
298                iDiagEOL_length = minLength * DPIScaleFactor;
299            }
300
301            // draw the semicircle
302            ptArcCenter.x = (savepoints[1].x + savepoints[2].x) / 2;
303            ptArcCenter.y = (savepoints[1].y + savepoints[2].y) / 2;
304            boolean reverseArc = ReverseDelayArc(savepoints);
305            if (reverseArc == false) {
306                ArcApproximationDouble( (ptArcCenter.x - iRadius), (ptArcCenter.y - iRadius),
307                        (ptArcCenter.x + iRadius), (ptArcCenter.y + iRadius),
308                        savepoints[1].x, savepoints[1].y, savepoints[2].x, savepoints[2].y, arcpoints);
309                if (lineType == TacticalLines.PURSUIT)
310                    dAngle1 += CONST_PI / 2;
311            } else {
312                ArcApproximationDouble((ptArcCenter.x - iRadius), (ptArcCenter.y - iRadius),
313                        (ptArcCenter.x + iRadius), (ptArcCenter.y + iRadius),
314                        savepoints[2].x, savepoints[2].y, savepoints[1].x, savepoints[1].y, arcpoints);
315                if (lineType == TacticalLines.PURSUIT)
316                    dAngle1 -= CONST_PI / 2;
317            }
318
319            // draw the arrow
320            iDeltaX1 = (iDiagEOL_length * Math.cos(dAngle1 - CONST_PI / 4));
321            iDeltaY1 = (iDiagEOL_length * Math.sin(dAngle1 - CONST_PI / 4));
322            iDeltaX2 = (iDiagEOL_length * Math.cos(dAngle1 + CONST_PI / 4));
323            iDeltaY2 = (iDiagEOL_length * Math.sin(dAngle1 + CONST_PI / 4));
324            if (lineType == TacticalLines.PURSUIT)
325                DrawEndpieceDeltasDouble(savepoints[2],
326                        iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints);
327            else
328                DrawEndpieceDeltasDouble(savepoints[0],
329                        iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints);
330
331            for (j = 0; j < 4; j++) {
332                points[counter] = new POINT2(deltapoints[j]);
333                counter++;
334            }
335
336            for (j = 0; j < 17; j++) {
337                points[counter] = new POINT2(arcpoints[j]);
338                points[counter].style = 0;
339                counter++;
340            }
341            points[counter-1].style = 5;
342
343            if (lineType == TacticalLines.PURSUIT) {
344                // draw the line perpendicular to arrow
345                points[counter] = lineutility.ExtendAlongLineDouble(savepoints[1], savepoints[2], iRadius * 2 - iDiagEOL_length, 0);
346                counter++;
347                points[counter] = lineutility.ExtendAlongLineDouble(savepoints[1], savepoints[2], iRadius * 2 + iDiagEOL_length, 0);
348                counter++;
349            }
350        } catch (Exception exc) {
351            ErrorLogger.LogException(_className ,"GetDelayGraphicEtcDouble",
352                    new RendererException("Failed inside GetDelayGraphicEtcDouble", exc));
353        }
354        return counter;
355    }
356
357    private static boolean IsEnvelopmentArcReversed(POINT2[] pPoints) {
358        try {
359            if (pPoints.length < 4) {
360                return false;
361            }
362
363            POINT2[] ptsSeize = new POINT2[2];
364            ptsSeize[0] = new POINT2(pPoints[1]);
365            ptsSeize[1] = new POINT2(pPoints[2]);
366            lineutility.CalcClockwiseCenterDouble(ptsSeize);
367            double d = lineutility.CalcDistanceDouble(ptsSeize[0], pPoints[3]);
368
369            ptsSeize[0] = new POINT2(pPoints[2]);
370            ptsSeize[1] = new POINT2(pPoints[1]);
371            lineutility.CalcClockwiseCenterDouble(ptsSeize);
372            double dArcReversed = lineutility.CalcDistanceDouble(ptsSeize[0], pPoints[3]);
373
374            return dArcReversed > d;
375        } catch (Exception exc) {
376            ErrorLogger.LogException(_className, "IsEnvelopmentArcReversed",
377                    new RendererException("IsEnvelopmentArcReversed", exc));
378        }
379        return false;
380    }
381
382    public static POINT2[] GetInfiltrationDouble(POINT2[] points) {
383        int counter = 0;
384
385        POINT2 p1 = points[0];//start
386        POINT2 p3 = points[1];//mid
387        POINT2 p5 = points[2];//end
388        POINT2 start = points[0];//start
389        POINT2 mid = points[1];//mid
390        POINT2 end = points[2];//end
391        POINT2 p2= new POINT2(0,0,1);
392        POINT2 p4 = new POINT2(0,0,1);
393        p1.style=0;
394
395
396
397        double dpi = RendererSettings.getInstance().getDeviceDPI();
398        double scale = 4;
399
400        if(p5.x==0 && p5.y==0)//handle points drop when all 3 on top of each other.
401        {
402            p5.x=p3.x;
403            p5.y=p3.y;
404        }
405
406        int d1 = (int)lineutility.CalcDistanceDouble(p1,p3);
407        int d2 = (int)lineutility.CalcDistanceDouble(p3,p5);
408
409        //force some distance so render doesn't fail when points too close
410        if(d1==0) {
411            p1.x = p1.x - 1;
412            p1.y = p1.y - 1;
413        }
414        if(d2==0) {
415            p5.x = p5.x + 1;
416            p5.y = p5.y + 1;
417        }
418
419        double arcDistance = dpi/scale;
420
421        POINT2 anchor1 = new POINT2();
422        POINT2 anchor2 = new POINT2();
423        if(p5.y >= p3.y)//end point lower than mid point
424        {
425            p2.y = p3.y - arcDistance;
426            p4.y = p3.y + arcDistance;
427        }
428        else//end point higher than mid point
429        {
430            p2.y = p3.y + arcDistance;
431            p4.y = p3.y - arcDistance;
432        }
433
434        arcDistance = dpi/scale;
435        if(d2 < arcDistance)
436            arcDistance = Math.max(d2*0.5,3);
437        if(p5.x >= p3.x)
438        {
439            p2.x = p3.x - arcDistance;
440            p4.x = p3.x + arcDistance;
441        }
442        else
443        {
444            p2.x = p3.x + arcDistance;
445            p4.x = p3.x - arcDistance;
446        }
447        anchor1.x=p2.x;
448        anchor1.y=p3.y;
449
450        anchor2.x=p4.x;
451        anchor2.y=p3.y;
452
453
454        ArrayList<POINT2> path = new ArrayList<>();
455
456        try {
457
458            // Draw the first straight line segment (p1 to p2)
459            //g2d.drawLine(p1.x, p1.y, p2.x, p2.y);
460            path.add(p1);
461            //path.add(p2);//first curve is going to add this point again
462
463            // Draw the first 45-degree arc (concave) from p2 to p3
464            //drawArc(g2d, p2, p3, true, 5);
465            //path.addAll(getArc(p2, p3, false, 5));
466            if(arcDistance < d1) {
467                path.addAll(lineutility.GetArcPointsDouble(p2, p3, anchor1, 5));
468                path.remove(path.size() - 1);//next curve is going to add this point again.
469            }
470
471
472            // Draw the second 45-degree arc (convex) from p3 to p4
473            //drawArc(g2d, p3, p4, false, 5);
474            //path.addAll(getArc(p3, p4, true, 5));
475            if(arcDistance < d2)
476                path.addAll(lineutility.GetArcPointsDouble(p3, p4, anchor2, 5));
477            else
478                path.add(p3);
479
480            // Draw the second straight line segment (p4 to p5)
481            //g2d.drawLine(p4.x, p4.y, p5.x, p5.y);
482            path.add(p5);
483
484        }
485        catch(Exception exc)
486        {
487            ErrorLogger.LogException("","",exc);
488        }
489
490        int lcv = 0;
491        points = new POINT2[path.size() + 3];
492
493        for(POINT2 pt : path)
494        {
495            if(lcv == 0)
496                pt.style = 0;
497            else
498                pt.style=1;
499            points[lcv] = pt;
500            lcv++;
501        }
502
503        return points;
504    }
505
506    /**
507     * Calculates the points for ENVELOPMENT
508     *
509     * @param points OUT - the client points, also used for the returned points.
510     */
511    protected static int GetEnvelopmentGraphicDouble(POINT2[] points) {
512        int counter=0;
513        try {
514            double iLength = 0;
515            double iRadius = 0;
516            double iDiagEOL_length = 0;
517            double dAngle1 = 0;
518            double iDeltaX1 = 0;
519            double iDeltaY1 = 0;
520            double iDeltaX2 = 0;
521            double iDeltaY2 = 0;
522            POINT2 ptArcCenter = new POINT2();
523            POINT2[] arcpoints = new POINT2[17];
524            POINT2[] deltapoints = new POINT2[4];
525            int j = 0;
526
527            lineutility.InitializePOINT2Array(arcpoints);
528            lineutility.InitializePOINT2Array(deltapoints);
529
530            boolean reverseArc = IsEnvelopmentArcReversed(points);
531
532            points[0].style = 14;
533            counter++;
534            points[1].style = 5;
535            counter++;
536
537            // Place pt3 on line pt1pt2
538            points[2] = lineutility.ClosestPointOnLine(points[0], lineutility.ExtendLine2Double(points[0], points[1], lineutility.CalcDistanceDouble(points[1], points[2]), 0), points[2]);
539
540            iLength =  Math.sqrt((points[1].x - points[0].x) * (points[1].x - points[0].x) +
541                    (points[1].y - points[0].y) * (points[1].y - points[0].y));
542            iRadius =  Math.sqrt((points[2].x - points[1].x) * (points[2].x - points[1].x) +
543                    (points[2].y - points[1].y) * (points[2].y - points[1].y)) / 2;
544            iDiagEOL_length = (iLength + iRadius * 2) / 20;
545            dAngle1 = Math.atan2(points[2].y - points[1].y, points[2].x - points[1].x);
546
547            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
548            if (iDiagEOL_length > maxLength * DPIScaleFactor) {
549                iDiagEOL_length = maxLength * DPIScaleFactor;
550            }
551            if (iDiagEOL_length < minLength * DPIScaleFactor) {   //was minLength
552                iDiagEOL_length = minLength * DPIScaleFactor;
553            }
554
555            // draw the semicircle
556            ptArcCenter.x = (points[1].x + points[2].x) / 2;
557            ptArcCenter.y = (points[1].y + points[2].y) / 2;
558            if (reverseArc) {
559                ArcApproximationDouble((ptArcCenter.x - iRadius), (ptArcCenter.y - iRadius),
560                        (ptArcCenter.x + iRadius), (ptArcCenter.y + iRadius),
561                        points[1].x, points[1].y, points[2].x, points[2].y, arcpoints);
562                dAngle1 += CONST_PI / 2;
563            } else {
564                ArcApproximationDouble((ptArcCenter.x - iRadius), (ptArcCenter.y - iRadius),
565                        (ptArcCenter.x + iRadius), (ptArcCenter.y + iRadius),
566                        points[2].x, points[2].y, points[1].x, points[1].y, arcpoints);
567                dAngle1 -= CONST_PI / 2;
568            }
569
570            // draw the arrow
571            iDeltaX1 = (iDiagEOL_length * Math.cos(dAngle1 - CONST_PI / 4));
572            iDeltaY1 = (iDiagEOL_length * Math.sin(dAngle1 - CONST_PI / 4));
573            iDeltaX2 = (iDiagEOL_length * Math.cos(dAngle1 + CONST_PI / 4));
574            iDeltaY2 = (iDiagEOL_length * Math.sin(dAngle1 + CONST_PI / 4));
575            DrawEndpieceDeltasDouble(points[2],
576                    iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints);
577
578            for (j = 0; j < 4; j++) {
579                points[counter] = new POINT2(deltapoints[j]);
580                counter++;
581            }
582
583            for (j = 0; j < 17; j++) {
584                points[counter] = new POINT2(arcpoints[j]);
585                points[counter].style = 0;
586                counter++;
587            }
588            points[counter-1].style = 5;
589        } catch (Exception exc) {
590            ErrorLogger.LogException(_className ,"GetEnvelopmentGraphicDouble",
591                    new RendererException("Failed inside GetEnvelopmentGraphicDouble", exc));
592        }
593        return counter;
594    }
595    /**
596     * Calculates the points for SCREEN, COVER, GUARD, SARA.
597     *
598     * @param points OUT - the client points, also used for the returned points.
599     * @param lineType the line type.
600     */
601    protected static int GetDISMCoverDouble(POINT2[] points,
602                                            int lineType) {
603        int counter = 0;
604        try {
605            POINT2 pt0 = new POINT2(points[0]);
606            POINT2 pt1 = new POINT2(points[1]);
607            POINT2 pt2 = new POINT2(points[2]);
608            POINT2 pt3 = new POINT2();
609            POINT2 pt4 = new POINT2();
610
611            lineutility.LineRelativeToLine(pt1, pt2, pt0, pt3, pt4);
612            //now we have the pt3-pt4 line which pt0 is on
613            //get the corresponding point back on the original line
614            lineutility.LineRelativeToLine(pt3, pt0, pt1, pt2, pt4);
615            final int quadrant = lineutility.GetQuadrantDouble(pt0, pt4);
616
617            pt1 = new POINT2(points[1]);
618            pt2 = new POINT2(points[2]);
619            final int sign;
620            if (pt1.x < pt2.x && (quadrant == 1 || quadrant == 4))
621                sign = -1;
622            else if (pt1.x > pt2.x && (quadrant == 2 || quadrant == 3))
623                sign = -1;
624            else
625                sign = 1;
626
627            POINT2 initialPt = new POINT2(points[0]);
628            initialPt.style = 0;
629            POINT2 endPt0 = new POINT2(points[1]);
630            endPt0.style = 0;
631            POINT2 endPt1 = new POINT2(points[2]);
632            endPt1.style = 0;
633
634            // Get length of each line from initial point
635            double length1 = lineutility.CalcDistanceDouble(initialPt, endPt0);
636            double length2 = lineutility.CalcDistanceDouble(initialPt, endPt1);
637            length1 = Math.min(length1, length2);
638
639            if (GetTGFontSize(length1) > 0) {
640                double delta = length1 / 15;
641
642                double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
643                if (delta > maxLength * DPIScaleFactor) {
644                    delta = maxLength * DPIScaleFactor;
645                }
646                if (delta < minLength * DPIScaleFactor) {
647                    delta = minLength * DPIScaleFactor;
648                }
649
650                POINT2[] ptsJaggyLine = new POINT2[4];
651                lineutility.InitializePOINT2Array(ptsJaggyLine);
652
653                // Draw jaggy line 1
654                final double angle0 = Math.atan2(initialPt.y - endPt0.y, initialPt.x - endPt0.x);
655                final double deltaX0a = Math.cos(angle0 + sign * CONST_PI / 4) * delta;
656                final double deltaY0a = Math.sin(angle0 + sign * CONST_PI / 4) * delta;
657                ptsJaggyLine[0] = new POINT2(initialPt);
658                if (lineType != TacticalLines.SARA) {
659                    ptsJaggyLine[0].x -= 30 * Math.cos(angle0);  //was 20
660                    ptsJaggyLine[0].y -= 30 * Math.sin(angle0);
661                }
662                POINT2 midPt0 = lineutility.MidPointDouble(ptsJaggyLine[0], endPt0, 0);
663                ptsJaggyLine[1].x = midPt0.x - deltaX0a;
664                ptsJaggyLine[1].y = midPt0.y - deltaY0a;
665                ptsJaggyLine[2].x = midPt0.x + deltaX0a;
666                ptsJaggyLine[2].y = midPt0.y + deltaY0a;
667                ptsJaggyLine[3] = new POINT2(endPt0);
668                for (int j = 0; j < 4; j++) {
669                    points[counter] = new POINT2(ptsJaggyLine[j]);
670                    counter++;
671                }
672                points[counter - 1].style = 5;
673
674                // Draw Arrow 1
675                final double deltaX0b = Math.cos(angle0 - sign * CONST_PI / 4) * delta;
676                final double deltaY0b = Math.sin(angle0 - sign * CONST_PI / 4) * delta;
677                ptsJaggyLine[0].x = ptsJaggyLine[3].x + deltaX0a;
678                ptsJaggyLine[0].y = ptsJaggyLine[3].y + deltaY0a;
679                ptsJaggyLine[1] = new POINT2(ptsJaggyLine[3]);
680                ptsJaggyLine[2].x = ptsJaggyLine[3].x + deltaX0b;
681                ptsJaggyLine[2].y = ptsJaggyLine[3].y + deltaY0b;
682                for (int j = 0; j < 3; j++) {
683                    points[counter] = new POINT2(ptsJaggyLine[j]);
684                    points[counter].style = 0;
685                    if (lineType == TacticalLines.SARA) {
686                        points[counter].style = 9;
687                    }
688
689                    counter++;
690                }
691                points[counter - 1].style = 5;
692                if (lineType == TacticalLines.SARA) {
693                    points[counter - 1].style = 9;
694                    points[counter] = new POINT2(points[counter - 3]);
695                    points[counter].style = 10;
696                    counter++;
697                }
698
699                // Draw jaggy line 2
700                final double angle1 = Math.atan2(initialPt.y - endPt1.y, initialPt.x - endPt1.x);
701                final double deltaX1a = Math.cos(angle1 - sign * CONST_PI / 4) * delta;
702                final double deltaY1a = Math.sin(angle1 - sign * CONST_PI / 4) * delta;
703                ptsJaggyLine[0] = new POINT2(initialPt);
704                if (lineType != TacticalLines.SARA) {
705                    ptsJaggyLine[0].x -= 30 * Math.cos(angle1);  //was 20
706                    ptsJaggyLine[0].y -= 30 * Math.sin(angle1);
707                }
708                POINT2 midPt1 = lineutility.MidPointDouble(ptsJaggyLine[0], endPt1, 0);
709                ptsJaggyLine[1].x = midPt1.x - deltaX1a;
710                ptsJaggyLine[1].y = midPt1.y - deltaY1a;
711                ptsJaggyLine[2].x = midPt1.x + deltaX1a;
712                ptsJaggyLine[2].y = midPt1.y + deltaY1a;
713                ptsJaggyLine[3] = new POINT2(endPt1);
714                for (int j = 0; j < 4; j++) {
715                    points[counter] = new POINT2(ptsJaggyLine[j]);
716                    counter++;
717                }
718                points[counter - 1].style = 5;
719
720                // Draw Arrow 2
721                final double deltaX1b = Math.cos(angle1 + sign * CONST_PI / 4) * delta;
722                final double deltaY1b = Math.sin(angle1 + sign * CONST_PI / 4) * delta;
723                ptsJaggyLine[0].x = ptsJaggyLine[3].x + deltaX1a;
724                ptsJaggyLine[0].y = ptsJaggyLine[3].y + deltaY1a;
725                ptsJaggyLine[1] = new POINT2(ptsJaggyLine[3]);
726                ptsJaggyLine[2].x = ptsJaggyLine[3].x + deltaX1b;
727                ptsJaggyLine[2].y = ptsJaggyLine[3].y + deltaY1b;
728                for (int j = 0; j < 3; j++) {
729                    points[counter] = new POINT2(ptsJaggyLine[j]);
730                    points[counter].style = 0;
731                    if (lineType == TacticalLines.SARA)
732                        points[counter].style = 9;
733
734                    counter++;
735                }
736                points[counter - 1].style = 5;
737                if (lineType == TacticalLines.SARA) {
738                    points[counter - 1].style = 9;
739                    points[counter] = new POINT2(points[counter - 3]);
740                    points[counter].style = 10;
741                    counter++;
742                }
743            } else {
744                points[0] = new POINT2(initialPt);
745                points[0].style = 0;
746                points[1] = new POINT2(endPt0);
747                points[1].style = 5;
748                points[2] = new POINT2(initialPt);
749                points[2].style = 0;
750                points[3] = new POINT2(endPt1);
751                return 4;
752            }
753        } catch (Exception exc) {
754            ErrorLogger.LogException(_className, "GetDISMcoverDouble",
755                    new RendererException("Failed inside GetDISMCoverDouble", exc));
756        }
757        return counter;
758    }
759    /**
760     * rev C uses 4 
761     * @param points
762     * @param linetype
763     * @return
764     */
765    protected static int GetDISMCoverDoubleRevC(POINT2[] points,
766                                            int linetype,
767                                            int vblSaveCounter) 
768    {
769            int counter = 0;
770        try 
771        {                        
772            // switch points[1] and points[2] if they are backwards
773            double dAngle0=0, dDeltaX0=0, dDeltaY0=0, dDeltaX1=0, dDeltaY1=0;
774            double iLengthPt0Pt1 = 0;
775            double iLengthPt0Pt2 = 0;
776            double iDelta = 0;
777            int j=0;
778            int t=1;
779            double iFontSize = 0;
780            double iLetterOffset = 0;
781            POINT2[] savepoints = new POINT2[3];
782            POINT2[] pts = new POINT2[2];
783            POINT2[] ptsJaggyLine = new POINT2[4];
784            //float scale = 1;
785            boolean goLeftThenRight=false;
786            int sign=1;
787            
788            //rev C with 4 points
789            POINT2[]origPoints=null;
790            if(vblSaveCounter==4)
791            {
792                origPoints=new POINT2[4];
793                for(j=0;j<vblSaveCounter;j++)
794                    origPoints[j]=new POINT2(points[j]);
795                
796                //reorder points
797                points[1]=origPoints[0];
798                points[2]=origPoints[3];
799                points[0].x=(origPoints[1].x+origPoints[2].x)/2;
800                points[0].y=(origPoints[1].y+origPoints[2].y)/2;
801            }
802                        
803            //added section for jaggy line orientation M. Deutch 6-24-11
804            POINT2 pt0=new POINT2(points[0]);
805            POINT2 pt1=new POINT2(points[1]);
806            POINT2 pt2=new POINT2(points[2]);
807            POINT2 pt3=new POINT2();
808            POINT2 pt4=new POINT2();                        
809            
810            lineutility.LineRelativeToLine(pt1, pt2, pt0, pt3, pt4);
811            //now we have the pt3-pt4 line which pt0 is on
812            //get the corresponding point back on the original line
813            lineutility.LineRelativeToLine(pt3, pt0, pt1, pt2, pt4);
814            int quadrant=lineutility.GetQuadrantDouble(pt0, pt4);
815
816            pt1=new POINT2(points[1]);
817            pt2=new POINT2(points[2]);
818            if(pt1.x<pt2.x && quadrant==1)
819                sign=-1;
820            else if(pt1.x > pt2.x && quadrant == 2)
821                sign=-1;
822            else if(pt1.x > pt2.x && quadrant == 3)
823                sign=-1;
824            else if(pt1.x < pt2.x && quadrant == 4)
825                sign=-1;
826            if(linetype==TacticalLines.SARA)
827                t=0;
828            
829            if(points[1].x<=points[2].x)
830                goLeftThenRight=true;
831
832            //save the points in the correct order
833            for (j = 0; j < 3; j++) {
834                savepoints[j] = new POINT2(points[j]);
835                savepoints[j].style = 0;
836            }
837
838            lineutility.InitializePOINT2Array(pts);
839            lineutility.InitializePOINT2Array(ptsJaggyLine);
840
841            iLengthPt0Pt1 = Math.sqrt((savepoints[1].x - savepoints[0].x) * (savepoints[1].x - savepoints[0].x) +
842                    (savepoints[1].y - savepoints[0].y) * (savepoints[1].y - savepoints[0].y));
843            iLengthPt0Pt2 = Math.sqrt((savepoints[2].x - savepoints[0].x) * (savepoints[2].x - savepoints[0].x) +
844                    (savepoints[2].y - savepoints[0].y) * (savepoints[2].y - savepoints[0].y));
845
846            if (iLengthPt0Pt1 > iLengthPt0Pt2) {
847                iLengthPt0Pt1 = iLengthPt0Pt2;
848            }
849            iFontSize = GetTGFontSize(iLengthPt0Pt1);
850            if (iFontSize > 0) 
851            {
852                iDelta = iLengthPt0Pt1 / 15;//was 15
853
854                double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
855                if (iDelta > maxLength * DPIScaleFactor) {
856                    iDelta = maxLength * DPIScaleFactor;
857                }
858                if (iDelta < minLength * DPIScaleFactor) {
859                    iDelta = minLength * DPIScaleFactor;
860                }
861                
862                // left side: draw letter in from the jaggy line
863                if(vblSaveCounter<4)//rev b
864                {
865                    if(goLeftThenRight)
866                        savepoints[0].x-=30*t;  //was 20
867                    else
868                        savepoints[0].x+=30*t;  //was 20
869                    
870                    iLetterOffset = 0;
871                    ptsJaggyLine[0].x = savepoints[0].x - iLetterOffset * 2;//was -
872                    ptsJaggyLine[0].y = savepoints[0].y;                
873                    ptsJaggyLine[0].x -= iLetterOffset;                
874                    dAngle0 = Math.atan2(ptsJaggyLine[0].y - savepoints[1].y, ptsJaggyLine[0].x - savepoints[1].x);
875                    pts[0].x = (ptsJaggyLine[0].x + savepoints[1].x) / 2;
876                    pts[0].y = (ptsJaggyLine[0].y + savepoints[1].y) / 2;
877                    dDeltaX0 = Math.cos(dAngle0 + sign*CONST_PI / 4) * iDelta;   //was +
878                    dDeltaY0 = Math.sin(dAngle0 + sign*CONST_PI / 4) * iDelta;   //was +
879                    ptsJaggyLine[1].x = pts[0].x - dDeltaX0;    //was -
880                    ptsJaggyLine[1].y = pts[0].y - dDeltaY0;    //was -
881                    ptsJaggyLine[2].x = pts[0].x + dDeltaX0;    //was +
882                    ptsJaggyLine[2].y = pts[0].y + dDeltaY0;    //was +
883                    ptsJaggyLine[3] = new POINT2(savepoints[1]);
884                    for (j = 0; j < 4; j++) 
885                    {
886                        points[counter] = new POINT2(ptsJaggyLine[j]);
887                        counter++;
888                    }
889                    points[counter - 1].style = 5;
890                }//end rev b
891                else    //rev c
892                {
893                    ptsJaggyLine[0]=new POINT2(origPoints[1]);
894                    dAngle0 = Math.atan2(ptsJaggyLine[0].y - origPoints[0].y, ptsJaggyLine[0].x - origPoints[0].x);
895                    pts[0].x = (ptsJaggyLine[0].x + origPoints[0].x) / 2;
896                    pts[0].y = (ptsJaggyLine[0].y + origPoints[0].y) / 2;
897                    dDeltaX0 = Math.cos(dAngle0 + sign*CONST_PI / 4) * iDelta;   //was +
898                    dDeltaY0 = Math.sin(dAngle0 + sign*CONST_PI / 4) * iDelta;   //was +
899                    ptsJaggyLine[1].x = pts[0].x - dDeltaX0;    //was -
900                    ptsJaggyLine[1].y = pts[0].y - dDeltaY0;    //was -
901                    ptsJaggyLine[2].x = pts[0].x + dDeltaX0;    //was +
902                    ptsJaggyLine[2].y = pts[0].y + dDeltaY0;    //was +
903                    //ptsJaggyLine[3] = new POINT2(savepoints[1]);
904                    ptsJaggyLine[3] = new POINT2(origPoints[0]);
905                    for (j = 0; j < 4; j++) 
906                    {
907                        points[counter] = new POINT2(ptsJaggyLine[j]);
908                        counter++;
909                    }
910                    points[counter - 1].style = 5;                    
911                }//end rev c
912                
913                // draw arrow at end of line
914                dDeltaX1 = Math.cos(dAngle0 - sign*CONST_PI / 4) * iDelta;   //was -
915                dDeltaY1 = Math.sin(dAngle0 - sign*CONST_PI / 4) * iDelta;   //was -
916                if(vblSaveCounter<4)
917                {
918                    ptsJaggyLine[0].x = savepoints[1].x + dDeltaX0; //was +
919                    ptsJaggyLine[0].y = savepoints[1].y + dDeltaY0; //was +
920                }
921                else
922                {
923                    ptsJaggyLine[0].x = origPoints[0].x + dDeltaX0; //was +
924                    ptsJaggyLine[0].y = origPoints[0].y + dDeltaY0; //was +                    
925                }
926                if(vblSaveCounter<4)
927                    ptsJaggyLine[1] = new POINT2(savepoints[1]);
928                else
929                    ptsJaggyLine[1] = new POINT2(origPoints[0]);
930                    
931                if(vblSaveCounter<4)
932                {
933                    ptsJaggyLine[2].x = savepoints[1].x + dDeltaX1; //was +
934                    ptsJaggyLine[2].y = savepoints[1].y + dDeltaY1; //was +
935                }
936                else
937                {
938                    ptsJaggyLine[2].x = origPoints[0].x + dDeltaX1; //was +
939                    ptsJaggyLine[2].y = origPoints[0].y + dDeltaY1; //was +                    
940                }
941                for (j = 0; j < 3; j++) {
942                    points[counter] = new POINT2(ptsJaggyLine[j]);
943                    points[counter].style = 0;
944                    if(linetype==TacticalLines.SARA || linetype==TacticalLines.MOVEMENT_TO_CONTACT)
945                    {
946                        points[counter].style = 9;
947                    }
948
949                    counter++;
950                }
951
952                points[counter - 1].style = 5;
953                if(linetype==TacticalLines.SARA || linetype==TacticalLines.MOVEMENT_TO_CONTACT)
954                {
955                    points[counter-1].style = 9;
956                    points[counter]=new POINT2(points[counter-3]);
957                    points[counter].style=10;
958                    counter++;
959                }
960
961                // right side: draw letter and jaggy line
962                if(vblSaveCounter<4)    //rev b
963                {
964                    if(goLeftThenRight)
965                        savepoints[0].x+=60*t;  //was 40
966                    else
967                        savepoints[0].x-=60*t;  //wass 40
968
969                    ptsJaggyLine[0].x = savepoints[0].x + iLetterOffset * 2;
970                    ptsJaggyLine[0].y = savepoints[0].y;
971                    ptsJaggyLine[0].x += iLetterOffset;                
972                    dAngle0 = Math.atan2(ptsJaggyLine[0].y - savepoints[2].y, ptsJaggyLine[0].x - savepoints[2].x);
973                    pts[0].x = (ptsJaggyLine[0].x + savepoints[2].x) / 2;
974                    pts[0].y = (ptsJaggyLine[0].y + savepoints[2].y) / 2;
975                    dDeltaX0 = Math.cos(dAngle0 - sign*CONST_PI / 4) * iDelta;   //was -
976                    dDeltaY0 = Math.sin(dAngle0 - sign*CONST_PI / 4) * iDelta;   //was -
977                    ptsJaggyLine[1].x = pts[0].x - dDeltaX0;    //was -
978                    ptsJaggyLine[1].y = pts[0].y - dDeltaY0;    //was -
979                    ptsJaggyLine[2].x = pts[0].x + dDeltaX0;    //was +
980                    ptsJaggyLine[2].y = pts[0].y + dDeltaY0;    //was +
981                    ptsJaggyLine[3] = new POINT2(savepoints[2]);
982                    for (j = 0; j < 4; j++) {
983                        points[counter] = new POINT2(ptsJaggyLine[j]);
984                        counter++;
985                    }
986                    points[counter - 1].style = 5;
987                    // draw arrow at end of line
988                    dDeltaX1 = Math.cos(dAngle0 + sign*CONST_PI / 4) * iDelta;   //was +
989                    dDeltaY1 = Math.sin(dAngle0 + sign*CONST_PI / 4) * iDelta;   //was +
990                    ptsJaggyLine[0].x = savepoints[2].x + dDeltaX0;
991                    ptsJaggyLine[0].y = savepoints[2].y + dDeltaY0;
992                    ptsJaggyLine[1] = savepoints[2];
993                    ptsJaggyLine[2].x = savepoints[2].x + dDeltaX1;
994                    ptsJaggyLine[2].y = savepoints[2].y + dDeltaY1;
995                }//end rev b
996                else    //rev c
997                {
998                    ptsJaggyLine[0]=new POINT2(origPoints[2]);
999                    dAngle0 = Math.atan2(ptsJaggyLine[0].y - origPoints[3].y, ptsJaggyLine[0].x - origPoints[3].x);
1000                    pts[0].x = (ptsJaggyLine[0].x + origPoints[3].x) / 2;
1001                    pts[0].y = (ptsJaggyLine[0].y + origPoints[3].y) / 2;
1002                    dDeltaX0 = Math.cos(dAngle0 - sign*CONST_PI / 4) * iDelta;   //was -
1003                    dDeltaY0 = Math.sin(dAngle0 - sign*CONST_PI / 4) * iDelta;   //was -
1004                    ptsJaggyLine[1].x = pts[0].x - dDeltaX0;    //was -
1005                    ptsJaggyLine[1].y = pts[0].y - dDeltaY0;    //was -
1006                    ptsJaggyLine[2].x = pts[0].x + dDeltaX0;    //was +
1007                    ptsJaggyLine[2].y = pts[0].y + dDeltaY0;    //was +
1008                    //ptsJaggyLine[3] = new POINT2(savepoints[2]);
1009                    ptsJaggyLine[3] = new POINT2(origPoints[3]);
1010                    for (j = 0; j < 4; j++) {
1011                        points[counter] = new POINT2(ptsJaggyLine[j]);
1012                        counter++;
1013                    }
1014                    points[counter - 1].style = 5;
1015                    // draw arrow at end of line
1016                    dDeltaX1 = Math.cos(dAngle0 + sign*CONST_PI / 4) * iDelta;   //was +
1017                    dDeltaY1 = Math.sin(dAngle0 + sign*CONST_PI / 4) * iDelta;   //was +
1018                    ptsJaggyLine[0].x = origPoints[3].x + dDeltaX0;
1019                    ptsJaggyLine[0].y = origPoints[3].y + dDeltaY0;
1020                    ptsJaggyLine[1] = new POINT2(origPoints[3]);
1021                    ptsJaggyLine[2].x = origPoints[3].x + dDeltaX1;
1022                    ptsJaggyLine[2].y = origPoints[3].y + dDeltaY1;                    
1023                }//end rev c
1024                
1025                for (j = 0; j < 3; j++) 
1026                {
1027                    points[counter] = new POINT2(ptsJaggyLine[j]);
1028                    points[counter].style = 0;
1029                    if(linetype==TacticalLines.SARA || linetype==TacticalLines.MOVEMENT_TO_CONTACT)
1030                        points[counter].style = 9;
1031
1032                    counter++;
1033                }
1034                points[counter - 1].style = 5;
1035                if(linetype==TacticalLines.SARA || linetype==TacticalLines.MOVEMENT_TO_CONTACT)
1036                {
1037                    points[counter-1].style = 9;
1038                    points[counter]=new POINT2(points[counter-3]);
1039                    points[counter].style=10;
1040                    counter++;
1041                }
1042            }
1043            else 
1044            {
1045                points[0] = new POINT2(savepoints[0]);
1046                points[0].style = 0;
1047                points[1] = new POINT2(savepoints[1]);
1048                points[1].style = 5;
1049                points[2] = new POINT2(savepoints[0]);
1050                points[2].style = 0;
1051                points[3] = new POINT2(savepoints[2]);
1052                return 4;
1053            }
1054        } 
1055        catch (Exception exc) 
1056        {
1057            ErrorLogger.LogException(_className ,"GetDISMcoverDoubleRevC",
1058                    new RendererException("Failed inside GetDISMCoverDoubleRevc", exc));
1059        }
1060        return counter;
1061    }
1062
1063
1064    /**
1065     * Calculates the points for Escort.
1066     *
1067     * @param points OUT - the client points, also used for the returned points.
1068     * @param lineType the line type.
1069     */
1070    static int GetDISMEscortDouble(TGLight tg, POINT2[] points, int lineType) {
1071        int counter = 6;
1072        try {
1073            POINT2 pt0 = new POINT2(points[1]);
1074            POINT2 pt1 = new POINT2();
1075            POINT2 pt2 = new POINT2();
1076            POINT2 pt3 = new POINT2();
1077            POINT2 pt4 = new POINT2();
1078            POINT2 pt5 = new POINT2(points[2]);
1079
1080
1081
1082            POINT2 offset = points[0];
1083            POINT2 intersect = lineutility.FindClosestPointOnLine(pt0,pt5,offset);
1084
1085            double xOffset = offset.x - intersect.x;
1086            double yOffset = offset.y - intersect.y;
1087            pt1 = new POINT2(pt0.x+xOffset, pt0.y + yOffset);
1088            pt4 = new POINT2(pt5.x+xOffset, pt5.y + yOffset);
1089
1090
1091            int pixelSize = tg.get_IconSize();
1092            double distance = lineutility.CalcDistanceDouble(pt1,pt4);
1093            POINT2 center = lineutility.MidPointDouble(pt1,pt4,0);
1094            Font font = tg.get_Font();
1095            if (font == null) {
1096                RendererSettings r = RendererSettings.getInstance();
1097                font = new Font(r.getMPLabelFontName(),r.getMPLabelFontType(),r.getMPLabelFontSize());
1098            }
1099
1100            POINT2 ptCenter = lineutility.MidPointDouble(pt1, pt4, 0);
1101            if ((font.getSize()*2 + pixelSize) < distance)//draw the gap for the icon
1102            {
1103                pt2 = lineutility.ExtendAlongLineDouble(center, pt1, pixelSize/2f + font.getSize());
1104                pt3 = lineutility.ExtendAlongLineDouble(center, pt4, pixelSize/2f + font.getSize());
1105            }
1106            else
1107            {
1108                pt2 = ptCenter;
1109                pt3 = ptCenter;
1110            }
1111
1112            pt0.style = 0;
1113            pt1.style = 1;
1114            pt2.style = 5;
1115            pt3.style = 0;
1116            pt4.style = 1;
1117            pt5.style = 1;
1118
1119            points[0] = pt0;
1120            points[1] = pt1;
1121            points[2] = pt2;
1122            points[3] = pt3;
1123            points[4] = pt4;
1124            points[5] = pt5;
1125
1126        } catch (Exception exc) {
1127            ErrorLogger.LogException(_className, "GetDISMEscortDouble",
1128                    new RendererException("Failed inside GetDISMEscortDouble", exc));
1129        }
1130        return counter;
1131    }
1132
1133
1134
1135    /**
1136     * Calculates the points for BYPASS
1137     *
1138     * @param points OUT - the client points, also used for the returned points.
1139     * @param linetype the line type.
1140     */
1141    protected static int GetDISMBypassDouble(POINT2[] points,
1142                                            int linetype) {
1143        int counter = 0;
1144        try {
1145            int j = 0;
1146            POINT2[] pointsCorner = new POINT2[2];
1147            POINT2[] rectpts = new POINT2[4];
1148            POINT2[] savepoints = new POINT2[3];
1149            POINT2[] deltapoints1 = new POINT2[4];
1150            POINT2[] deltapoints2 = new POINT2[4];
1151            ref<double[]> iDeltaX = new ref(), iDeltaY = new ref();
1152            int bPointsRight = 0;
1153
1154            for (j = 0; j < 3; j++) {
1155                savepoints[j] = new POINT2(points[j]);
1156            }
1157
1158            lineutility.InitializePOINT2Array(pointsCorner);
1159            lineutility.InitializePOINT2Array(rectpts);
1160            lineutility.InitializePOINT2Array(deltapoints1);
1161            lineutility.InitializePOINT2Array(deltapoints2);
1162
1163            DrawOpenRectangleDouble(savepoints, pointsCorner, rectpts);
1164            for (j = 0; j < 4; j++) {
1165                points[counter] = rectpts[j];
1166                counter++;
1167            }
1168
1169            bPointsRight = DetermineDirectionDouble(savepoints);
1170
1171            CalcEndpieceDeltasDouble(savepoints, iDeltaX, iDeltaY, CONST_PI / 4);
1172
1173            if ((savepoints[0].y - savepoints[1].y) < 0) {// Point0 is higher than Point1
1174                if (bPointsRight != 0) {// figure opens to the right
1175                    DrawEndpieceDeltasDouble(savepoints[0],
1176                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints1);
1177                    DrawEndpieceDeltasDouble(savepoints[1],
1178                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints2);
1179                } else {// figure opens to the left
1180                    DrawEndpieceDeltasDouble(savepoints[0],
1181                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints1);
1182                    DrawEndpieceDeltasDouble(savepoints[1],
1183                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints2);
1184                }
1185            } else {// Point0 is lower than Point1
1186                if (bPointsRight != 0) {// figure opens to the right
1187                    DrawEndpieceDeltasDouble(savepoints[0],
1188                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints1);
1189                    DrawEndpieceDeltasDouble(savepoints[1],
1190                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints2);
1191                } else {// figure opens to the left
1192                    DrawEndpieceDeltasDouble(savepoints[0],
1193                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints1);
1194                    DrawEndpieceDeltasDouble(savepoints[1],
1195                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints2);
1196                }
1197            }
1198
1199            for (j = 0; j < 4; j++) {
1200                points[counter] = new POINT2(deltapoints1[j]);
1201                counter++;
1202            }
1203            for (j = 0; j < 4; j++) {
1204                points[counter] = new POINT2(deltapoints2[j]);
1205                counter++;
1206            }
1207        } catch (Exception exc) {
1208            ErrorLogger.LogException(_className ,"GetDISMBypassDouble",
1209                    new RendererException("Failed inside GetDISMBypassDouble", exc));
1210        }
1211        return counter;
1212    }
1213    /**
1214     * Calculates the points for BREACH.
1215     *
1216     * @param points OUT - the client points, also used for the returned points.
1217     * @param linetype the line type.
1218     */
1219    protected static int GetDISMBreachDouble(POINT2[] points, int linetype) {
1220        int counter = 0;
1221        try {
1222            POINT2[] pointsCorner = new POINT2[2];
1223            POINT2[] rectpts = new POINT2[4];
1224            POINT2[] deltapoints1 = new POINT2[4];
1225            POINT2[] deltapoints2 = new POINT2[4];
1226            ref<double[]> iDeltaX = new ref(), iDeltaY = new ref();
1227            int bPointsRight = 0, j = 0;
1228            POINT2[] savepoints = new POINT2[3];
1229
1230            for (j = 0; j < 3; j++) {
1231                savepoints[j] = new POINT2(points[j]);
1232            }
1233
1234            lineutility.InitializePOINT2Array(pointsCorner);
1235            lineutility.InitializePOINT2Array(rectpts);
1236            lineutility.InitializePOINT2Array(deltapoints1);
1237            lineutility.InitializePOINT2Array(deltapoints2);
1238
1239            DrawOpenRectangleDouble(savepoints, pointsCorner, rectpts);
1240            for (j = 0; j < 4; j++) {
1241                points[counter] = new POINT2(rectpts[j]);
1242                counter++;
1243            }
1244
1245            bPointsRight = DetermineDirectionDouble(savepoints);
1246
1247            CalcEndpieceDeltasDouble(savepoints, iDeltaX, iDeltaY, CONST_PI / 4);
1248
1249            if ((savepoints[0].y - savepoints[1].y) < 0) {// Point0 is higher than Point1
1250                if (bPointsRight != 0) {// figure opens to the right
1251                    DrawEndpieceDeltasDouble(savepoints[0],
1252                            iDeltaX.value[0], iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], deltapoints1);
1253                    DrawEndpieceDeltasDouble(savepoints[1],
1254                            iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], iDeltaX.value[0], deltapoints2);
1255                } else {// figure opens to the left
1256                    DrawEndpieceDeltasDouble(savepoints[0],
1257                            iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], iDeltaX.value[0], deltapoints1);
1258                    DrawEndpieceDeltasDouble(savepoints[1],
1259                            iDeltaX.value[0], iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], deltapoints2);
1260                }
1261            } else {// Point0 is lower than Point1
1262                if (bPointsRight != 0) {// figure opens to the right
1263                    DrawEndpieceDeltasDouble(savepoints[0],
1264                            iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], iDeltaX.value[0], deltapoints1);
1265                    DrawEndpieceDeltasDouble(savepoints[1],
1266                            iDeltaX.value[0], iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], deltapoints2);
1267                } else {// figure opens to the left
1268                    DrawEndpieceDeltasDouble(savepoints[0],
1269                            iDeltaX.value[0], iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], deltapoints1);
1270                    DrawEndpieceDeltasDouble(savepoints[1],
1271                            iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], iDeltaX.value[0], deltapoints2);
1272                }
1273            }
1274            for (j = 0; j < 4; j++) {
1275                points[counter] = new POINT2(deltapoints1[j]);
1276                counter++;
1277            }
1278            for (j = 0; j < 4; j++) {
1279                points[counter] = new POINT2(deltapoints2[j]);
1280                counter++;
1281            }
1282        } catch (Exception exc) {
1283            ErrorLogger.LogException(_className ,"GetDISMBreachDouble",
1284                    new RendererException("Failed inside GetDISMBreachDouble", exc));
1285        }
1286        return counter;
1287    }
1288    /**
1289     * Calculates the points for CANALIZE
1290     *
1291     * @param points - OUT - the client points, also used for the returned points.
1292     * @param linetype the line type.
1293     */
1294    protected static int GetDISMCanalizeDouble(POINT2[] points, int linetype) {
1295        int counter = 0;
1296        try {
1297            POINT2[] pointsCorner = new POINT2[2];
1298            POINT2[] rectpts = new POINT2[4];
1299            POINT2[] deltapoints1 = new POINT2[4];
1300            POINT2[] deltapoints2 = new POINT2[4];
1301            int j = 0;
1302            ref<double[]> iDeltaX = new ref(), iDeltaY = new ref();
1303            int bPointsRight = 0;
1304            POINT2[] savepoints = new POINT2[3];
1305
1306            for (j = 0; j < 3; j++) {
1307                savepoints[j] = new POINT2(points[j]);
1308            }
1309
1310            lineutility.InitializePOINT2Array(pointsCorner);
1311            lineutility.InitializePOINT2Array(rectpts);
1312            lineutility.InitializePOINT2Array(deltapoints1);
1313            lineutility.InitializePOINT2Array(deltapoints2);
1314
1315            DrawOpenRectangleDouble(savepoints, pointsCorner, rectpts);
1316
1317            for (j = 0; j < 4; j++) {
1318                points[counter] = new POINT2(rectpts[j]);
1319                counter++;
1320            }
1321
1322            bPointsRight = DetermineDirectionDouble(savepoints);
1323
1324            CalcEndpieceDeltasDouble(savepoints, iDeltaX, iDeltaY, CONST_PI / 4);
1325
1326            if ((savepoints[0].y - savepoints[1].y) < 0) {// Point0 is higher than Point1
1327                if (bPointsRight != 0) {// figure opens to the right
1328                    DrawEndpieceDeltasDouble(savepoints[1],
1329                            iDeltaX.value[0], iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], deltapoints1);
1330                    DrawEndpieceDeltasDouble(savepoints[0],
1331                            iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], iDeltaX.value[0], deltapoints2);
1332                } else {// figure opens to the left
1333                    DrawEndpieceDeltasDouble(savepoints[1],
1334                            iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], iDeltaX.value[0], deltapoints1);
1335                    DrawEndpieceDeltasDouble(savepoints[0],
1336                            iDeltaX.value[0], iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], deltapoints2);
1337                }
1338            } else {// Point0 is lower than Point1
1339                if (bPointsRight != 0) {// figure opens to the right
1340                    DrawEndpieceDeltasDouble(savepoints[1],
1341                            iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], iDeltaX.value[0], deltapoints1);
1342                    DrawEndpieceDeltasDouble(savepoints[0],
1343                            iDeltaX.value[0], iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], deltapoints2);
1344                } else {// figure opens to the left
1345                    DrawEndpieceDeltasDouble(savepoints[1],
1346                            iDeltaX.value[0], iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], deltapoints1);
1347                    DrawEndpieceDeltasDouble(savepoints[0],
1348                            iDeltaY.value[0], -iDeltaX.value[0], -iDeltaY.value[0], iDeltaX.value[0], deltapoints2);
1349                }
1350            }
1351
1352            for (j = 0; j < 4; j++) {
1353                points[counter] = new POINT2(deltapoints1[j]);
1354                counter++;
1355            }
1356            for (j = 0; j < 4; j++) {
1357                points[counter] = new POINT2(deltapoints2[j]);
1358                counter++;
1359            }
1360        } catch (Exception exc) {
1361            ErrorLogger.LogException(_className ,"GetDISMCanalizeDouble",
1362                    new RendererException("Failed inside GetDISMCanalizeDouble", exc));
1363        }
1364        return counter;
1365    }
1366
1367    /**
1368     * Gets shape for Feint, decoy, or dummy indicator. Does not check if tactical graphic should have indicator
1369     * @param tg used to get line color and stroke
1370     * @param ptA bottom left point of triangle
1371     * @param ptC bottom right point of triangle
1372     * @return Dummy indicator shape
1373     */
1374    public static Shape2 getFDIShape(TGLight tg, POINT2 ptA, POINT2 ptC) {
1375        try {
1376            POINT2 midPt = lineutility.MidPointDouble(ptA, ptC, 0);
1377            double len = lineutility.CalcDistanceDouble(ptA, midPt);
1378            POINT2 ptB = lineutility.ExtendDirectedLine(ptA, ptC, midPt, lineutility.extend_above, len);
1379            Shape2 shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
1380            shape.moveTo(ptA);
1381            shape.lineTo(ptB);
1382            shape.lineTo(ptC);
1383            shape.set_Style(1);
1384            shape.setLineColor(tg.get_LineColor());
1385
1386            BasicStroke stroke = clsUtility.getLineStroke(tg.get_LineThickness(), shape.get_Style(), BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER);
1387            shape.setStroke(stroke);
1388            return shape;
1389        } catch (Exception exc) {
1390            ErrorLogger.LogException(_className, "getFDIShape",
1391                    new RendererException("Failed inside getFDIShape", exc));
1392        }
1393        return null;
1394    }
1395
1396    /**
1397     * Gets shape for Feint, decoy, or dummy indicator for symbols with arrowhead. Does not check if tactical graphic should have indicator
1398     * Extends each point outside arrow as necessary
1399     * @param tg used to get line color and stroke
1400     * @param ptA bottom left point of arrow
1401     * @param ptB arrow point
1402     * @param ptC bottom right point of arrow
1403     * @return Dummy indicator shape
1404     */
1405    public static Shape2 getFDIShape(TGLight tg, POINT2 ptA, POINT2 ptB, POINT2 ptC) {
1406        try {
1407            // Extend ptA and ptC .25w
1408            double w = lineutility.CalcDistanceDouble(ptA, ptC) * 0.25;
1409            if (w < tg.get_LineThickness() * 1.5) {
1410                // lineThickness * 1.5 is minimum distance between arrow and dummy modifier
1411                w = tg.get_LineThickness() * 1.5;
1412            }
1413            ptC = lineutility.ExtendLineDouble(ptA, ptC, w);
1414            ptA = lineutility.ExtendLineDouble(ptC, ptA, w);
1415
1416            // Extend ptB .5w
1417            POINT2 midPt = lineutility.MidPointDouble(ptA, ptC, 0);
1418            w = lineutility.CalcDistanceDouble(midPt, ptB) * 0.5;
1419            if (w < tg.get_LineThickness() * 1.5) {
1420                // lineThickness * 1.5 is minimum distance between arrow and dummy modifier
1421                w = tg.get_LineThickness() * 1.5;
1422            }
1423            ptB = lineutility.ExtendLineDouble(midPt, ptB, w);
1424
1425            Shape2 shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
1426            shape.moveTo(ptA);
1427            shape.lineTo(ptB);
1428            shape.lineTo(ptC);
1429            shape.set_Style(1);
1430            shape.setLineColor(tg.get_LineColor());
1431
1432            BasicStroke stroke = clsUtility.getLineStroke(tg.get_LineThickness(), shape.get_Style(), BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER);
1433            shape.setStroke(stroke);
1434            return shape;
1435        } catch (Exception exc) {
1436            ErrorLogger.LogException(_className, "getFDIShape",
1437                    new RendererException("Failed inside getFDIShape", exc));
1438        }
1439        return null;
1440    }
1441
1442    /**
1443     * Calculates the points for DECEIVE.
1444     *
1445     * @param points - OUT - the client points, also used for the returned points.
1446     */
1447    protected static void GetDISMDeceiveDouble(POINT2[] points) {
1448        try {
1449            POINT2[] savepoints = new POINT2[3];// POINT2[3];
1450            int j = 0;
1451
1452            for (j = 0; j < 3; j++) {
1453                savepoints[j] = new POINT2(points[j]);
1454            }
1455
1456            points[0] = new POINT2(savepoints[0]);
1457            points[0].style = 1;
1458            points[1] = new POINT2(savepoints[1]);
1459            points[1].style = 5;
1460            points[2] = new POINT2(savepoints[2]);
1461            points[2].style = 1;
1462            points[3] = new POINT2(savepoints[0]);
1463            points[3].style = 5;
1464
1465        } catch (Exception exc) {
1466            ErrorLogger.LogException(_className ,"GetDISMDeceiveDouble",
1467                    new RendererException("Failed inside GetDISMDeceiveDouble", exc));
1468        }
1469    }
1470
1471    /**
1472     * Calculates the points for DISRUPT
1473     *
1474     * @param points OUT - the client points, also used for the returned points.
1475     * @param linetype the line type.
1476     */
1477    protected static int GetDISMDisruptDouble(POINT2[] points, int linetype) {
1478        int counter = 0;
1479        try {
1480            POINT2[] pts = new POINT2[2];
1481            POINT2[] ptsArrow = new POINT2[3];
1482            POINT2 ptCenter = new POINT2();
1483            int j = 0;
1484            POINT2[] savepoints = new POINT2[3];
1485            double dAngle1 = 0;
1486            POINT2[] deltapoints1 = new POINT2[4];
1487            POINT2[] deltapoints2 = new POINT2[4];
1488            POINT2[] deltapoints3 = new POINT2[4];
1489            double iDiagEOL_length = 0;
1490            double iDeltaX1 = 0;
1491            double iDeltaY1 = 0;
1492            double iDeltaX2 = 0;
1493            double iDeltaY2 = 0;
1494
1495            for (j = 0; j < 3; j++) {
1496                savepoints[j] = new POINT2(points[j]);
1497            }
1498
1499            lineutility.InitializePOINT2Array(pts);
1500            lineutility.InitializePOINT2Array(ptsArrow);
1501            lineutility.InitializePOINT2Array(deltapoints1);
1502            lineutility.InitializePOINT2Array(deltapoints2);
1503            lineutility.InitializePOINT2Array(deltapoints3);
1504
1505            //  DrawLine(destination, mask, color, points, 2, 2);
1506            points[counter] = new POINT2(savepoints[0]);
1507            points[counter].style = 0;
1508            counter++;
1509            points[counter] = new POINT2(savepoints[1]);
1510            points[counter].style = 5;
1511            counter++;
1512            //  pts[0] = points[1];
1513            //  pts[1] = points[2];
1514            //  DrawLine(destination, mask, color, pts, 2, 2);
1515            points[counter] = new POINT2(savepoints[1]);
1516            points[counter].style = 0;
1517            counter++;
1518            points[counter] = new POINT2(savepoints[2]);
1519            points[counter].style = 5;
1520            counter++;
1521
1522            ptCenter.x = (savepoints[0].x + savepoints[1].x) / 2;
1523            ptCenter.y = (savepoints[0].y + savepoints[1].y) / 2;
1524            ptsArrow[0] = new POINT2(savepoints[2]);
1525            ptsArrow[1].x = ptCenter.x + (savepoints[2].x - savepoints[1].x) * 4 / 5;
1526            ptsArrow[1].y = ptCenter.y + (savepoints[2].y - savepoints[1].y) * 4 / 5;
1527            ptsArrow[2].x = savepoints[0].x + (savepoints[2].x - savepoints[1].x) * 3 / 5;
1528            ptsArrow[2].y = savepoints[0].y + (savepoints[2].y - savepoints[1].y) * 3 / 5;
1529
1530            pts[0].x = ptCenter.x - (savepoints[2].x - savepoints[1].x) / 5;
1531            pts[0].y = ptCenter.y - (savepoints[2].y - savepoints[1].y) / 5;
1532            pts[1] = new POINT2(ptsArrow[1]);
1533            //  DrawLine(destination, mask, color, pts, 2, 2);
1534            points[counter] = new POINT2(pts[0]);
1535            points[counter].style = 0;
1536            counter++;
1537            points[counter] = new POINT2(pts[1]);
1538            points[counter].style = 5;
1539            counter++;
1540
1541            pts[0] = new POINT2(savepoints[0]);
1542            pts[1] = new POINT2(ptsArrow[2]);
1543            //  DrawLine(destination, mask, color, pts, 2, 2);
1544            points[counter] = new POINT2(pts[0]);
1545            points[counter].style = 0;
1546            counter++;
1547            points[counter] = new POINT2(pts[1]);
1548            points[counter].style = 5;
1549            counter++;
1550
1551            // the following code is very similar to CalcEndpieceDeltas
1552            iDiagEOL_length =  ((Math.sqrt // height of graphic
1553                    (
1554                    (savepoints[1].x - savepoints[0].x) * (savepoints[1].x - savepoints[0].x) +
1555                    (savepoints[1].y - savepoints[0].y) * (savepoints[1].y - savepoints[0].y)) +
1556                    Math.sqrt // length of graphic
1557                    (
1558                    (savepoints[2].x - savepoints[1].x) * (savepoints[2].x - savepoints[1].x) +
1559                    (savepoints[2].y - savepoints[1].y) * (savepoints[2].y - savepoints[1].y))) / 15);
1560
1561            //M. Deutch 8-18-04
1562            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
1563            if (iDiagEOL_length >  maxLength * DPIScaleFactor) {
1564                iDiagEOL_length =  maxLength * DPIScaleFactor;
1565            }
1566            if (iDiagEOL_length <  minLength * DPIScaleFactor) {//was minLength
1567                iDiagEOL_length =  minLength * DPIScaleFactor;   //was minLength
1568            }
1569
1570            // dAngle1 = angle used to calculate the end-piece deltas
1571            dAngle1 = Math.atan2(savepoints[1].y - savepoints[2].y, savepoints[1].x - savepoints[2].x);
1572            //  dAngle1 = atan2(savepoints[1].y - savepoints[2].y, savepoints[1].x - savepoints[2].x);
1573            iDeltaX1 =  (iDiagEOL_length * Math.cos(dAngle1 - CONST_PI / 6));
1574            iDeltaY1 =  (iDiagEOL_length * Math.sin(dAngle1 - CONST_PI / 6));
1575            iDeltaX2 =  (iDiagEOL_length * Math.cos(dAngle1 + CONST_PI / 6));
1576            iDeltaY2 =  (iDiagEOL_length * Math.sin(dAngle1 + CONST_PI / 6));
1577
1578            DrawEndpieceDeltasDouble(ptsArrow[0],
1579                    iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints1);
1580            DrawEndpieceDeltasDouble(ptsArrow[1],
1581                    iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints2);
1582            DrawEndpieceDeltasDouble(ptsArrow[2],
1583                    iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints3);
1584            for (j = 0; j < 4; j++) {
1585                points[counter] = new POINT2(deltapoints1[j]);
1586                counter++;
1587            }
1588            for (j = 0; j < 4; j++) {
1589                points[counter] = new POINT2(deltapoints2[j]);
1590                counter++;
1591            }
1592            for (j = 0; j < 4; j++) {
1593                points[counter] = new POINT2(deltapoints3[j]);
1594                counter++;
1595            }
1596        } catch (Exception exc) {
1597            ErrorLogger.LogException(_className ,"GetDISMDisruptDouble",
1598                    new RendererException("Failed inside GetDISMDisruptDouble", exc));
1599        }
1600        return counter;
1601    }
1602    /**
1603     * Calculates the points for CONTAIN
1604     *
1605     * @param points OUT - the client points, also used for the returned points.
1606     * @param linetype the line type.
1607     */
1608    protected static int GetDISMContainDouble(POINT2[] points, int linetype) {
1609        int counter = 0;
1610        try {
1611            POINT2[] pts = new POINT2[3];
1612            POINT2 ptCenter = new POINT2();
1613            POINT2 ptPerp = new POINT2(); // point used to draw perpendicular line
1614            double iPerpLength = 0;
1615            int j = 0;
1616            double dAngle1 = 0, d = 0;
1617            double dCosAngle1 = 0;
1618            double dSinAngle1 = 0;
1619            double iRadius = 0;
1620            double iDiagEOL_length = 0;
1621            double dAngle2 = 0;
1622            double dDeltaX1, dDeltaY1, dDeltaX2, dDeltaY2;
1623            POINT2[] savepoints = new POINT2[3];
1624            POINT2[] arcpoints = new POINT2[17];
1625
1626            for (j = 0; j < 3; j++) {
1627                savepoints[j] = new POINT2(points[j]);
1628            }
1629
1630            lineutility.InitializePOINT2Array(pts);
1631            lineutility.InitializePOINT2Array(arcpoints);
1632
1633            ptCenter.x = (savepoints[0].x + savepoints[1].x) / 2;
1634            ptCenter.y = (savepoints[0].y + savepoints[1].y) / 2;
1635
1636            //added section M. Deutch   8-10-06
1637            //reverse points 0 and 1 if necessary to ensure arc
1638            //has correct orientation
1639            ref<double[]> m = new ref();
1640            POINT2 ptRelative = lineutility.PointRelativeToLine(savepoints[0], savepoints[1], savepoints[2]);
1641
1642            lineutility.CalcTrueSlopeDouble2(savepoints[0], savepoints[1], m);
1643            if (m.value[0] != 0) {
1644                if (savepoints[0].y > savepoints[1].y) {
1645                    if (ptRelative.x > ptCenter.x) {
1646                        lineutility.Reverse2Points(savepoints[0], savepoints[1]);
1647                    }
1648                }
1649                if (savepoints[0].y < savepoints[1].y) {
1650                    if (ptRelative.x < ptCenter.x) {
1651                        lineutility.Reverse2Points(savepoints[0], savepoints[1]);
1652                    }
1653                }
1654            } else {
1655                if (savepoints[0].x < savepoints[1].x) {
1656                    if (ptRelative.y > ptCenter.y) {
1657                        lineutility.Reverse2Points(savepoints[0], savepoints[1]);
1658                    }
1659                }
1660                if (savepoints[0].x > savepoints[1].x) {
1661                    if (ptRelative.y < ptCenter.y) {
1662                        lineutility.Reverse2Points(savepoints[0], savepoints[1]);
1663                    }
1664                }
1665            }
1666            //end section
1667
1668            iPerpLength =  Math.sqrt((ptCenter.x - savepoints[2].x) * (ptCenter.x - savepoints[2].x) + (ptCenter.y - savepoints[2].y) * (ptCenter.y - savepoints[2].y));
1669            if (iPerpLength < 1) {
1670                iPerpLength = 1;
1671            }
1672
1673            dAngle1 = Math.atan2(savepoints[0].y - savepoints[1].y, savepoints[0].x - savepoints[1].x);
1674            dCosAngle1 = Math.cos(dAngle1 + CONST_PI / 2);
1675            dSinAngle1 = Math.sin(dAngle1 + CONST_PI / 2);
1676            
1677            ptPerp.x = ptCenter.x + dCosAngle1 * iPerpLength;
1678            ptPerp.y = ptCenter.y + dSinAngle1 * iPerpLength;
1679
1680            pts[0] = new POINT2(ptCenter);
1681
1682            pts[1] = new POINT2(savepoints[2]);
1683
1684            points[counter] = new POINT2(pts[0]);
1685            points[counter].style = 14;
1686            counter++;
1687            points[counter] = new POINT2(pts[1]);
1688            points[counter].style = 5;
1689            counter++;
1690
1691            // draw arrowhead
1692            iRadius =  Math.sqrt((ptCenter.x - savepoints[0].x) * (ptCenter.x - savepoints[0].x) + (ptCenter.y - savepoints[0].y) * (ptCenter.y - savepoints[0].y));
1693            iDiagEOL_length = (iPerpLength + iRadius) / 20;
1694
1695            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
1696            if (iDiagEOL_length >  maxLength * DPIScaleFactor) {
1697                iDiagEOL_length =  maxLength * DPIScaleFactor;
1698            }
1699            if (iDiagEOL_length <  minLength * DPIScaleFactor) {
1700                iDiagEOL_length =  minLength * DPIScaleFactor;
1701            }
1702
1703            dAngle2 = Math.atan2(ptPerp.y - ptCenter.y, ptPerp.x - ptCenter.x);
1704            dDeltaX1 = Math.cos(dAngle2 + CONST_PI / 4);
1705            dDeltaY1 = Math.sin(dAngle2 + CONST_PI / 4);
1706            dDeltaX2 = Math.cos(dAngle2 - CONST_PI / 4);
1707            dDeltaY2 = Math.sin(dAngle2 - CONST_PI / 4);
1708            pts[0].x = ptCenter.x + dDeltaX1 * iDiagEOL_length;
1709            pts[0].y = ptCenter.y + dDeltaY1 * iDiagEOL_length;
1710            pts[1] = new POINT2(ptCenter);
1711            pts[2].x = ptCenter.x + dDeltaX2 * iDiagEOL_length;
1712            pts[2].y = ptCenter.y + dDeltaY2 * iDiagEOL_length;
1713            //end section
1714            for (j = 0; j < 3; j++) {
1715                points[counter] = new POINT2(pts[j]);
1716                points[counter].style = 0;
1717                counter++;
1718            }
1719            points[counter - 1].style = 5;
1720
1721            // draw arc
1722            ArcApproximationDouble(ptCenter.x - iRadius, ptCenter.y - iRadius,
1723                    ptCenter.x + iRadius, ptCenter.y + iRadius,
1724                    savepoints[0].x, savepoints[0].y, savepoints[1].x, savepoints[1].y, arcpoints);
1725
1726            for (j = 0; j < 17; j++) {
1727                points[counter] = new POINT2(arcpoints[j]);
1728                points[counter].style = 0;
1729                counter++;
1730            }
1731            points[counter - 1].style = 5;
1732
1733            // draw spokes inside arc
1734            pts[0] = new POINT2(savepoints[0]);
1735            pts[1].x = (pts[0].x + ptCenter.x) / 2;
1736            pts[1].y = (pts[0].y + ptCenter.y) / 2;
1737            d = lineutility.CalcDistanceDouble(pts[0], pts[1]);
1738            if (d > maxLength * DPIScaleFactor) //shorten the spoke
1739            {
1740                pts[1] = lineutility.ExtendLineDouble(pts[1], pts[0], -maxLength * DPIScaleFactor);
1741            }
1742
1743            points[counter] = new POINT2(pts[0]);
1744            points[counter].style = 0;
1745            counter++;
1746            points[counter] = new POINT2(pts[1]);
1747            points[counter].style = 5;
1748            counter++;
1749
1750            pts[0] = new POINT2(savepoints[1]);
1751            pts[1].x = (pts[0].x + ptCenter.x) / 2;
1752            pts[1].y = (pts[0].y + ptCenter.y) / 2;
1753            d = lineutility.CalcDistanceDouble(pts[0], pts[1]);
1754            if (d > maxLength * DPIScaleFactor) //shorten the spoke
1755            {
1756                pts[1] = lineutility.ExtendLineDouble(pts[1], pts[0], -maxLength * DPIScaleFactor);
1757            }
1758            //  DrawLine(destination, mask, color, pts, 2, 2);
1759
1760            points[counter] = new POINT2(pts[0]);
1761            points[counter].style = 0;
1762            counter++;
1763            points[counter] = new POINT2(pts[1]);
1764            points[counter].style = 5;
1765            counter++;
1766
1767            pts[0].x = ptCenter.x - (ptPerp.x - ptCenter.x) * iRadius / iPerpLength;
1768            pts[0].y = ptCenter.y - (ptPerp.y - ptCenter.y) * iRadius / iPerpLength;
1769            pts[1].x = (ptCenter.x + pts[0].x) / 2;
1770            pts[1].y = (ptCenter.y + pts[0].y) / 2;
1771            d = lineutility.CalcDistanceDouble(pts[0], pts[1]);
1772            if (d > maxLength * DPIScaleFactor) //shorten the spoke
1773            {
1774                pts[1] = lineutility.ExtendLineDouble(pts[1], pts[0], -maxLength * DPIScaleFactor);
1775            }
1776
1777            points[counter] = new POINT2(pts[0]);
1778            points[counter].style = 0;
1779            counter++;
1780            points[counter] = new POINT2(pts[1]);
1781            points[counter].style = 5;
1782            counter++;
1783
1784            pts[0].x = ptCenter.x - dDeltaX1 * iRadius;
1785            pts[0].y = ptCenter.y - dDeltaY1 * iRadius;
1786            pts[1].x = (ptCenter.x + pts[0].x) / 2;
1787            pts[1].y = (ptCenter.y + pts[0].y) / 2;
1788            d = lineutility.CalcDistanceDouble(pts[0], pts[1]);
1789            if (d > maxLength * DPIScaleFactor) //shorten the spoke
1790            {
1791                pts[1] = lineutility.ExtendLineDouble(pts[1], pts[0], -maxLength * DPIScaleFactor);
1792            }
1793
1794            points[counter] = new POINT2(pts[0]);
1795            points[counter].style = 0;
1796            counter++;
1797            points[counter] = new POINT2(pts[1]);
1798            points[counter].style = 5;
1799            counter++;
1800
1801            pts[0].x = ptCenter.x - dDeltaX2 * iRadius;
1802            pts[0].y = ptCenter.y - dDeltaY2 * iRadius;
1803            pts[1].x = (ptCenter.x + pts[0].x) / 2;
1804            pts[1].y = (ptCenter.y + pts[0].y) / 2;
1805            d = lineutility.CalcDistanceDouble(pts[0], pts[1]);
1806            if (d > maxLength * DPIScaleFactor) //shorten the spoke
1807            {
1808                pts[1] = lineutility.ExtendLineDouble(pts[1], pts[0], -maxLength * DPIScaleFactor);
1809            }
1810
1811            points[counter] = new POINT2(pts[0]);
1812            points[counter].style = 0;
1813            counter++;
1814            points[counter] = new POINT2(pts[1]);
1815            points[counter].style = 5;
1816            counter++;
1817
1818            dDeltaX1 = Math.cos(dAngle2 + CONST_PI / 8);
1819            dDeltaY1 = Math.sin(dAngle2 + CONST_PI / 8);
1820            dDeltaX2 = Math.cos(dAngle2 - CONST_PI / 8);
1821            dDeltaY2 = Math.sin(dAngle2 - CONST_PI / 8);
1822            pts[0].x = ptCenter.x - dDeltaX1 * iRadius;
1823            pts[0].y = ptCenter.y - dDeltaY1 * iRadius;
1824            pts[1].x = (ptCenter.x + pts[0].x) / 2;
1825            pts[1].y = (ptCenter.y + pts[0].y) / 2;
1826            d = lineutility.CalcDistanceDouble(pts[0], pts[1]);
1827            if (d > maxLength * DPIScaleFactor) //shorten the spoke
1828            {
1829                pts[1] = lineutility.ExtendLineDouble(pts[1], pts[0], -maxLength * DPIScaleFactor);
1830            }
1831
1832            points[counter] = new POINT2(pts[0]);
1833            points[counter].style = 0;
1834            counter++;
1835            points[counter] = new POINT2(pts[1]);
1836            points[counter].style = 5;
1837            counter++;
1838
1839            pts[0].x = ptCenter.x - dDeltaX2 * iRadius;
1840            pts[0].y = ptCenter.y - dDeltaY2 * iRadius;
1841            pts[1].x = (ptCenter.x + pts[0].x) / 2;
1842            pts[1].y = (ptCenter.y + pts[0].y) / 2;
1843            d = lineutility.CalcDistanceDouble(pts[0], pts[1]);
1844            if (d > maxLength * DPIScaleFactor) //shorten the spoke
1845            {
1846                pts[1] = lineutility.ExtendLineDouble(pts[1], pts[0], -maxLength * DPIScaleFactor);
1847            }
1848
1849            points[counter] = new POINT2(pts[0]);
1850            points[counter].style = 0;
1851            counter++;
1852            points[counter] = new POINT2(pts[1]);
1853            points[counter].style = 5;
1854            counter++;
1855
1856            dDeltaX1 = Math.cos(dAngle2 + 3 * CONST_PI / 8);
1857            dDeltaY1 = Math.sin(dAngle2 + 3 * CONST_PI / 8);
1858            dDeltaX2 = Math.cos(dAngle2 - 3 * CONST_PI / 8);
1859            dDeltaY2 = Math.sin(dAngle2 - 3 * CONST_PI / 8);
1860            pts[0].x = ptCenter.x - dDeltaX1 * iRadius;
1861            pts[0].y = ptCenter.y - dDeltaY1 * iRadius;
1862            pts[1].x = (ptCenter.x + pts[0].x) / 2;
1863            pts[1].y = (ptCenter.y + pts[0].y) / 2;
1864            d = lineutility.CalcDistanceDouble(pts[0], pts[1]);
1865            if (d > maxLength * DPIScaleFactor) //shorten the spoke
1866            {
1867                pts[1] = lineutility.ExtendLineDouble(pts[1], pts[0], -maxLength * DPIScaleFactor);
1868            }
1869
1870            points[counter] = new POINT2(pts[0]);
1871            points[counter].style = 0;
1872            counter++;
1873            points[counter] = new POINT2(pts[1]);
1874            points[counter].style = 5;
1875            counter++;
1876
1877            pts[0].x = ptCenter.x - dDeltaX2 * iRadius;
1878            pts[0].y = ptCenter.y - dDeltaY2 * iRadius;
1879            pts[1].x = (ptCenter.x + pts[0].x) / 2;
1880            pts[1].y = (ptCenter.y + pts[0].y) / 2;
1881            d = lineutility.CalcDistanceDouble(pts[0], pts[1]);
1882            if (d > maxLength * DPIScaleFactor) //shorten the spoke
1883            {
1884                pts[1] = lineutility.ExtendLineDouble(pts[1], pts[0], -maxLength * DPIScaleFactor);
1885            }
1886
1887            points[counter] = new POINT2(pts[0]);
1888            points[counter].style = 0;
1889            counter++;
1890            points[counter] = new POINT2(pts[1]);
1891            points[counter].style = 5;
1892            counter++;
1893
1894        } catch (Exception exc) {
1895            ErrorLogger.LogException(_className ,"GetDISMContainDouble",
1896                    new RendererException("Failed inside GetDISMContainDouble", exc));
1897        }
1898        return counter;
1899    }
1900    /**
1901     * Calculates the points for FIX, MNFLDFIX
1902     *
1903     * @param points OUT - the client points, also used for the returned points.
1904     * @param linetype the line type.
1905     */
1906    protected static int GetDISMFixDouble(POINT2[] points, int linetype,Rectangle2D clipBounds) {
1907        int counter = 0;
1908        try {
1909            POINT2[] pts = new POINT2[3];
1910            POINT2[] savepoints = new POINT2[2];
1911            double dAngle1 = 0;
1912            double dLength = 0;
1913            double dJaggyHalfAmp = 0;
1914            double dJaggyHalfPeriod = 0;
1915            double dDeltaXOut = 0;
1916            double dDeltaYOut = 0;
1917            double dDeltaXAlong = 0;
1918            double dDeltaYAlong = 0;
1919            int iNumJaggies = 0;
1920            int i = 0, j = 0;
1921
1922            for (j = 0; j < 2; j++) {
1923                savepoints[j] = new POINT2(points[j]);
1924            }
1925
1926            Boolean drawJaggies=true;
1927            if(clipBounds != null)
1928            {
1929                POINT2 ul=new POINT2(clipBounds.getMinX(),clipBounds.getMinY());
1930                POINT2 lr=new POINT2(clipBounds.getMaxX(),clipBounds.getMaxY());
1931                savepoints=lineutility.BoundOneSegment(savepoints[0], savepoints[1], ul, lr);
1932            }
1933            if(savepoints==null)
1934            {
1935                savepoints=new POINT2[2];
1936                for (j = 0; j < 2; j++) {
1937                    savepoints[j] = new POINT2(points[j]);
1938                }
1939                drawJaggies=false;
1940            }
1941
1942            lineutility.InitializePOINT2Array(pts);
1943            //reverse the points
1944
1945            dAngle1 = Math.atan2(savepoints[0].y - savepoints[1].y, savepoints[0].x - savepoints[1].x);
1946            dLength = Math.sqrt((savepoints[1].x - savepoints[0].x) * (savepoints[1].x - savepoints[0].x) +
1947                    (savepoints[1].y - savepoints[0].y) * (savepoints[1].y - savepoints[0].y));
1948            //arraysupport tries to set jaggylength before the points get bounded
1949            dJaggyHalfAmp = dLength / 15; // half the amplitude of the "jaggy function"
1950
1951            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
1952            if (dJaggyHalfAmp > maxLength * DPIScaleFactor) {
1953                dJaggyHalfAmp = maxLength * DPIScaleFactor;
1954            }
1955            if (dJaggyHalfAmp < minLength * DPIScaleFactor) {
1956                dJaggyHalfAmp = minLength * DPIScaleFactor;
1957            }
1958
1959            dJaggyHalfPeriod = dJaggyHalfAmp / 1.5; // half the period of the "jaggy function"
1960            dDeltaXOut = Math.cos(dAngle1 + CONST_PI / 2) * dJaggyHalfAmp; // X-delta out from the center line
1961            dDeltaYOut = Math.sin(dAngle1 + CONST_PI / 2) * dJaggyHalfAmp; // Y-delta out from the center line
1962            dDeltaXAlong = Math.cos(dAngle1) * dJaggyHalfPeriod; // X-delta along the center line
1963            dDeltaYAlong = Math.sin(dAngle1) * dJaggyHalfPeriod; // Y-delta along the center line
1964            iNumJaggies = (int) (dLength / dJaggyHalfPeriod) - 3;
1965            i = 2;
1966            pts[0] = new POINT2(savepoints[1]);
1967            pts[1].x = savepoints[1].x + dDeltaXAlong * 1.5;
1968            pts[1].y = savepoints[1].y + dDeltaYAlong * 1.5;
1969            //DrawLine(destination, mask, color, pts, 2, 2);
1970            points[counter] = new POINT2(pts[0]);
1971            points[counter].style = 0;
1972            counter++;
1973            points[counter] = new POINT2(pts[1]);
1974            points[counter].style = 5;
1975            counter++;
1976
1977            pts[0].x = savepoints[1].x + dDeltaXOut + dDeltaXAlong * i;
1978            pts[0].y = savepoints[1].y + dDeltaYOut + dDeltaYAlong * i;
1979            i++;
1980            points[counter] = new POINT2(pts[0]);
1981            points[counter].style = 0;
1982            counter++;
1983            points[counter] = new POINT2(pts[1]);
1984            points[counter].style = 5;
1985            counter++;
1986
1987            if(drawJaggies) {
1988                while (i <= iNumJaggies) {
1989                    pts[1].x = savepoints[1].x - dDeltaXOut + dDeltaXAlong * i;
1990                    pts[1].y = savepoints[1].y - dDeltaYOut + dDeltaYAlong * i;
1991                    i++;
1992                    pts[2].x = savepoints[1].x + dDeltaXOut + dDeltaXAlong * i;
1993                    pts[2].y = savepoints[1].y + dDeltaYOut + dDeltaYAlong * i;
1994                    i++;
1995                    for (j = 0; j < 3; j++) {
1996                        points[counter] = new POINT2(pts[j]);
1997                        points[counter].style = 0;
1998                        counter++;
1999                    }
2000                    points[counter - 1].style = 5;
2001                    pts[0] = new POINT2(pts[2]);
2002                }
2003            }
2004
2005            pts[1] = new POINT2(pts[0]);
2006            pts[0].x = savepoints[1].x + dDeltaXAlong * i;
2007            pts[0].y = savepoints[1].y + dDeltaYAlong * i;
2008            points[counter] = new POINT2(pts[0]);
2009            points[counter].style = 0;
2010            counter++;
2011            points[counter] = new POINT2(pts[1]);
2012            points[counter].style = 5;
2013            counter++;
2014
2015            pts[1] = new POINT2(savepoints[0]);
2016            //DrawLine(destination, mask, color, pts, 2, 2);
2017            points[counter] = new POINT2(pts[0]);
2018            points[counter].style = 0;
2019            counter++;
2020            points[counter] = new POINT2(pts[1]);
2021            points[counter].style = 5;
2022            counter++;
2023
2024            // draw arrowhead
2025            pts[0].x = savepoints[0].x + dDeltaXOut / 1.5 - dDeltaXAlong;
2026            pts[0].y = savepoints[0].y + dDeltaYOut / 1.5 - dDeltaYAlong;
2027            pts[2].x = savepoints[0].x - dDeltaXOut / 1.5 - dDeltaXAlong;
2028            pts[2].y = savepoints[0].y - dDeltaYOut / 1.5 - dDeltaYAlong;
2029            for (j = 0; j < 3; j++) {
2030                points[counter] = new POINT2(pts[j]);
2031                if (linetype == (long) TacticalLines.MNFLDFIX) {
2032                    points[counter].style = 9;
2033                } else {
2034                    points[counter].style = 0;
2035                }
2036                counter++;
2037            }
2038            if (linetype == (long) TacticalLines.MNFLDFIX) {
2039                points[counter - 1].style = 10;
2040            } else {
2041                points[counter - 1].style = 5;
2042            }
2043
2044        } catch (Exception exc) {
2045            ErrorLogger.LogException(_className ,"GetDISMFixDouble",
2046                    new RendererException("Failed inside GetDISMFixDouble", exc));
2047        }
2048        return counter;
2049    }
2050    /**
2051     * Calculates the points for CLEAR.
2052     *
2053     * @param points OUT - the client points, also used for the returned points.
2054     * @param linetype the line type.
2055     */
2056    protected static int GetDISMClearDouble(POINT2[] points, int linetype) {
2057        int counter = 0;
2058        try {
2059            POINT2[] savepoints = new POINT2[3];
2060            int j = 0;
2061            POINT2[] pts = new POINT2[2];
2062            POINT2[] ptsArrow = new POINT2[3];
2063            double ctrX =  ((points[0].x + points[1].x) / 2);
2064            double ctrY =  ((points[0].y + points[1].y) / 2);
2065            ref<double[]> iDeltaX1 = new ref(), iDeltaY1 = new ref(), iDeltaX2 = new ref(), iDeltaY2 = new ref();
2066            POINT2[] deltapoints1 = new POINT2[4];
2067            POINT2[] deltapoints2 = new POINT2[4];
2068            POINT2[] deltapoints3 = new POINT2[4];
2069
2070            for (j = 0; j < 3; j++) {
2071                savepoints[j] = new POINT2(points[j]);
2072            }
2073
2074            lineutility.InitializePOINT2Array(pts);
2075            lineutility.InitializePOINT2Array(ptsArrow);
2076            lineutility.InitializePOINT2Array(deltapoints1);
2077            lineutility.InitializePOINT2Array(deltapoints2);
2078            lineutility.InitializePOINT2Array(deltapoints3);
2079
2080            //DrawLine(destination, mask, color, points, 2, 2);
2081            points[counter] = new POINT2(savepoints[0]);
2082            points[counter].style = 0;
2083            counter++;
2084            points[counter] = new POINT2(savepoints[1]);
2085            points[counter].style = 5;
2086            counter++;
2087
2088            pts[0].x = ctrX;
2089            pts[0].y = ctrY;
2090            pts[1] = new POINT2(savepoints[2]);
2091            ptsArrow[0] = new POINT2(pts[0]);
2092            //DrawLine(destination, mask, color, pts, 2, 2);
2093            points[counter] = new POINT2(pts[0]);
2094            points[counter].style = 0;
2095            counter++;
2096            points[counter] = new POINT2(pts[1]);
2097            points[counter].style = 5;
2098            counter++;
2099
2100            pts[0].x = (savepoints[0].x + ctrX) / 2;
2101            pts[0].y = (savepoints[0].y + ctrY) / 2;
2102            pts[1].x = savepoints[2].x + savepoints[0].x - pts[0].x;
2103            pts[1].y = savepoints[2].y + savepoints[0].y - pts[0].y;
2104            ptsArrow[1] = new POINT2(pts[0]);
2105            //DrawLine(destination, mask, color, pts, 2, 2);
2106            points[counter] = new POINT2(pts[0]);
2107            points[counter].style = 0;
2108            counter++;
2109            points[counter] = new POINT2(pts[1]);
2110            points[counter].style = 5;
2111            counter++;
2112
2113            pts[0].x = (savepoints[1].x + ctrX) / 2;
2114            pts[0].y = (savepoints[1].y + ctrY) / 2;
2115            pts[1].x = savepoints[2].x + savepoints[1].x - pts[0].x;
2116            pts[1].y = savepoints[2].y + savepoints[1].y - pts[0].y;
2117            ptsArrow[2] = new POINT2(pts[0]);
2118            points[counter] = new POINT2(pts[0]);
2119            points[counter].style = 0;
2120            counter++;
2121            points[counter] = new POINT2(pts[1]);
2122            points[counter].style = 5;
2123            counter++;
2124
2125            CalcEndpieceDeltasDouble(savepoints, iDeltaX1, iDeltaY1, CONST_PI / 6);
2126            CalcEndpieceDeltasDouble(savepoints, iDeltaX2, iDeltaY2, -CONST_PI / 6);
2127            DrawEndpieceDeltasDouble(ptsArrow[0],
2128                    iDeltaX1.value[0], iDeltaY1.value[0], iDeltaX2.value[0], iDeltaY2.value[0], deltapoints1);
2129            DrawEndpieceDeltasDouble(ptsArrow[1],
2130                    iDeltaX1.value[0], iDeltaY1.value[0], iDeltaX2.value[0], iDeltaY2.value[0], deltapoints2);
2131            DrawEndpieceDeltasDouble(ptsArrow[2],
2132                    iDeltaX1.value[0], iDeltaY1.value[0], iDeltaX2.value[0], iDeltaY2.value[0], deltapoints3);
2133            for (j = 0; j < 4; j++) {
2134                points[counter] = new POINT2(deltapoints1[j]);
2135                counter++;
2136            }
2137            for (j = 0; j < 4; j++) {
2138                points[counter] = new POINT2(deltapoints2[j]);
2139                counter++;
2140            }
2141            for (j = 0; j < 4; j++) {
2142                points[counter] = new POINT2(deltapoints3[j]);
2143                counter++;
2144            }
2145        } catch (Exception exc) {
2146            ErrorLogger.LogException(_className ,"GetDISMClearDouble",
2147                    new RendererException("Failed inside GetDISMClearDouble", exc));
2148        }
2149        return counter;
2150    }
2151    private static boolean IsSeizeArcReversed(POINT2[] pPoints){
2152        try {
2153            double dAngle1 = Math.atan2(pPoints[0].y - pPoints[1].y, pPoints[0].x - pPoints[1].x);
2154            double dDeltaX1 = Math.cos(dAngle1 + CONST_PI / 4);
2155            double dDeltaY1 = Math.sin(dAngle1 + CONST_PI / 4);
2156            double dDeltaX2 = Math.cos(dAngle1 - CONST_PI / 4);
2157            double dDeltaY2 = Math.sin(dAngle1 - CONST_PI / 4);
2158
2159            double dChordLength = Math.sqrt((pPoints[1].x - pPoints[0].x) * (pPoints[1].x - pPoints[0].x) +
2160                    (pPoints[1].y - pPoints[0].y) * (pPoints[1].y - pPoints[0].y));
2161            double dArcRadius = dChordLength / 1.414213562373; // sqrt(2) == 1.414213562373
2162            POINT2 ptArcCenter = new POINT2();
2163
2164            //get the default center
2165            ptArcCenter.x = pPoints[0].x - dDeltaX1 * dArcRadius;
2166            ptArcCenter.y = pPoints[0].y - dDeltaY1 * dArcRadius;
2167            double d = lineutility.CalcDistanceDouble(ptArcCenter, pPoints[2]);
2168
2169            //get the alternate center if the arc is reversed
2170            POINT2 ptArcCenterReversed = new POINT2();
2171            ptArcCenterReversed.x = pPoints[0].x - dDeltaX2 * dArcRadius;
2172            ptArcCenterReversed.y = pPoints[0].y - dDeltaY2 * dArcRadius;
2173            double dReversed = lineutility.CalcDistanceDouble(ptArcCenterReversed, pPoints[2]);
2174
2175            if (dReversed > d) {
2176                return true;
2177            } else {
2178                return false;
2179            }
2180        } catch (Exception exc) {
2181            ErrorLogger.LogException(_className ,"IsSeizeArcReversed",
2182                    new RendererException("Failed inside IsSeizeArcReversed", exc));
2183        }
2184        return false;
2185    }
2186    /**
2187     * Calculates the points for SEIZE
2188     *
2189     * @param points OUT - the client points, also used for the returned points.
2190     * @param linetype the line type.
2191     */
2192    protected static int GetDISMSeizeDouble(POINT2[] points,
2193            int linetype,
2194            double radius) 
2195    {
2196        int counter = 0;
2197        try {
2198            POINT2 ptArcCenter = new POINT2();
2199            POINT2 ptArcStart = new POINT2();
2200            POINT2[] savepoints = new POINT2[3];
2201            float scale = (float) 0.9;
2202            double iCircleRadius =  (25 * scale);
2203            POINT2[] arcpoints = new POINT2[17];
2204            POINT2[] pts = new POINT2[3];
2205            double dAngle1 = 0;
2206            double dDeltaX1 = 0;
2207            double dDeltaY1 = 0;
2208            double dDeltaX2 = 0;
2209            double dDeltaY2 = 0;
2210            double dChordLength = 0;
2211            double dArcRadius = 0;
2212            int j = 0;
2213            double dDeltaX3 = 0;
2214            double dDeltaY3 = 0;
2215            double iDiagEOL_length = 0;
2216            double factor = 1;
2217
2218            if(radius>0)
2219                iCircleRadius=radius;
2220            
2221            
2222            for (j = 0; j < 3; j++) {
2223                savepoints[j] = new POINT2(points[j]);
2224            }
2225            
2226            //if radius is 0 then it is rev B
2227            String client=CELineArray.getClient();
2228            if(!client.startsWith("cpof") && radius==0)
2229            {
2230                dArcRadius=lineutility.CalcDistanceDouble(savepoints[0], savepoints[1]);
2231                if(iCircleRadius>dArcRadius/2)
2232                    iCircleRadius=dArcRadius/2;
2233            }
2234
2235            lineutility.InitializePOINT2Array(pts);
2236            lineutility.InitializePOINT2Array(arcpoints);
2237            // draw circle
2238            ArcApproximationDouble(savepoints[0].x - iCircleRadius, savepoints[0].y - iCircleRadius,
2239                    savepoints[0].x + iCircleRadius, savepoints[0].y + iCircleRadius,
2240                    savepoints[0].x, savepoints[0].y, savepoints[0].x, savepoints[0].y, arcpoints);
2241            for (j = 0; j < 17; j++) {
2242                points[counter] = new POINT2(arcpoints[j]);
2243                points[counter].style = 0;
2244                counter++;
2245            }
2246            points[counter - 1].style = 5;
2247
2248            // draw arc
2249            dAngle1 = Math.atan2(savepoints[0].y - savepoints[1].y, savepoints[0].x - savepoints[1].x);
2250            dDeltaX1 = Math.cos(dAngle1 + CONST_PI / 4);
2251            dDeltaY1 = Math.sin(dAngle1 + CONST_PI / 4);
2252            dDeltaX2 = Math.cos(dAngle1 - CONST_PI / 4);
2253            dDeltaY2 = Math.sin(dAngle1 - CONST_PI / 4);
2254
2255            boolean isArcReversed = IsSeizeArcReversed(savepoints);
2256
2257            if (isArcReversed == false) {
2258                ptArcStart.x = savepoints[0].x - dDeltaX2 * iCircleRadius;
2259                ptArcStart.y = savepoints[0].y - dDeltaY2 * iCircleRadius;
2260                dChordLength = Math.sqrt((savepoints[1].x - savepoints[0].x) * (savepoints[1].x - savepoints[0].x) +
2261                        (savepoints[1].y - savepoints[0].y) * (savepoints[1].y - savepoints[0].y));
2262                dArcRadius = dChordLength / 1.414213562373; // sqrt(2) == 1.414213562373
2263                ptArcCenter.x = savepoints[0].x - dDeltaX1 * dArcRadius;
2264                ptArcCenter.y = savepoints[0].y - dDeltaY1 * dArcRadius;
2265
2266                ArcApproximationDouble((ptArcCenter.x - dArcRadius), (ptArcCenter.y - dArcRadius),
2267                        (ptArcCenter.x + dArcRadius), (ptArcCenter.y + dArcRadius),
2268                        savepoints[1].x, savepoints[1].y, ptArcStart.x, ptArcStart.y, arcpoints);
2269                for (j = 0; j < 17; j++) {
2270                    if (lineutility.CalcDistanceDouble(savepoints[0], arcpoints[j]) >= iCircleRadius) {
2271                        points[counter] = new POINT2(arcpoints[j]);
2272                        points[counter].style = 0;
2273                        counter++;
2274                    } else if (j > 0) {
2275                        // Last point was outside the circle this point is inside
2276                        POINT2 intersectPt = lineutility.intersectPolygon(Arrays.copyOfRange(points, 0, 17), arcpoints[j], arcpoints[j - 1]);
2277                        if (intersectPt == null) {
2278                            intersectPt = arcpoints[j];
2279                        }
2280
2281                        // Add remaining points to keep constant count
2282                        for (int k = j; k < 17; k++) {
2283                            points[counter] = new POINT2(intersectPt);
2284                            points[counter].style = 0;
2285                            counter++;
2286                        }
2287                        break;
2288                    } else {
2289                        // All points are in the circle
2290                        for (j = 0; j < 17; j++) {
2291                            points[counter] = new POINT2(arcpoints[j]);
2292                            points[counter].style = 0;
2293                            counter++;
2294                        }
2295                        break;
2296                    }
2297                }
2298            } else //arc is reversed
2299            {
2300                ptArcStart.x = savepoints[0].x - dDeltaX1 * iCircleRadius;
2301                ptArcStart.y = savepoints[0].y - dDeltaY1 * iCircleRadius;
2302                dChordLength = Math.sqrt((savepoints[1].x - savepoints[0].x) * (savepoints[1].x - savepoints[0].x) +
2303                        (savepoints[1].y - savepoints[0].y) * (savepoints[1].y - savepoints[0].y));
2304                dArcRadius = dChordLength / 1.414213562373; // sqrt(2) == 1.414213562373
2305                ptArcCenter.x = savepoints[0].x - dDeltaX2 * dArcRadius;
2306                ptArcCenter.y = savepoints[0].y - dDeltaY2 * dArcRadius;
2307                ArcApproximationDouble((ptArcCenter.x - dArcRadius), (ptArcCenter.y - dArcRadius),
2308                        (ptArcCenter.x + dArcRadius), (ptArcCenter.y + dArcRadius),
2309                        ptArcStart.x, ptArcStart.y, savepoints[1].x, savepoints[1].y, arcpoints);
2310                boolean outsideCircle = false;
2311                for (j = 0; j < 17; j++) {
2312                    // Don't include points inside circle
2313                    if (outsideCircle || lineutility.CalcDistanceDouble(savepoints[0], arcpoints[j]) >= iCircleRadius) {
2314                        if (!outsideCircle && j > 0) {
2315                            // Last point was inside the circle this point is outside
2316                            POINT2 intersectPt = lineutility.intersectPolygon(Arrays.copyOfRange(points, 0, 17), arcpoints[j], arcpoints[j - 1]);
2317                            if (intersectPt == null) {
2318                                intersectPt = arcpoints[j - 1];
2319                            }
2320
2321                            // Add skipped points to keep constant count
2322                            for (int k = 0; k < j; k++) {
2323                                points[counter] = new POINT2(intersectPt);
2324                                points[counter].style = 0;
2325                                counter++;
2326                            }
2327                        }
2328
2329                        points[counter] = new POINT2(arcpoints[j]);
2330                        points[counter].style = 0;
2331                        counter++;
2332                        outsideCircle = true;
2333                    }
2334                }
2335                if (!outsideCircle) {
2336                    // All points are in the circle
2337                    for (j = 0; j < 17; j++) {
2338                        points[counter] = new POINT2(arcpoints[j]);
2339                        points[counter].style = 0;
2340                        counter++;
2341                    }
2342                }
2343            }
2344            points[counter - 1].style = 5;
2345
2346            // draw arrow
2347            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
2348            if (dChordLength / 8 > maxLength * DPIScaleFactor) {
2349                factor = dChordLength / (8 * maxLength * DPIScaleFactor);
2350            }
2351            if (factor == 0) {
2352                factor = 1;
2353            }
2354
2355
2356            if (isArcReversed == false) {
2357                pts[0].x = savepoints[1].x - (savepoints[1].x - savepoints[0].x) / (8 * factor);
2358                pts[0].y = savepoints[1].y - (savepoints[1].y - savepoints[0].y) / (8 * factor);
2359                pts[1] = new POINT2(savepoints[1]);
2360                dDeltaX3 = Math.cos(dAngle1 + CONST_PI / 2);
2361                dDeltaY3 = Math.sin(dAngle1 + CONST_PI / 2);
2362                iDiagEOL_length =  (dChordLength / 8);
2363                pts[2].x = savepoints[1].x + dDeltaX3 * iDiagEOL_length / factor;
2364                pts[2].y = savepoints[1].y + dDeltaY3 * iDiagEOL_length / factor;
2365            } //DrawLine(destination, mask, color, pts, 3, 2);
2366            //diagnostic arc reversed
2367            else {
2368                pts[0].x = savepoints[1].x - (savepoints[1].x - savepoints[0].x) / (8 * factor);
2369                pts[0].y = savepoints[1].y - (savepoints[1].y - savepoints[0].y) / (8 * factor);
2370                pts[1] = new POINT2(savepoints[1]);
2371                dDeltaX3 = Math.cos(dAngle1 - CONST_PI / 2);
2372                dDeltaY3 = Math.sin(dAngle1 - CONST_PI / 2);
2373                iDiagEOL_length =  (dChordLength / 8);
2374                pts[2].x = savepoints[1].x + dDeltaX3 * iDiagEOL_length / factor;
2375                pts[2].y = savepoints[1].y + dDeltaY3 * iDiagEOL_length / factor;
2376            }
2377            //end diagnostic
2378
2379
2380            //diagnostic
2381            //end diagnostic
2382
2383            for (j = 0; j < 3; j++) {
2384                points[counter] = new POINT2(pts[j]);
2385                points[counter].style = 0;
2386                counter++;
2387            }
2388            points[counter - 1].style = 5;
2389        } catch (Exception exc) {
2390            ErrorLogger.LogException(_className ,"GetDISMSeizeDouble",
2391                    new RendererException("Failed inside GetDISMSeizeDouble", exc));
2392        }
2393        return counter;
2394    }
2395    /**
2396     * Used twice for RIP to determine if the points are clockwise.
2397     * @param x1
2398     * @param y1
2399     * @param x2
2400     * @param y2
2401     * @param px
2402     * @param py
2403     * @return RIGHT_SIDE if 3 points are clockwise
2404     */
2405    private static int side(double x1, double y1, double x2, double y2, double px, double py) {
2406        double dx1, dx2, dy1, dy2;
2407        try {
2408            double o;
2409
2410            dx1 = x2 - x1;
2411            dy1 = y2 - y1;
2412            dx2 = px - x1;
2413            dy2 = py - y1;
2414            o = (dx1 * dy2) - (dy1 * dx2);
2415            if (o > 0.0) {
2416                return (LEFT_SIDE);
2417            }
2418            if (o < 0.0) {
2419                return (RIGHT_SIDE);
2420            }
2421        } catch (Exception exc) {
2422            ErrorLogger.LogException(_className, "side",
2423                    new RendererException("Failed inside side", exc));
2424        }
2425        return (COLINEAR);
2426    }
2427
2428    /**
2429     * Calculates the points for RIP
2430     *
2431     * @param points OUT - the client points, also used for the returned points.
2432     * @param linetype the line type
2433     */
2434    protected static int GetDISMRIPDouble(POINT2[] points, int linetype) {
2435        int counter = 0;
2436        try {
2437            // draw the straight lines
2438            POINT2[] pts = new POINT2[2];
2439            POINT2[] savepoints = new POINT2[4];
2440            int j = 0;
2441            double iLengthPt0Pt1 = 0;
2442            double iDiagEOL_length = 0;
2443            double dAngle1 = 0;
2444            double iDeltaX1 = 0;
2445            double iDeltaY1 = 0;
2446            double iDeltaX2 = 0;
2447            double iDeltaY2 = 0;
2448            double iLengthPt2Pt3 = 0;
2449            double iRadius = 0;
2450            POINT2[] deltapoints = new POINT2[4];
2451            POINT2[] arcpoints = new POINT2[17];
2452            POINT2 ptArcCenter = new POINT2();
2453
2454            boolean clockwise=false;
2455            int side01=side(points[0].x,points[0].y,points[1].x,points[1].y,points[2].x,points[2].y);
2456            int side12=side(points[1].x,points[1].y,points[2].x,points[2].y,points[3].x,points[3].y);
2457            if(side01==RIGHT_SIDE && side12==RIGHT_SIDE)
2458                clockwise=true;
2459            else if(side01==RIGHT_SIDE && side12==COLINEAR)
2460                clockwise=true;
2461            else if(side01==COLINEAR && side12==RIGHT_SIDE)
2462                clockwise=true;
2463
2464            for (j = 0; j < 4; j++) {
2465                savepoints[j] = new POINT2(points[j]);
2466            }
2467
2468            lineutility.InitializePOINT2Array(pts);
2469            lineutility.InitializePOINT2Array(deltapoints);
2470            lineutility.InitializePOINT2Array(arcpoints);
2471
2472            points[counter] = new POINT2(savepoints[0]);
2473            points[counter].style = 0;
2474            counter++;
2475            points[counter] = new POINT2(savepoints[1]);
2476            points[counter].style = 5;
2477            counter++;
2478
2479            pts[0] = new POINT2(savepoints[2]);
2480            pts[1] = new POINT2(savepoints[3]);
2481            points[counter] = new POINT2(pts[0]);
2482            points[counter].style = 0;
2483            counter++;
2484            points[counter] = new POINT2(pts[1]);
2485            points[counter].style = 5;
2486            counter++;
2487
2488            // draw the arrowhead on line between savepoints 0 and 1
2489            pts[0] = new POINT2(savepoints[0]);
2490            pts[1] = new POINT2(savepoints[1]);
2491            iLengthPt0Pt1 =  Math.sqrt((pts[1].x - pts[0].x) * (pts[1].x - pts[0].x) +
2492                    (pts[1].y - pts[0].y) * (pts[1].y - pts[0].y));
2493            iDiagEOL_length = iLengthPt0Pt1 / 8;
2494
2495            //M. Deutch 8-19-04
2496            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
2497            if (iDiagEOL_length >  maxLength * DPIScaleFactor) {
2498                iDiagEOL_length =  maxLength * DPIScaleFactor;
2499            }
2500            if (iDiagEOL_length <  minLength * DPIScaleFactor) {
2501                iDiagEOL_length =  minLength * DPIScaleFactor;
2502            }
2503
2504            dAngle1 = Math.atan2(pts[1].y - pts[0].y, pts[1].x - pts[0].x);
2505            iDeltaX1 =  (iDiagEOL_length * Math.cos(dAngle1 - CONST_PI / 4));
2506            iDeltaY1 =  (iDiagEOL_length * Math.sin(dAngle1 - CONST_PI / 4));
2507            iDeltaX2 =  (iDiagEOL_length * Math.cos(dAngle1 + CONST_PI / 4));
2508            iDeltaY2 =  (iDiagEOL_length * Math.sin(dAngle1 + CONST_PI / 4));
2509            DrawEndpieceDeltasDouble(pts[0],
2510                    iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints);
2511            for (j = 0; j < 4; j++) {
2512                points[counter] = new POINT2(deltapoints[j]);
2513                points[counter].style = 0;
2514                counter++;
2515            }
2516            points[counter - 3].style = 5;
2517            points[counter - 1].style = 5;
2518
2519            // draw the arrowhead on line between savepoints 2 and 3
2520            if (linetype == TacticalLines.RIP) {
2521                pts[0] = new POINT2(savepoints[2]);
2522                pts[1] = new POINT2(savepoints[3]);
2523                iLengthPt2Pt3 =  Math.sqrt((pts[1].x - pts[0].x) * (pts[1].x - pts[0].x) +
2524                        (pts[1].y - pts[0].y) * (pts[1].y - pts[0].y));
2525                iDiagEOL_length = iLengthPt2Pt3 / 8;
2526
2527                //M. Deutch 8-19-04
2528                if (iDiagEOL_length >  maxLength * DPIScaleFactor) {
2529                    iDiagEOL_length =  maxLength * DPIScaleFactor;
2530                }
2531                if (iDiagEOL_length <  minLength * DPIScaleFactor) {
2532                    iDiagEOL_length =  minLength * DPIScaleFactor;
2533                }
2534
2535                dAngle1 = Math.atan2(pts[1].y - pts[0].y, pts[1].x - pts[0].x);
2536                iDeltaX1 =  (iDiagEOL_length * Math.cos(dAngle1 - CONST_PI / 4));
2537                iDeltaY1 =  (iDiagEOL_length * Math.sin(dAngle1 - CONST_PI / 4));
2538                iDeltaX2 =  (iDiagEOL_length * Math.cos(dAngle1 + CONST_PI / 4));
2539                iDeltaY2 =  (iDiagEOL_length * Math.sin(dAngle1 + CONST_PI / 4));
2540                DrawEndpieceDeltasDouble(pts[0],
2541                        iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints);
2542                for (j = 0; j < 4; j++) {
2543                    points[counter] = new POINT2(deltapoints[j]);
2544                    points[counter].style = 0;
2545                    counter++;
2546                }
2547                points[counter - 3].style = 5;
2548                points[counter - 1].style = 5;
2549            }
2550
2551            // draw the semicircle
2552            iRadius =  (Math.sqrt((savepoints[2].x - savepoints[1].x) * (savepoints[2].x - savepoints[1].x) +
2553                    (savepoints[2].y - savepoints[1].y) * (savepoints[2].y - savepoints[1].y)) / 2);
2554            ptArcCenter.x = (savepoints[1].x + savepoints[2].x) / 2;
2555            ptArcCenter.y = (savepoints[1].y + savepoints[2].y) / 2;
2556
2557            if(clockwise==false)
2558            {
2559                ArcApproximationDouble((ptArcCenter.x - iRadius), (ptArcCenter.y - iRadius),
2560                    (ptArcCenter.x + iRadius), (ptArcCenter.y + iRadius),
2561                    savepoints[2].x, savepoints[2].y, savepoints[1].x, savepoints[1].y, arcpoints);
2562            }
2563            else
2564            {
2565                ArcApproximationDouble((ptArcCenter.x - iRadius), (ptArcCenter.y - iRadius),
2566                    (ptArcCenter.x + iRadius), (ptArcCenter.y + iRadius),
2567                    savepoints[1].x, savepoints[1].y, savepoints[2].x, savepoints[2].y, arcpoints);
2568            }
2569            for (j = 0; j < 17; j++) {
2570                points[counter] = new POINT2(arcpoints[j]);
2571                points[counter].style = 0;
2572                counter++;
2573            }
2574            points[counter - 1].style = 5;
2575        } catch (Exception exc) {
2576            ErrorLogger.LogException(_className ,"GetDISMRIPDouble",
2577                    new RendererException("Failed inside GetDISMRIPDouble", exc));
2578        }
2579        return counter;
2580    }
2581    /**
2582     * Calculates the points for BYDIF
2583     *
2584     * @param points OUT - the client points, also used for the returned points.
2585     * @param linetype the line type.
2586     */
2587    protected static int GetDISMByDifDouble(POINT2[] points,
2588            int linetype,
2589            Rectangle2D clipBounds) {
2590        int counter = 0;
2591        try {
2592            POINT2[] pointsCorner = new POINT2[2];
2593            POINT2[] rectpts = new POINT2[4];
2594            POINT2[] savepoints = new POINT2[3], savepoints2 = new POINT2[2];
2595            POINT2[] deltapoints1 = new POINT2[4];
2596            POINT2[] deltapoints2 = new POINT2[4];
2597            POINT2[] pts = new POINT2[3];
2598            //POINT2 pt0 = new POINT2();
2599            //POINT2 pt1 = new POINT2();
2600            ref<double[]> iDeltaX = new ref(), iDeltaY = new ref();
2601            int bPointsRight = 0;
2602            double dAngle1 = 0;
2603            double dLength = 0;
2604            double dJaggyHalfAmp = 0;
2605            double dJaggyHalfPeriod = 0;
2606            double dDeltaXOut = 0;
2607            double dDeltaYOut = 0;
2608            double dDeltaXAlong = 0;
2609            double dDeltaYAlong = 0;
2610            int iNumJaggies = 0;
2611            int i = 0, j = 0;
2612            //int pointcounter = 0;
2613            //int[] segments = null;
2614            //end declarations
2615            //lineutility.WriteFile("made it this far");
2616            //ok to here
2617
2618            for (j = 0; j < 3; j++) {
2619                savepoints[j] = new POINT2(points[j]);
2620            }
2621
2622            lineutility.InitializePOINT2Array(pointsCorner);
2623            lineutility.InitializePOINT2Array(rectpts);
2624            lineutility.InitializePOINT2Array(pts);
2625            lineutility.InitializePOINT2Array(deltapoints1);
2626            lineutility.InitializePOINT2Array(deltapoints2);
2627
2628            DrawOpenRectangleDouble(savepoints, pointsCorner, rectpts);
2629            //save the back side for use by the jagged line
2630            savepoints2[0] = new POINT2(rectpts[1]);
2631            savepoints2[1] = new POINT2(rectpts[2]);
2632
2633            //diagnostic these hard coded because JavalineArray does not know the bounds
2634            if(clipBounds != null)
2635            {
2636                POINT2 ul=new POINT2(clipBounds.getMinX(),clipBounds.getMinY());
2637                POINT2 lr=new POINT2(clipBounds.getMaxX(),clipBounds.getMaxY());
2638                savepoints2=lineutility.BoundOneSegment(savepoints2[0], savepoints2[1], ul, lr);
2639            }
2640            Boolean drawJaggies=true;
2641            if(savepoints2==null)
2642            {
2643                savepoints2 = new POINT2[2];
2644                savepoints2[0] = new POINT2(rectpts[1]);
2645                savepoints2[1] = new POINT2(rectpts[2]);
2646                drawJaggies=false;
2647            }
2648            for (j = 0; j < 4; j++) {
2649                points[counter] = new POINT2(rectpts[j]);
2650                points[counter].style = 0;
2651                counter++;
2652            }
2653            points[1].style = 5;
2654            points[counter - 1].style = 5;
2655
2656            dAngle1 = Math.atan2(savepoints2[0].y - savepoints2[1].y, savepoints2[0].x - savepoints2[1].x);
2657            dLength = Math.sqrt((savepoints2[1].x - savepoints2[0].x) * (savepoints2[1].x - savepoints2[0].x) +
2658                    (savepoints2[1].y - savepoints2[0].y) * (savepoints2[1].y - savepoints2[0].y));
2659            dJaggyHalfAmp = dLength / 15; // half the amplitude of the "jaggy function"
2660
2661            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
2662            if (dJaggyHalfAmp > maxLength * DPIScaleFactor) {
2663                dJaggyHalfAmp = maxLength * DPIScaleFactor;
2664            }
2665            if (dJaggyHalfAmp < minLength * DPIScaleFactor) {
2666                dJaggyHalfAmp = minLength * DPIScaleFactor;
2667            }
2668
2669            dJaggyHalfPeriod = dJaggyHalfAmp / 1.5; // half the period of the "jaggy function"
2670            dDeltaXOut = Math.cos(dAngle1 + CONST_PI / 2) * dJaggyHalfAmp; // X-delta out from the center line
2671            dDeltaYOut = Math.sin(dAngle1 + CONST_PI / 2) * dJaggyHalfAmp; // Y-delta out from the center line
2672            dDeltaXAlong = Math.cos(dAngle1) * dJaggyHalfPeriod; // X-delta along the center line
2673            dDeltaYAlong = Math.sin(dAngle1) * dJaggyHalfPeriod; // Y-delta along the center line
2674
2675            iNumJaggies = (int) (dLength / dJaggyHalfPeriod) - 3;
2676            i = 2;
2677            pts[0] = new POINT2(savepoints2[1]);
2678            pts[1].x = savepoints2[1].x + dDeltaXAlong * 1.5;
2679            pts[1].y = savepoints2[1].y + dDeltaYAlong * 1.5;
2680            points[counter] = new POINT2(pts[0]);
2681            points[counter].style = 0;
2682            counter++;
2683            points[counter] = new POINT2(pts[1]);
2684            points[counter].style = 5;
2685            counter++;
2686
2687            pts[0].x = savepoints2[1].x + dDeltaXOut + dDeltaXAlong * i;
2688            pts[0].y = savepoints2[1].y + dDeltaYOut + dDeltaYAlong * i;
2689            i++;
2690            points[counter] = new POINT2(pts[0]);
2691            points[counter].style = 0;
2692            counter++;
2693            points[counter] = new POINT2(pts[1]);
2694            points[counter].style = 5;
2695            counter++;
2696            
2697            if(drawJaggies)//diagnostic
2698            {
2699                while (i <= iNumJaggies) {
2700                    pts[1].x = savepoints2[1].x - dDeltaXOut + dDeltaXAlong * i;
2701                    pts[1].y = savepoints2[1].y - dDeltaYOut + dDeltaYAlong * i;
2702                    i++;
2703                    pts[2].x = savepoints2[1].x + dDeltaXOut + dDeltaXAlong * i;
2704                    pts[2].y = savepoints2[1].y + dDeltaYOut + dDeltaYAlong * i;
2705                    i++;
2706                    for (j = 0; j < 3; j++) {
2707                        points[counter] = new POINT2(pts[j]);
2708                        points[counter].style = 0;
2709                        counter++;
2710                    }
2711                    points[counter - 1].style = 5;
2712                    pts[0] = new POINT2(pts[2]);
2713                }
2714            }
2715
2716            pts[1] = new POINT2(pts[0]);
2717            pts[0].x = savepoints2[1].x + dDeltaXAlong * i;
2718            pts[0].y = savepoints2[1].y + dDeltaYAlong * i;
2719            //DrawLine(destination, mask, color, pts, 2, 2);
2720            points[counter] = new POINT2(pts[0]);
2721            points[counter].style = 0;
2722            counter++;
2723            points[counter] = new POINT2(pts[1]);
2724            points[counter].style = 5;
2725            counter++;
2726
2727            pts[1] = new POINT2(savepoints2[0]);
2728            //DrawLine(destination, mask, color, pts, 2, 2);
2729            points[counter] = new POINT2(pts[0]);
2730            points[counter].style = 0;
2731            counter++;
2732            points[counter] = new POINT2(pts[1]);
2733            points[counter].style = 5;
2734            counter++;
2735
2736            bPointsRight = DetermineDirectionDouble(savepoints);
2737
2738            CalcEndpieceDeltasDouble(savepoints, iDeltaX, iDeltaY, CONST_PI / 4);
2739
2740            if ((savepoints[0].y - savepoints[1].y) < 0) {// Point0 is higher than Point1
2741                if (bPointsRight != 0) {// figure opens to the right
2742                    DrawEndpieceDeltasDouble(savepoints[0],
2743                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints1);
2744                    DrawEndpieceDeltasDouble(savepoints[1],
2745                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints2);
2746                } else {// figure opens to the left
2747                    DrawEndpieceDeltasDouble(savepoints[0],
2748                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints1);
2749                    DrawEndpieceDeltasDouble(savepoints[1],
2750                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints2);
2751                }
2752            } else {// Point0 is lower than Point1
2753                if (bPointsRight != 0) {// figure opens to the right
2754                    DrawEndpieceDeltasDouble(savepoints[0],
2755                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints1);
2756                    DrawEndpieceDeltasDouble(savepoints[1],
2757                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints2);
2758                } else {// figure opens to the left
2759                    DrawEndpieceDeltasDouble(savepoints[0],
2760                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints1);
2761                    DrawEndpieceDeltasDouble(savepoints[1],
2762                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints2);
2763                }
2764            }
2765            points[counter] = new POINT2(deltapoints1[1]);
2766            points[counter].style = 9;
2767            counter++;
2768            points[counter] = new POINT2(deltapoints1[0]);
2769            points[counter].style = 9;
2770            counter++;
2771            points[counter] = new POINT2(deltapoints1[3]);
2772            points[counter].style = 9;
2773            counter++;
2774            points[counter] = new POINT2(deltapoints1[3]);
2775            points[counter].style = 10;
2776            counter++;
2777
2778            points[counter] = new POINT2(deltapoints2[1]);
2779            points[counter].style = 9;
2780            counter++;
2781            points[counter] = new POINT2(deltapoints2[0]);
2782            points[counter].style = 9;
2783            counter++;
2784            points[counter] = new POINT2(deltapoints2[3]);
2785            points[counter].style = 9;
2786            counter++;
2787            points[counter] = new POINT2(deltapoints2[3]);
2788            points[counter].style = 10;
2789            counter++;
2790
2791        } catch (Exception exc) {
2792            //lineutility.WriteFile(exc.getMessage());
2793            ErrorLogger.LogException(_className ,"GetDISMByDifDouble",
2794                    new RendererException("Failed inside GetDISMByDifDouble", exc));
2795        }
2796        return counter;
2797    }
2798    /**
2799     * Calculates the points for PENETRATE
2800     *
2801     * @param points OUT - the client points, also used for the returned points.
2802     * @param linetype the line type.
2803     */
2804    protected static void GetDISMPenetrateDouble(POINT2[] points, int linetype) {
2805        try {
2806            POINT2[] arrowpts = new POINT2[3];
2807            POINT2 midpt = new POINT2();
2808            POINT2[] savepoints = new POINT2[3];
2809            int j = 0;
2810            double d = 0;
2811
2812            for (j = 0; j < 3; j++) {
2813                savepoints[j] = new POINT2(points[j]);
2814            }
2815            lineutility.InitializePOINT2Array(arrowpts);
2816
2817            points[0].x = savepoints[0].x;
2818            points[0].y = savepoints[0].y;
2819            points[0].style = 0;
2820            points[1].x = savepoints[1].x;
2821            points[1].y = savepoints[1].y;
2822            points[1].style = 5;
2823
2824            midpt = lineutility.MidPointDouble(savepoints[0], savepoints[1], 0);
2825
2826            points[2] = new POINT2(savepoints[2]);
2827
2828            points[3] = new POINT2(midpt);
2829            points[3].style = 5;
2830            d = lineutility.MBRDistance(savepoints, 3);
2831
2832            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
2833            if (d / 5 > maxLength * DPIScaleFactor) {
2834                d = 5 * maxLength * DPIScaleFactor;
2835            }
2836            if (d / 5 < minLength * DPIScaleFactor) {
2837                d = 5 * minLength * DPIScaleFactor;
2838            }
2839            String client=CELineArray.getClient();
2840            if(client.matches("cpof3d") || client.matches("cpof2d"))
2841            {
2842                if(d<400 * DPIScaleFactor)
2843                    d=400 * DPIScaleFactor;
2844            }
2845            else
2846            {
2847                if(d<150 * DPIScaleFactor)
2848                    d=150 * DPIScaleFactor;
2849            }
2850            if(d>600 * DPIScaleFactor)
2851                d=600 * DPIScaleFactor;
2852
2853            lineutility.GetArrowHead4Double(points[2], points[3], (int)d / 20,(int)d / 20, arrowpts, 0);
2854            for (j = 0; j < 3; j++) {
2855                points[4 + j] = new POINT2(arrowpts[j]);
2856            }
2857
2858        } catch (Exception exc) {
2859            ErrorLogger.LogException(_className ,"GetDISMPenetrateDouble",
2860                    new RendererException("Failed inside GetDISMPenetrateDouble", exc));
2861        }
2862    }
2863    /**
2864     * Calculates the points for BYIMP
2865     *
2866     * @param points OUT - the client points, also used for the returned points.
2867     * @param linetype the line type.
2868     */
2869    protected static int GetDISMByImpDouble(POINT2[] points,
2870            int linetype) {
2871        int counter = 0;
2872        try {
2873            int j = 0;
2874            POINT2[] pointsCorner = new POINT2[2];
2875            POINT2[] rectpts = new POINT2[4];
2876            POINT2[] savepoints = new POINT2[3];
2877            POINT2[] deltapoints1 = new POINT2[4];
2878            POINT2[] deltapoints2 = new POINT2[4];
2879            POINT2 midpt = new POINT2();
2880            POINT2[] pts = new POINT2[6];
2881            POINT2 ptRelative = new POINT2();
2882            ref<double[]> iDeltaX = new ref(), iDeltaY = new ref();
2883            int bPointsRight = 0;
2884            double dMBR = lineutility.MBRDistance(points, 3);
2885            //end declarations
2886
2887            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
2888            if (dMBR > 40 * maxLength * DPIScaleFactor) {
2889                dMBR = 40 * maxLength * DPIScaleFactor;
2890            }
2891            if (dMBR < 5 * minLength * DPIScaleFactor) {
2892                dMBR = 5 * minLength * DPIScaleFactor;
2893            }
2894            if(dMBR>250 * DPIScaleFactor)
2895                dMBR=250 * DPIScaleFactor;
2896            if(dMBR / 15 > lineutility.CalcDistanceDouble(points[0], points[1]))
2897                // Don't let gap be wider than channel
2898                dMBR = 15 * lineutility.CalcDistanceDouble(points[0], points[1]);
2899
2900            for (j = 0; j < 3; j++) {
2901                savepoints[j] = new POINT2(points[j]);
2902            }
2903
2904            lineutility.InitializePOINT2Array(rectpts);
2905            lineutility.InitializePOINT2Array(deltapoints1);
2906            lineutility.InitializePOINT2Array(deltapoints2);
2907            lineutility.InitializePOINT2Array(pts);
2908            lineutility.InitializePOINT2Array(pointsCorner);
2909
2910            DrawOpenRectangleDouble(savepoints, pointsCorner, rectpts);
2911
2912            points[counter] = new POINT2(rectpts[0]);
2913            points[counter].style = 0;
2914            counter++;
2915            points[counter] = new POINT2(rectpts[1]);
2916            points[counter].style = 0;
2917            counter++;
2918            midpt = lineutility.MidPointDouble(rectpts[1], rectpts[2], 0);
2919            pts[0] = lineutility.ExtendLine2Double(rectpts[1], midpt, -dMBR / 30, 5);
2920            pts[1] = lineutility.ExtendLine2Double(rectpts[1], midpt, dMBR / 30, 5);
2921            points[counter] = new POINT2(pts[0]);
2922            points[counter].style = 5;
2923            counter++;
2924
2925            ptRelative = lineutility.PointRelativeToLine(rectpts[0], rectpts[1], pts[0]);
2926            pts[2] = lineutility.ExtendLineDouble(ptRelative, pts[0], -dMBR / 30);
2927
2928            pts[3] = lineutility.ExtendLineDouble(ptRelative, pts[0], dMBR / 30);
2929
2930            points[counter] = new POINT2(pts[2]);
2931            points[counter].style = 0;
2932            counter++;
2933            points[counter] = new POINT2(pts[3]);
2934            points[counter].style = 5;
2935            counter++;
2936            ptRelative = lineutility.PointRelativeToLine(rectpts[2], rectpts[3], pts[1]);
2937            pts[4] = lineutility.ExtendLineDouble(ptRelative, pts[1], -dMBR / 30);
2938
2939            pts[5] = lineutility.ExtendLineDouble(ptRelative, pts[1], dMBR / 30);
2940            points[counter] = new POINT2(pts[4]);
2941            points[counter].style = 0;
2942            counter++;
2943            points[counter] = new POINT2(pts[5]);
2944            points[counter].style = 5;
2945            counter++;
2946            points[counter] = new POINT2(pts[1]);
2947            points[counter].style = 0;
2948            counter++;
2949            points[counter] = new POINT2(rectpts[2]);
2950            points[counter].style = 0;
2951            counter++;
2952            points[counter] = new POINT2(rectpts[3]);
2953            points[counter].style = 5;
2954            counter++;
2955
2956            bPointsRight = DetermineDirectionDouble(savepoints);
2957
2958            CalcEndpieceDeltasDouble(savepoints, iDeltaX, iDeltaY, CONST_PI / 4);
2959
2960            if ((savepoints[0].y - savepoints[1].y) < 0) {// Point0 is higher than Point1
2961                if (bPointsRight != 0) {// figure opens to the right
2962                    DrawEndpieceDeltasDouble(savepoints[0],
2963                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints1);
2964                    DrawEndpieceDeltasDouble(savepoints[1],
2965                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints2);
2966                } else {// figure opens to the left
2967                    DrawEndpieceDeltasDouble(savepoints[0],
2968                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints1);
2969                    DrawEndpieceDeltasDouble(savepoints[1],
2970                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints2);
2971                }
2972            } else {// Point0 is lower than Point1
2973                if (bPointsRight != 0) {// figure opens to the right
2974                    DrawEndpieceDeltasDouble(savepoints[0],
2975                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints1);
2976                    DrawEndpieceDeltasDouble(savepoints[1],
2977                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints2);
2978                } else {// figure opens to the left
2979                    DrawEndpieceDeltasDouble(savepoints[0],
2980                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints1);
2981                    DrawEndpieceDeltasDouble(savepoints[1],
2982                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints2);
2983                }
2984            }
2985
2986            points[counter] = new POINT2(deltapoints1[1]);
2987            points[counter].style = 9;
2988            counter++;
2989            points[counter] = new POINT2(deltapoints1[0]);
2990            points[counter].style = 9;
2991            counter++;
2992            points[counter] = new POINT2(deltapoints1[3]);
2993            points[counter].style = 9;
2994            counter++;
2995            points[counter] = new POINT2(deltapoints1[3]);
2996            points[counter].style = 10;
2997            counter++;
2998
2999            points[counter] = new POINT2(deltapoints2[1]);
3000            points[counter].style = 9;
3001            counter++;
3002            points[counter] = new POINT2(deltapoints2[0]);
3003            points[counter].style = 9;
3004            counter++;
3005            points[counter] = new POINT2(deltapoints2[3]);
3006            points[counter].style = 9;
3007            counter++;
3008            points[counter] = new POINT2(deltapoints2[3]);
3009            points[counter].style = 10;
3010            counter++;
3011
3012        } catch (Exception exc) {
3013            ErrorLogger.LogException(_className ,"GetDISMByImpDouble",
3014                    new RendererException("Failed inside GetDISMByImpDouble", exc));
3015        }
3016        return counter;
3017    }
3018    /**
3019     * Calculates the points for SPTBYFIRE
3020     *
3021     * @param points OUT - the client points, also used for the returned points.
3022     * @param linetype the line type.
3023     */
3024    protected static int GetDISMSupportByFireDouble(POINT2[] points,
3025            int linetype) {
3026        int counter = 0;
3027        try {
3028            POINT2[] pts = new POINT2[3];
3029            POINT2[] savepoints = new POINT2[4];
3030            int j = 0;
3031            double iDiagEOL_length = 0;
3032            double dAngle1 = 0;
3033            double iDeltaX1 = 0;
3034            double iDeltaY1 = 0;
3035            double iDeltaX2 = 0;
3036            double iDeltaY2 = 0;
3037
3038            for (j = 0; j < 4; j++) {
3039                savepoints[j] = new POINT2(points[j]);
3040            }
3041            ReorderSptByFirePoints(savepoints);
3042
3043            lineutility.InitializePOINT2Array(pts);
3044            // draw line connecting points 1 & 2
3045            points[counter] = new POINT2(savepoints[0]);
3046            points[counter].style = 0;
3047            counter++;
3048            points[counter] = new POINT2(savepoints[1]);
3049            points[counter].style = 5;
3050            counter++;
3051
3052            // draw line connecting savepoints 1 & 3
3053            pts[0] = new POINT2(savepoints[0]);
3054            pts[1] = new POINT2(savepoints[2]);
3055            points[counter] = new POINT2(pts[0]);
3056            points[counter].style = 0;
3057            counter++;
3058            points[counter] = new POINT2(pts[1]);
3059            points[counter].style = 5;
3060            counter++;
3061
3062            // draw arrow at end of line
3063            iDiagEOL_length =  (Math.sqrt(
3064                    (savepoints[0].x - savepoints[1].x) * (savepoints[0].x - savepoints[1].x) +
3065                    (savepoints[0].y - savepoints[1].y) * (savepoints[0].y - savepoints[1].y)) / 10);
3066
3067            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
3068            if (iDiagEOL_length >  maxLength * DPIScaleFactor) {
3069                iDiagEOL_length =  maxLength * DPIScaleFactor;
3070            }
3071            if (iDiagEOL_length <  minLength * DPIScaleFactor) {
3072                iDiagEOL_length =  minLength * DPIScaleFactor;
3073            }
3074
3075            dAngle1 = Math.atan2(savepoints[0].y - savepoints[2].y, savepoints[0].x - savepoints[2].x);
3076            iDeltaX1 =  (Math.cos(dAngle1 + CONST_PI / 6) * iDiagEOL_length);
3077            iDeltaY1 =  (Math.sin(dAngle1 + CONST_PI / 6) * iDiagEOL_length);
3078            iDeltaX2 =  (Math.cos(dAngle1 - CONST_PI / 6) * iDiagEOL_length);
3079            iDeltaY2 =  (Math.sin(dAngle1 - CONST_PI / 6) * iDiagEOL_length);
3080            pts[0].x = savepoints[2].x + iDeltaX1;
3081            pts[0].y = savepoints[2].y + iDeltaY1;
3082            pts[1] = new POINT2(savepoints[2]);
3083            pts[2].x = savepoints[2].x + iDeltaX2;
3084            pts[2].y = savepoints[2].y + iDeltaY2;
3085            //DrawLine(destination, mask, color, pts, 3, 2);
3086            for (j = 0; j < 3; j++) {
3087                points[counter] = new POINT2(pts[j]);
3088                points[counter].style = 0;
3089                counter++;
3090            }
3091            points[counter - 1].style = 5;
3092
3093            // draw line connecting savepoints 2 & 4
3094            pts[0] = new POINT2(savepoints[1]);
3095            pts[1] = new POINT2(savepoints[3]);
3096            points[counter] = new POINT2(pts[0]);
3097            points[counter].style = 0;
3098            counter++;
3099            points[counter] = new POINT2(pts[1]);
3100            points[counter].style = 5;
3101            counter++;
3102
3103            // draw arrow at end of line
3104            dAngle1 = Math.atan2(savepoints[1].y - savepoints[3].y, savepoints[1].x - savepoints[3].x);
3105            iDeltaX1 =  (Math.cos(dAngle1 + CONST_PI / 6) * iDiagEOL_length);
3106            iDeltaY1 =  (Math.sin(dAngle1 + CONST_PI / 6) * iDiagEOL_length);
3107            iDeltaX2 =  (Math.cos(dAngle1 - CONST_PI / 6) * iDiagEOL_length);
3108            iDeltaY2 =  (Math.sin(dAngle1 - CONST_PI / 6) * iDiagEOL_length);
3109            pts[0].x = savepoints[3].x + iDeltaX1;
3110            pts[0].y = savepoints[3].y + iDeltaY1;
3111            pts[1] = new POINT2(savepoints[3]);
3112            pts[2].x = savepoints[3].x + iDeltaX2;
3113            pts[2].y = savepoints[3].y + iDeltaY2;
3114            //DrawLine(destination, mask, color, pts, 3, 2);
3115            for (j = 0; j < 3; j++) {
3116                points[counter] = new POINT2(pts[j]);
3117                points[counter].style = 0;
3118                counter++;
3119            }
3120            points[counter - 1].style = 5;
3121
3122            // draw lines on the back of the graphic
3123            dAngle1 = Math.atan2(savepoints[1].y - savepoints[0].y, savepoints[1].x - savepoints[0].x);
3124            iDiagEOL_length *= 2;
3125            iDeltaX1 =  (Math.cos(dAngle1 - CONST_PI / 4) * iDiagEOL_length);
3126            iDeltaY1 =  (Math.sin(dAngle1 - CONST_PI / 4) * iDiagEOL_length);
3127            iDeltaX2 =  (Math.cos(dAngle1 + CONST_PI / 4) * iDiagEOL_length);
3128            iDeltaY2 =  (Math.sin(dAngle1 + CONST_PI / 4) * iDiagEOL_length);
3129            pts[0].x = savepoints[0].x - iDeltaX1;
3130            pts[0].y = savepoints[0].y - iDeltaY1;
3131            pts[1] = new POINT2(savepoints[0]);
3132            points[counter] = new POINT2(pts[0]);
3133            points[counter].style = 0;
3134            counter++;
3135            points[counter] = new POINT2(pts[1]);
3136            points[counter].style = 5;
3137            counter++;
3138
3139            pts[0].x = savepoints[1].x + iDeltaX2;
3140            pts[0].y = savepoints[1].y + iDeltaY2;
3141            pts[1] = new POINT2(savepoints[1]);
3142            points[counter] = new POINT2(pts[0]);
3143            points[counter].style = 0;
3144            counter++;
3145            points[counter] = new POINT2(pts[1]);
3146            points[counter].style = 5;
3147            counter++;
3148        }
3149        catch (Exception exc) {
3150            ErrorLogger.LogException(_className ,"GetDISMSupportbyFireDouble",
3151                    new RendererException("Failed inside GetDISMSupportByFireDouble", exc));
3152        }
3153        return counter;
3154    }
3155
3156    private static void ReorderAtkByFirePoints(POINT2[] points) {
3157        try {
3158            //assume the points were ordered correctly. then pt0 is above the line from pt1 to pt2
3159            POINT2[] savepoints = new POINT2[3];
3160            POINT2 ptAboveLine = new POINT2(), ptBelowLine = new POINT2(), ptLeftOfLine = new POINT2(), ptRightOfLine = new POINT2();
3161            double distToLine = 0, distanceToPointAboveLine = 0, distanceToPointBelowLine = 0;
3162            double distanceToPointLeftOfLine = 0, distanceToPointRightOfLine = 0;
3163            for (int j = 0; j < 3; j++) {
3164                savepoints[j] = new POINT2(points[j]);
3165            }
3166
3167            if (Math.abs(savepoints[1].x - savepoints[2].x) > 2) {
3168                distToLine = lineutility.CalcDistanceToLineDouble(savepoints[1], savepoints[2], savepoints[0]);
3169                ptAboveLine = lineutility.ExtendDirectedLine(savepoints[1], savepoints[2], savepoints[2], 2, distToLine);
3170                ptBelowLine = lineutility.ExtendDirectedLine(savepoints[1], savepoints[2], savepoints[2], 3, distToLine);
3171                distanceToPointAboveLine = lineutility.CalcDistanceDouble(savepoints[0], ptAboveLine);
3172                distanceToPointBelowLine = lineutility.CalcDistanceDouble(savepoints[0], ptBelowLine);
3173                if (distanceToPointAboveLine < distanceToPointBelowLine) {
3174                    //then pt2 - pt3 should be left to right
3175                    if (savepoints[2].x < savepoints[1].x) {
3176                        lineutility.Reverse2Points(savepoints[1], savepoints[2]);
3177                    }
3178
3179
3180                } else {
3181                    if (savepoints[2].x > savepoints[1].x) {
3182                        lineutility.Reverse2Points(savepoints[1], savepoints[2]);
3183                    }
3184
3185                }
3186            } else //the last 2 points form a vertical line
3187            {
3188                distToLine = lineutility.CalcDistanceToLineDouble(savepoints[1], savepoints[2], savepoints[0]);
3189                ptLeftOfLine = lineutility.ExtendDirectedLine(savepoints[1], savepoints[2], savepoints[2], 0, distToLine);
3190                ptRightOfLine = lineutility.ExtendDirectedLine(savepoints[1], savepoints[2], savepoints[2], 1, distToLine);
3191                distanceToPointLeftOfLine = lineutility.CalcDistanceDouble(savepoints[0], ptLeftOfLine);
3192                distanceToPointRightOfLine = lineutility.CalcDistanceDouble(savepoints[0], ptRightOfLine);
3193                if (distanceToPointRightOfLine < distanceToPointLeftOfLine) {
3194                    if (savepoints[2].y < savepoints[1].y) {
3195                        lineutility.Reverse2Points(savepoints[1], savepoints[2]);
3196                    }
3197                } else {
3198                    if (savepoints[2].y > savepoints[1].y) {
3199                        lineutility.Reverse2Points(savepoints[1], savepoints[2]);
3200                    }
3201                }
3202            }
3203            points[1].x = savepoints[1].x;
3204            points[1].y = savepoints[1].y;
3205            points[2].x = savepoints[2].x;
3206            points[2].y = savepoints[2].y;
3207        } catch (Exception exc) {
3208            ErrorLogger.LogException(_className, "ReorderAtkByFirePoints",
3209                    new RendererException("Failed inside GetDISMSupportByFireDouble", exc));
3210        }
3211    }
3212    private static void ReorderSptByFirePoints(POINT2[] points) {
3213        try {
3214            //assume the points were ordered correctly. then pt0 is above the line from pt1 to pt2
3215            POINT2 ptAboveLine = new POINT2(), ptBelowLine = new POINT2(), ptLeftOfLine = new POINT2(), ptRightOfLine = new POINT2();
3216            double distToLine = 0, distanceToPointAboveLine = 0, distanceToPointBelowLine = 0;
3217            double distanceToPointLeftOfLine = 0, distanceToPointRightOfLine = 0;
3218
3219            POINT2 midpt = lineutility.MidPointDouble(points[0], points[1], 0);
3220            if (Math.abs(points[2].x - points[3].x) > 2) {
3221                distToLine = lineutility.CalcDistanceToLineDouble(points[1], points[2], midpt);
3222                ptAboveLine = lineutility.ExtendDirectedLine(points[1], points[2], points[2], 2, distToLine);
3223                ptBelowLine = lineutility.ExtendDirectedLine(points[1], points[2], points[2], 3, distToLine);
3224                distanceToPointAboveLine = lineutility.CalcDistanceDouble(points[0], ptAboveLine);
3225                distanceToPointBelowLine = lineutility.CalcDistanceDouble(points[0], ptBelowLine);
3226                if (distanceToPointAboveLine < distanceToPointBelowLine) {
3227                    //then pt2 - pt3 should be left to right
3228                    if (points[2].x < points[1].x) {
3229                        lineutility.Reverse2Points(points[0], points[1]);
3230                        lineutility.Reverse2Points(points[2], points[3]);
3231                    }
3232                } else {
3233                    if (points[2].x > points[1].x) {
3234                        lineutility.Reverse2Points(points[0], points[1]);
3235                        lineutility.Reverse2Points(points[2], points[3]);
3236                    }
3237                }
3238            } else //the last 2 points form a vertical line
3239            {
3240                distToLine = lineutility.CalcDistanceToLineDouble(points[1], points[2], midpt);
3241                ptLeftOfLine = lineutility.ExtendDirectedLine(points[1], points[2], points[2], 0, distToLine);
3242                ptRightOfLine = lineutility.ExtendDirectedLine(points[1], points[2], points[2], 1, distToLine);
3243                distanceToPointLeftOfLine = lineutility.CalcDistanceDouble(points[0], ptLeftOfLine);
3244                distanceToPointRightOfLine = lineutility.CalcDistanceDouble(points[0], ptRightOfLine);
3245                if (distanceToPointLeftOfLine < distanceToPointRightOfLine) {
3246                    //then pt2 - pt3 should be left to right
3247                    if (points[2].y > points[1].y) {
3248                        lineutility.Reverse2Points(points[0], points[1]);
3249                        lineutility.Reverse2Points(points[2], points[3]);
3250                    }
3251                } else {
3252                    if (points[2].y < points[1].y) {
3253                        lineutility.Reverse2Points(points[0], points[1]);
3254                        lineutility.Reverse2Points(points[2], points[3]);
3255                    }
3256                }
3257
3258            }
3259        } catch (Exception exc) {
3260            ErrorLogger.LogException(_className, "ReorderSptByFire",
3261                    new RendererException("Failed inside ReorderSptByFirePoints", exc));
3262        }
3263    }
3264    /**
3265     * Calculates the points for ATKBYFIRE
3266     *
3267     * @param points OUT - the client points, also used for the returned points.
3268     * @param linetype the line type.
3269     */
3270    protected static int GetDISMATKBYFIREDouble(POINT2[] points, int linetype) {
3271        int counter = 0;
3272        try {
3273            POINT2[] pts = new POINT2[3];
3274            POINT2 ptMid = new POINT2();
3275            POINT2[] savepoints = new POINT2[3];
3276            int j = 0;
3277            double iDiagEOL_length = 0;
3278            double dAngle1 = 0;
3279            double iDeltaX1 = 0;
3280            double iDeltaY1 = 0;
3281            double iDeltaX2 = 0;
3282            double iDeltaY2 = 0;
3283
3284            for (j = 0; j < 3; j++) {
3285                savepoints[j] = new POINT2(points[j]);
3286            }
3287
3288            ReorderAtkByFirePoints(savepoints);
3289
3290            lineutility.InitializePOINT2Array(pts);
3291            // draw line across back
3292            pts[0] = new POINT2(savepoints[1]);
3293            pts[1] = new POINT2(savepoints[2]);
3294            //DrawLine(destination, mask, color, pts, 2, 2);
3295            points[counter] = new POINT2(pts[0]);
3296            points[counter].style = 0;
3297            counter++;
3298            points[counter] = new POINT2(pts[1]);
3299            points[counter].style = 5;
3300            counter++;
3301
3302            // draw perpendicular line
3303            ptMid.x = (savepoints[1].x + savepoints[2].x) / 2;
3304            ptMid.y = (savepoints[1].y + savepoints[2].y) / 2;
3305            pts[0] = new POINT2(ptMid);
3306            pts[1] = new POINT2(savepoints[0]);
3307            //DrawLine(destination, mask, color, pts, 2, 2);
3308            points[counter] = new POINT2(pts[0]);
3309            points[counter].style = 0;
3310            counter++;
3311            points[counter] = new POINT2(pts[1]);
3312            points[counter].style = 5;
3313            counter++;
3314
3315            // draw arrowhead
3316            iDiagEOL_length =  ((Math.sqrt // height of graphic
3317                    (
3318                    (savepoints[1].x - savepoints[2].x) * (savepoints[1].x - savepoints[2].x) +
3319                    (savepoints[1].y - savepoints[2].y) * (savepoints[1].y - savepoints[2].y)) +
3320                    Math.sqrt // length of graphic
3321                    (
3322                    (savepoints[0].x - ptMid.x) * (savepoints[0].x - ptMid.x) +
3323                    (savepoints[0].y - ptMid.y) * (savepoints[0].y - ptMid.y))) / 20);
3324            //if(iDiagEOL_length<10)
3325            //  iDiagEOL_length=10;
3326            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
3327            if ((double) iDiagEOL_length > maxLength/5 * DPIScaleFactor) {
3328                iDiagEOL_length =  maxLength/5 * DPIScaleFactor;
3329            }
3330            if ((double) iDiagEOL_length < minLength * DPIScaleFactor) {
3331                iDiagEOL_length =  minLength * DPIScaleFactor;
3332            }
3333
3334            dAngle1 = Math.atan2(ptMid.y - savepoints[0].y, ptMid.x - savepoints[0].x);
3335            iDeltaX1 =  (Math.cos(dAngle1 + CONST_PI / 6) * iDiagEOL_length);
3336            iDeltaY1 =  (Math.sin(dAngle1 + CONST_PI / 6) * iDiagEOL_length);
3337            iDeltaX2 =  (Math.cos(dAngle1 - CONST_PI / 6) * iDiagEOL_length);
3338            iDeltaY2 =  (Math.sin(dAngle1 - CONST_PI / 6) * iDiagEOL_length);
3339            pts[0].x = savepoints[0].x + iDeltaX1;
3340            pts[0].y = savepoints[0].y + iDeltaY1;
3341            pts[1] = new POINT2(savepoints[0]);
3342            pts[2].x = savepoints[0].x + iDeltaX2;
3343            pts[2].y = savepoints[0].y + iDeltaY2;
3344            //DrawLine(destination, mask, color, pts, 3, 2);
3345            for (j = 0; j < 3; j++) {
3346                points[counter] = new POINT2(pts[j]);
3347                points[counter].style = 0;
3348                counter++;
3349            }
3350            points[counter - 1].style = 5;
3351
3352            // draw lines on the back of the graphic
3353            dAngle1 = Math.atan2(savepoints[1].y - savepoints[2].y, savepoints[1].x - savepoints[2].x);
3354            iDeltaX1 =  (Math.cos(dAngle1 - CONST_PI / 4) * iDiagEOL_length * 2);
3355            iDeltaY1 =  (Math.sin(dAngle1 - CONST_PI / 4) * iDiagEOL_length * 2);
3356            iDeltaX2 =  (Math.cos(dAngle1 + CONST_PI / 4) * iDiagEOL_length * 2);
3357            iDeltaY2 =  (Math.sin(dAngle1 + CONST_PI / 4) * iDiagEOL_length * 2);
3358
3359            pts[0].x = savepoints[1].x + iDeltaX1;
3360            pts[0].y = savepoints[1].y + iDeltaY1;
3361            pts[1] = new POINT2(savepoints[1]);
3362            //DrawLine(destination, mask, color, pts, 2, 2);
3363            points[counter] = new POINT2(pts[0]);
3364            points[counter].style = 0;
3365            counter++;
3366            points[counter] = new POINT2(pts[1]);
3367            points[counter].style = 5;
3368            counter++;
3369
3370            pts[0].x = savepoints[2].x - iDeltaX2;
3371            pts[0].y = savepoints[2].y - iDeltaY2;
3372            pts[1] = new POINT2(savepoints[2]);
3373            //DrawLine(destination, mask, color, pts, 2, 2);
3374            points[counter] = new POINT2(pts[0]);
3375            points[counter].style = 0;
3376            counter++;
3377            points[counter] = new POINT2(pts[1]);
3378            points[counter].style = 5;
3379            counter++;
3380        } catch (Exception exc) {
3381            ErrorLogger.LogException(_className ,"GetDISMAtkByFireDouble",
3382                    new RendererException("Failed inside GetDISMAtkByFireDouble", exc));
3383        }
3384        return counter;
3385    }
3386    /**
3387     * Calculates the points for GAP
3388     *
3389     * @param points OUT - the client points, also used for the returned points.
3390     * @param linetype the line type.
3391     */
3392    protected static int GetDISMGapDouble(POINT2[] points, int linetype) {
3393        try {
3394            POINT2[] savepoints = new POINT2[4];
3395            POINT2[] pts = new POINT2[2];
3396            int j = 0;
3397            double dMBR = lineutility.MBRDistance(points, 4);
3398            //end declarations
3399
3400            for (j = 0; j < 4; j++) {
3401                savepoints[j] = new POINT2(points[j]);
3402            }
3403
3404            lineutility.InitializePOINT2Array(pts);
3405            //M. Deutch 8-19-04
3406            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
3407            if (dMBR / 10 > maxLength * DPIScaleFactor) {
3408                dMBR = 10 * maxLength * DPIScaleFactor;
3409            }
3410            if (dMBR / 10 < minLength * DPIScaleFactor) {
3411                dMBR = 10 * minLength * DPIScaleFactor;
3412            }
3413
3414            points[0] = new POINT2(savepoints[0]);
3415            points[0].style = 0;
3416            points[1] = new POINT2(savepoints[1]);
3417            points[1].style = 5;
3418            points[2] = new POINT2(savepoints[2]);
3419            points[2].style = 0;
3420            points[3] = new POINT2(savepoints[3]);
3421            points[3].style = 5;
3422
3423            double dist = dMBR / 10;
3424            if(dist > 20 * DPIScaleFactor)
3425                dist = 20 * DPIScaleFactor;
3426            double dist2 = dist;
3427
3428            //get the extension point
3429            pts[0] = lineutility.ExtendLineDouble(savepoints[1], savepoints[0], dist);
3430            pts[1] = lineutility.ExtendLineDouble(savepoints[2], savepoints[0], dist2);
3431            points[4] = new POINT2(points[0]);
3432            points[4].style = 0;
3433            points[5] = lineutility.MidPointDouble(pts[0], pts[1], 5);
3434            //get the extension point
3435            pts[0] = lineutility.ExtendLineDouble(savepoints[0], savepoints[1], dist);
3436            pts[1] = lineutility.ExtendLineDouble(savepoints[3], savepoints[1], dist2);
3437            points[6] = new POINT2(points[1]);
3438            points[6].style = 0;
3439            points[7] = lineutility.MidPointDouble(pts[0], pts[1], 5);
3440            //get the extension point
3441            pts[0] = lineutility.ExtendLineDouble(savepoints[0], savepoints[2], dist2);
3442            pts[1] = lineutility.ExtendLineDouble(savepoints[3], savepoints[2], dist);
3443            points[8] = new POINT2(points[2]);
3444            points[8].style = 0;
3445            points[9] = lineutility.MidPointDouble(pts[0], pts[1], 5);
3446            //get the extension point
3447            pts[0] = lineutility.ExtendLineDouble(savepoints[1], savepoints[3], dist2);
3448            pts[1] = lineutility.ExtendLineDouble(savepoints[2], savepoints[3], dist);
3449            points[10] = new POINT2(points[3]);
3450            points[10].style = 0;
3451            points[11] = lineutility.MidPointDouble(pts[0], pts[1], 5);
3452
3453        } catch (Exception exc) {
3454            ErrorLogger.LogException(_className ,"GetDISMGapDouble",
3455                    new RendererException("Failed inside GetDISMGapDouble", exc));
3456        }
3457        return 12;
3458    }
3459    /**
3460     * Calculates the points for MNFLDDIS
3461     *
3462     * @param points - OUT - the client points, also used for the returned points.
3463     * @param linetype the line type.
3464     */
3465    protected static int GetDISMMinefieldDisruptDouble(POINT2[] points, int linetype) {
3466        int counter=0;
3467        try {
3468            POINT2[] pts = new POINT2[2];
3469            POINT2[] ptsArrow = new POINT2[3];
3470            POINT2 ptCenter = new POINT2();
3471            int j = 0;
3472            POINT2[] savepoints = new POINT2[3];
3473            double dAngle1 = 0, d = 0, dist = 0;
3474            POINT2[] deltapoints1 = new POINT2[4];
3475            POINT2[] deltapoints2 = new POINT2[4];
3476            POINT2[] deltapoints3 = new POINT2[4];
3477            double iDiagEOL_length = 0;
3478            double iDeltaX1 = 0;
3479            double iDeltaY1 = 0;
3480            double iDeltaX2 = 0;
3481            double iDeltaY2 = 0;
3482            POINT2 ptTail = new POINT2();
3483            //end declarations
3484
3485            for (j = 0; j < 3; j++) {
3486                savepoints[j] = new POINT2(points[j]);
3487            }
3488
3489            lineutility.InitializePOINT2Array(ptsArrow);
3490            lineutility.InitializePOINT2Array(deltapoints1);
3491            lineutility.InitializePOINT2Array(deltapoints2);
3492            lineutility.InitializePOINT2Array(deltapoints3);
3493            lineutility.InitializePOINT2Array(pts);
3494            
3495            points[counter] = new POINT2(savepoints[0]);
3496            points[counter].style = 0;
3497            counter++;
3498            points[counter] = new POINT2(savepoints[1]);
3499            points[counter].style = 5;
3500            counter++;
3501
3502            ptCenter.x = (savepoints[0].x + savepoints[1].x) / 2;
3503            ptCenter.y = (savepoints[0].y + savepoints[1].y) / 2;
3504
3505            ptsArrow[0] = new POINT2(savepoints[2]);
3506            ptsArrow[1].x = ptCenter.x + (savepoints[2].x - savepoints[0].x) * 4 / 5;
3507            ptsArrow[1].y = ptCenter.y + (savepoints[2].y - savepoints[0].y) * 4 / 5;
3508            ptsArrow[2].x = savepoints[1].x + (savepoints[2].x - savepoints[0].x) * 3 / 5;
3509            ptsArrow[2].y = savepoints[1].y + (savepoints[2].y - savepoints[0].y) * 3 / 5;
3510
3511            points[counter] = new POINT2(savepoints[1]);
3512            points[counter].style = 0;
3513            counter++;
3514            points[counter] = new POINT2(ptsArrow[2]);
3515            points[counter].style = 5;
3516            counter++;
3517
3518            pts[1] = new POINT2(ptsArrow[1]);
3519
3520            //draw middle line
3521            points[counter] = new POINT2(ptCenter);
3522            points[counter].style = 0;
3523            counter++;
3524            points[counter] = new POINT2(pts[1]);
3525            points[counter].style = 5;
3526            counter++;
3527
3528            //draw tail
3529            dist = lineutility.CalcDistanceDouble(savepoints[2], savepoints[0]);
3530            d = dist;
3531            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
3532            if (d > 5 * maxLength * DPIScaleFactor) {
3533                d = 5 * maxLength * DPIScaleFactor;
3534            }
3535            if (d < 5 * minLength * DPIScaleFactor) {
3536                d = 5 * minLength * DPIScaleFactor;
3537            }
3538            ptTail = new POINT2(ptCenter);
3539            pts[0].x = ptTail.x - (savepoints[2].x - savepoints[0].x) / 5;
3540            pts[0].y = ptTail.y - (savepoints[2].y - savepoints[0].y) / 5;
3541            pts[0] = lineutility.ExtendLineDouble(pts[0], ptTail, -d / 5);
3542            points[counter] = new POINT2(ptTail);
3543            points[counter].style = 0;
3544            counter++;
3545            points[counter] = new POINT2(pts[0]);
3546            points[counter].style = 5;
3547            counter++;
3548
3549            pts[0] = new POINT2(savepoints[0]);
3550            pts[1] = new POINT2(ptsArrow[0]);
3551
3552            points[counter] = new POINT2(pts[0]);
3553            points[counter].style = 0;
3554            counter++;
3555            points[counter] = new POINT2(pts[1]);
3556            points[counter].style = 5;
3557            counter++;
3558
3559            // the following code is very similar to CalcEndpieceDeltas
3560            iDiagEOL_length =  ((Math.sqrt // height of graphic
3561                    (
3562                    (savepoints[1].x - savepoints[0].x) * (savepoints[1].x - savepoints[0].x) +
3563                    (savepoints[1].y - savepoints[0].y) * (savepoints[1].y - savepoints[0].y)) +
3564                    Math.sqrt // length of graphic
3565                    (
3566                    (savepoints[2].x - savepoints[1].x) * (savepoints[2].x - savepoints[1].x) +
3567                    (savepoints[2].y - savepoints[1].y) * (savepoints[2].y - savepoints[1].y))) / 15);
3568            // dAngle1 = angle used to calculate the end-piece deltas
3569
3570            if (iDiagEOL_length >  maxLength * DPIScaleFactor) {
3571                iDiagEOL_length =  maxLength * DPIScaleFactor;
3572            }
3573            if (iDiagEOL_length <  minLength * DPIScaleFactor) {
3574                iDiagEOL_length =  minLength * DPIScaleFactor;
3575            }
3576
3577            dAngle1 = Math.atan2(savepoints[0].y - savepoints[2].y, savepoints[0].x - savepoints[2].x);
3578            iDeltaX1 =  (iDiagEOL_length * Math.cos(dAngle1 - CONST_PI / 6));
3579            iDeltaY1 =  (iDiagEOL_length * Math.sin(dAngle1 - CONST_PI / 6));
3580            iDeltaX2 =  (iDiagEOL_length * Math.cos(dAngle1 + CONST_PI / 6));
3581            iDeltaY2 =  (iDiagEOL_length * Math.sin(dAngle1 + CONST_PI / 6));
3582
3583            DrawEndpieceDeltasDouble(ptsArrow[0],
3584                    iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints1);
3585            DrawEndpieceDeltasDouble(ptsArrow[1],
3586                    iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints2);
3587            DrawEndpieceDeltasDouble(ptsArrow[2],
3588                    iDeltaX1, iDeltaY1, iDeltaX2, iDeltaY2, deltapoints3);
3589            points[counter] = new POINT2(deltapoints1[1]);
3590            points[counter].style = 9;
3591            counter++;
3592            points[counter] = new POINT2(deltapoints1[0]);
3593            points[counter].style = 9;
3594            counter++;
3595            points[counter] = new POINT2(deltapoints1[3]);
3596            points[counter].style = 9;
3597            counter++;
3598            points[counter] = new POINT2(deltapoints1[3]);
3599            points[counter].style = 10;
3600            counter++;
3601
3602            points[counter] = new POINT2(deltapoints2[1]);
3603            points[counter].style = 9;
3604            counter++;
3605            points[counter] = new POINT2(deltapoints2[0]);
3606            points[counter].style = 9;
3607            counter++;
3608            points[counter] = new POINT2(deltapoints2[3]);
3609            points[counter].style = 9;
3610            counter++;
3611            points[counter] = new POINT2(deltapoints2[3]);
3612            points[counter].style = 10;
3613            counter++;
3614
3615            points[counter] = new POINT2(deltapoints3[1]);
3616            points[counter].style = 9;
3617            counter++;
3618            points[counter] = new POINT2(deltapoints3[0]);
3619            points[counter].style = 9;
3620            counter++;
3621            points[counter] = new POINT2(deltapoints3[3]);
3622            points[counter].style = 9;
3623            counter++;
3624            points[counter] = new POINT2(deltapoints3[3]);
3625            points[counter].style = 10;
3626            counter++;
3627
3628        } catch (Exception exc) {
3629            ErrorLogger.LogException(_className ,"GetDISMMinefieldDisruptDouble",
3630                    new RendererException("Failed inside GetDISMMinefieldDisruptDouble", exc));
3631        }
3632        return counter;
3633    }
3634    /**
3635     * Calculates the points for LINTGT
3636     *
3637     * @param points - OUT - the client points, also used for the returned points.
3638     * @param linetype the line type.
3639     * @param vblCounter the number of points required to display the symbol
3640     */
3641    protected static int GetDISMLinearTargetDouble(POINT2[] points, int linetype, int vblCounter) {
3642        int counter = 0;
3643        try {
3644            int j = 0;
3645            double dMBR = lineutility.MBRDistance(points, vblCounter-4);
3646            //end declarations
3647
3648            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
3649            if (dMBR / 20 > maxLength * DPIScaleFactor) {
3650                dMBR = 20 * maxLength * DPIScaleFactor;
3651            }
3652            if (dMBR / 20 < minLength * DPIScaleFactor) {
3653                dMBR = 20 * minLength * DPIScaleFactor;
3654            }
3655            if (dMBR < 150 * DPIScaleFactor) {
3656                dMBR = 150 * DPIScaleFactor;
3657            }
3658            if(dMBR>250 * DPIScaleFactor)
3659                dMBR=250 * DPIScaleFactor;
3660            
3661            for (j = 0; j < vblCounter - 4; j++) {
3662                points[counter].style = 0;
3663                counter++;
3664            }
3665            //for(j=vblCounter-4;j<vblCounter;j++)
3666              //  points[j]=new POINT2();
3667
3668            points[counter - 1].style = 5;
3669
3670            points[counter] = lineutility.ExtendTrueLinePerpDouble(points[0], points[1], points[0], dMBR / 20, 0);
3671            counter++;
3672            points[counter] = lineutility.ExtendTrueLinePerpDouble(points[0], points[1], points[0], -dMBR / 20, 5);
3673            counter++;
3674            points[counter] = lineutility.ExtendTrueLinePerpDouble(points[vblCounter - 5], points[vblCounter - 6], points[vblCounter - 5], dMBR / 20, 0);
3675            counter++;
3676            points[counter] = lineutility.ExtendTrueLinePerpDouble(points[vblCounter - 5], points[vblCounter - 6], points[vblCounter - 5], -dMBR / 20, 5);
3677            counter++;
3678            if (linetype == (long) TacticalLines.FPF) {
3679                points[0].style = 6;
3680            }
3681        } catch (Exception exc) {
3682            ErrorLogger.LogException(_className ,"GetDISMLinearTargetDouble",
3683                    new RendererException("Failed inside GetDISMLinearTargetDouble", exc));
3684        }
3685        return counter;
3686    }
3687    /**
3688     * Calculates the points for BLOCK, MNFLDBLK
3689     *
3690     * @param points - OUT - the client points, also used for the returned points.
3691     * @param linetype the line type.
3692     */
3693    protected static void GetDISMBlockDouble2(POINT2[] points,
3694            int linetype) {
3695        try {
3696            POINT2 ptRelative = new POINT2(points[2]);
3697            
3698            POINT2 midpt = lineutility.MidPointDouble(points[0], points[1], 0);
3699            int j = 0;
3700            points[0].style = 0;
3701            points[1].style = 5;
3702            points[2] = new POINT2(midpt);
3703            points[3] = new POINT2(ptRelative);
3704            if (linetype == (long) TacticalLines.BLOCK) {
3705                points[2].style = 14;
3706            }
3707            if (linetype == (long) TacticalLines.FPF) {
3708                points[2].style = 6;
3709            }
3710        } catch (Exception exc) {
3711            ErrorLogger.LogException(_className ,"GetDISMBlockDouble2",
3712                    new RendererException("Failed inside GetDISMBlockDouble2", exc));
3713        }
3714    }
3715    /**
3716     * Calculates the points for PAA_RECTANGULAR.
3717     *
3718     * @param points - OUT - the client points, also used for the returned points.
3719     * @param linetype the line type.
3720     */
3721    protected static void GetDISMPAADouble(POINT2[] points, int linetype) {
3722        try {
3723            POINT2 pt0 = new POINT2(points[0]);
3724            POINT2 pt1 = new POINT2(points[1]);
3725            POINT2 pt2 = new POINT2();
3726            POINT2 pt3 = new POINT2();
3727            POINT2 midpt = new POINT2();
3728            double d = lineutility.CalcDistanceDouble(pt0, pt1);
3729
3730            midpt = lineutility.MidPointDouble(pt0, pt1, 0);
3731            pt2 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, midpt, d / 2, 0);
3732            pt3 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, midpt, -d / 2, 0);
3733            d = lineutility.CalcDistanceDouble(pt0, pt2);
3734            points[0] = new POINT2(pt0);
3735            points[0].style = 14;
3736            points[1] = new POINT2(pt2);
3737            points[1].style = 14;
3738            points[2] = new POINT2(pt1);
3739            points[2].style = 14;
3740            points[3] = new POINT2(pt3);
3741            points[3].style = 14;
3742            points[4] = new POINT2(pt0);
3743            points[4].style = 5;
3744        } catch (Exception exc) {
3745            ErrorLogger.LogException(_className ,"GetDISMPAADouble",
3746                    new RendererException("Failed inside GetDISMPAADouble", exc));
3747        }
3748    }
3749
3750    private static boolean ReverseDelayArc(POINT2[] points) {
3751        POINT2 pt1 = points[0];
3752        POINT2 pt2 = points[1];
3753        POINT2 pt3 = points[2];
3754
3755        float lineAngle = getAngleBetweenPoints(pt1.x, pt1.y, pt2.x, pt2.y);
3756        float curveAngle = getAngleBetweenPoints(pt2.x, pt2.y, pt3.x, pt3.y);
3757
3758        float upperBound = curveAngle + 180;
3759        return !isInRange(curveAngle, upperBound, lineAngle);
3760    }
3761
3762    private static boolean isInRange(float min, float max, float targetAngle) {
3763        targetAngle = normalizeAngle(targetAngle);
3764        min = normalizeAngle(min);
3765        max = normalizeAngle(max);
3766
3767        if (min < max) {
3768            return min <= targetAngle && targetAngle <= max;
3769        }
3770        return min <= targetAngle || targetAngle <= max;
3771
3772    }
3773
3774    private static float getAngleBetweenPoints(double x1, double y1, double x2, double y2) {
3775        return (float) Math.toDegrees(Math.atan2(y2 - y1, x2 - x1));
3776    }
3777
3778    /**
3779     * Returns an angle from 0 to 360
3780     *
3781     * @param angle the angle to normalize
3782     * @return an angle in range from 0 to 360
3783     */
3784    public static float normalizeAngle(float angle) {
3785        return (3600000 + angle) % 360;
3786    }
3787
3788    private static void DrawEndpieceDeltasDouble(POINT2 point,
3789            double iDelta1,
3790            double iDelta2,
3791            double iDelta3,
3792            double iDelta4,
3793            POINT2[] deltapoints)
3794                {
3795        try
3796        {
3797            deltapoints[0] = new POINT2(point);
3798            deltapoints[0].style = 0;
3799            deltapoints[1].x = point.x + iDelta1;
3800            deltapoints[1].y = point.y + iDelta2;
3801            deltapoints[1].style = 5;
3802            deltapoints[2] = new POINT2(point);
3803            deltapoints[2].style = 0;
3804            deltapoints[3].x = point.x + iDelta3;
3805            deltapoints[3].y = point.y + iDelta4;
3806            deltapoints[3].style = 5;
3807        } catch (Exception exc) {
3808            ErrorLogger.LogException(_className ,"DrawEndpieceDeltasDouble",
3809                    new RendererException("Failed inside DrawEndpieceDeltasDouble", exc));
3810        }
3811    }
3812    /**
3813     * Calculates the points for EASY
3814     *
3815     * @param points - OUT - the client points, also used for the returned points.
3816     * @param linetype the line type.
3817     */
3818    protected static int GetDISMEasyDouble(POINT2[] points,
3819            int linetype) {
3820        int counter = 0;
3821        try {
3822            int j = 0;
3823            POINT2[] pointsCorner = new POINT2[2];
3824            POINT2[] rectpts = new POINT2[4];
3825            POINT2[] savepoints = new POINT2[3];
3826            POINT2[] deltapoints1 = new POINT2[4];
3827            POINT2[] deltapoints2 = new POINT2[4];
3828            ref<double[]> iDeltaX = new ref(), iDeltaY = new ref();
3829            int bPointsRight = 0;
3830            //end declarations
3831
3832            for (j = 0; j < 3; j++) {
3833                savepoints[j] = points[j];
3834            }
3835            lineutility.InitializePOINT2Array(pointsCorner);
3836            lineutility.InitializePOINT2Array(rectpts);
3837            lineutility.InitializePOINT2Array(deltapoints1);
3838            lineutility.InitializePOINT2Array(deltapoints2);
3839
3840            DrawOpenRectangleDouble(savepoints, pointsCorner, rectpts);
3841            for (j = 0; j < 4; j++) {
3842                points[counter] = new POINT2(rectpts[j]);
3843                points[counter].style = 0;
3844                counter++;
3845            }
3846            points[counter - 1].style = 5;
3847
3848            bPointsRight = DetermineDirectionDouble(savepoints);
3849
3850            CalcEndpieceDeltasDouble(savepoints, iDeltaX, iDeltaY, CONST_PI / 4);
3851
3852            if ((savepoints[0].y - savepoints[1].y) < 0) {// Point0 is higher than Point1
3853                if (bPointsRight != 0) {// figure opens to the right
3854                    DrawEndpieceDeltasDouble(savepoints[0],
3855                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints1);
3856                    DrawEndpieceDeltasDouble(savepoints[1],
3857                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints2);
3858                } else {// figure opens to the left
3859                    DrawEndpieceDeltasDouble(savepoints[0],
3860                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints1);
3861                    DrawEndpieceDeltasDouble(savepoints[1],
3862                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints2);
3863                }
3864            } else {// Point0 is lower than Point1
3865                if (bPointsRight != 0) {// figure opens to the right
3866                    DrawEndpieceDeltasDouble(savepoints[0],
3867                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints1);
3868                    DrawEndpieceDeltasDouble(savepoints[1],
3869                            iDeltaY.value[0], -iDeltaX.value[0], iDeltaX.value[0], iDeltaY.value[0], deltapoints2);
3870                } else {// figure opens to the left
3871                    DrawEndpieceDeltasDouble(savepoints[0],
3872                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints1);
3873                    DrawEndpieceDeltasDouble(savepoints[1],
3874                            iDeltaX.value[0], iDeltaY.value[0], iDeltaY.value[0], -iDeltaX.value[0], deltapoints2);
3875                }
3876            }
3877
3878            points[counter] = new POINT2(deltapoints1[1]);
3879            points[counter].style = 9;
3880            counter++;
3881            points[counter] = new POINT2(deltapoints1[0]);
3882            points[counter].style = 9;
3883            counter++;
3884            points[counter] = new POINT2(deltapoints1[3]);
3885            points[counter].style = 9;
3886            counter++;
3887            points[counter] = new POINT2(deltapoints1[3]);
3888            points[counter].style = 10;
3889            counter++;
3890
3891            points[counter] = new POINT2(deltapoints2[1]);
3892            points[counter].style = 9;
3893            counter++;
3894            points[counter] = new POINT2(deltapoints2[0]);
3895            points[counter].style = 9;
3896            counter++;
3897            points[counter] = new POINT2(deltapoints2[3]);
3898            points[counter].style = 9;
3899            counter++;
3900            points[counter] = new POINT2(deltapoints2[3]);
3901            points[counter].style = 10;
3902            counter++;
3903
3904        } catch (Exception exc) {
3905            ErrorLogger.LogException(_className ,"GetDISMEasyDouble",
3906                    new RendererException("Failed inside GetDISMEasyDouble", exc));
3907        }
3908        return counter;
3909    }
3910    
3911    /**
3912     * Calculates the points for AMBUSH
3913     *
3914     * @param pLinePoints - OUT - the client points, also used for the returned points.
3915     */
3916    protected static int AmbushPointsDouble(POINT2[] pLinePoints)
3917    {
3918        int counter=0;
3919        try
3920        {
3921            POINT2[] pts=new POINT2[3];
3922            POINT2[] savepoints=new POINT2[3];
3923            // calculate midpoint
3924            POINT2 ptMid=new POINT2();
3925            double dRadius=0,d=0;
3926            double dAngle1=0;
3927            double dAngle1c=0;
3928            double dAngle2c=0;
3929            double dAngle12c=0;
3930            double dAngle0=0;
3931            POINT2[] arcpoints=new POINT2[17];
3932            double dAngleTic = 0;
3933            double dDeltaX1=0, dDeltaY1=0;
3934            double dDeltaX2 = 0;
3935            double dDeltaY2 = 0;
3936            POINT2 ptCenter=new POINT2();
3937            int j=0,i=0;
3938            double iArrowLength=0;
3939
3940            for(j=0;j<3;j++)
3941            {
3942                savepoints[j]=new POINT2(pLinePoints[j]);
3943            }
3944
3945            //initialize the pOINT2 arrays
3946            lineutility.InitializePOINT2Array(arcpoints);
3947            lineutility.InitializePOINT2Array(pts);
3948
3949            ptMid.x = (savepoints[1].x + savepoints[2].x) / 2;
3950            ptMid.y = (savepoints[1].y + savepoints[2].y) / 2;
3951
3952            // calculate arc center
3953            dRadius = Math.sqrt( (ptMid.x-savepoints[2].x) * (ptMid.x-savepoints[2].x) +
3954                (ptMid.y-savepoints[2].y) * (ptMid.y-savepoints[2].y) );
3955
3956            // add section M. Deutch 8-25-05
3957            //consider the other possiblity for a center
3958            double dRadius2 = Math.sqrt( (ptMid.x-savepoints[1].x) * (ptMid.x-savepoints[1].x) +
3959                (ptMid.y-savepoints[1].y) * (ptMid.y-savepoints[1].y) );
3960
3961            dAngle1 = Math.atan2(savepoints[1].y - savepoints[2].y, savepoints[1].x - savepoints[2].x);
3962            ptCenter.x = ptMid.x + Math.cos(dAngle1 - CONST_PI / 2) * dRadius;
3963            ptCenter.y = ptMid.y + Math.sin(dAngle1 - CONST_PI / 2) * dRadius;
3964
3965            //added section M. Deutch 8-25-05
3966            //consider the other possibility for a center if the points were reversed
3967            double dAngle2 = Math.atan2(savepoints[2].y - savepoints[1].y, savepoints[2].x - savepoints[1].x);
3968            POINT2 ptCenter2=new POINT2();
3969            ptCenter2.x = ptMid.x + Math.cos(dAngle2 - CONST_PI / 2) * dRadius;
3970            ptCenter2.y = ptMid.y + Math.sin(dAngle2 - CONST_PI / 2) * dRadius;
3971            double dist=lineutility.CalcDistanceDouble(savepoints[0],ptCenter);
3972            double dist2=lineutility.CalcDistanceDouble(savepoints[0],ptCenter2);
3973            //if the distance to the new center is closer
3974            //then reverse the arc endpoints
3975            if(dist2>dist)
3976            {
3977                //POINT2 ptTemp=new POINT2();
3978                POINT2 ptTemp=new POINT2(savepoints[1]);
3979                savepoints[1]=new POINT2(savepoints[2]);
3980                savepoints[2]=new POINT2(ptTemp);
3981                ptCenter=new POINT2(ptCenter2);
3982                dAngle1=dAngle2;
3983            }
3984            //end section
3985
3986            dRadius = Math.sqrt ( (savepoints[1].x-ptCenter.x) * (savepoints[1].x-ptCenter.x) +
3987                (savepoints[1].y-ptCenter.y) * (savepoints[1].y-ptCenter.y) );
3988
3989            // draw arc
3990            ArcApproximationDouble ((ptCenter.x - dRadius),(ptCenter.y - dRadius),
3991                (ptCenter.x + dRadius),( ptCenter.y + dRadius),
3992                savepoints[2].x, savepoints[2].y, savepoints[1].x, savepoints[1].y, arcpoints);
3993
3994            for(j=0;j<17;j++)
3995            {
3996                pLinePoints[counter]=new POINT2(arcpoints[j]);
3997                pLinePoints[counter].style=0;
3998                counter++;
3999            }
4000            pLinePoints[counter-1].style=5;
4001
4002            // draw line out from arc to point 1
4003            pts[0] = new POINT2(savepoints[0]);
4004            dAngle1c = Math.atan2(ptCenter.y - savepoints[1].y, ptCenter.x - savepoints[1].x);
4005            dAngle2c = Math.atan2(ptCenter.y - savepoints[2].y, ptCenter.x - savepoints[2].x);
4006            dAngle12c = (dAngle1c + dAngle2c) / 2;
4007            if ( (dAngle1c > 0) && (dAngle2c < 0) )
4008            {
4009                pts[1].x = ptCenter.x + Math.cos(dAngle12c) * dRadius;
4010                pts[1].y = ptCenter.y + Math.sin(dAngle12c) * dRadius;
4011            }
4012            else
4013            {
4014                pts[1].x = ptCenter.x - Math.cos(dAngle12c) * dRadius;
4015                pts[1].y = ptCenter.y - Math.sin(dAngle12c) * dRadius;
4016            }
4017            pLinePoints[counter]=new POINT2(pts[0]);
4018            pLinePoints[counter].style=0;counter++;
4019            pLinePoints[counter]=new POINT2(pts[1]);
4020            pLinePoints[counter].style=5;counter++;
4021
4022
4023            // draw arrowhead on end of line
4024            dAngle0 = Math.atan2(pts[1].y - savepoints[0].y, pts[1].x - savepoints[0].x);
4025            iArrowLength =(
4026                (
4027                Math.sqrt // height of graphic
4028                (
4029                (savepoints[1].x-savepoints[2].x) * (savepoints[1].x-savepoints[2].x) +
4030                (savepoints[1].y-savepoints[2].y) * (savepoints[1].y-savepoints[2].y)
4031                ) +
4032                Math.sqrt // length of graphic
4033                (
4034                (savepoints[0].x-ptMid.x) * (savepoints[0].x-ptMid.x) +
4035                (savepoints[0].y-ptMid.y) * (savepoints[0].y-ptMid.y)
4036                )
4037                ) / 20);
4038
4039            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
4040            if((double)iArrowLength>maxLength * DPIScaleFactor)
4041                iArrowLength=(int)maxLength * DPIScaleFactor;
4042            if((double)iArrowLength<minLength * DPIScaleFactor)
4043                iArrowLength=(int)minLength * DPIScaleFactor;
4044
4045            pts[0].x = savepoints[0].x + Math.cos(dAngle0 + CONST_PI / 6) * iArrowLength;
4046            pts[0].y = savepoints[0].y + Math.sin(dAngle0 + CONST_PI / 6) * iArrowLength;
4047            pts[1] = savepoints[0];
4048            pts[2].x = savepoints[0].x + Math.cos(dAngle0 - CONST_PI / 6) * iArrowLength;
4049            pts[2].y = savepoints[0].y + Math.sin(dAngle0 - CONST_PI / 6) * iArrowLength;
4050            for(j=0;j<3;j++)
4051            {
4052                pLinePoints[counter]=new POINT2(pts[j]);
4053                pLinePoints[counter].style=0;
4054                counter++;
4055            }
4056            pLinePoints[counter-1].style=5;
4057
4058            // draw lines out from arc toward back of graphic
4059            d=dRadius/3;
4060            if(d>maxLength * DPIScaleFactor)
4061                    d=maxLength * DPIScaleFactor;
4062            if(d<minLength * DPIScaleFactor)
4063                    d=minLength * DPIScaleFactor;
4064
4065            dAngleTic = CONST_PI / 18; // angle in radians between tic-marks
4066            dDeltaX2 = Math.cos(dAngle1 + CONST_PI / 2) * d;
4067            dDeltaY2 = Math.sin(dAngle1 + CONST_PI / 2) * d;
4068            for (i=0; i<8; i++)
4069            {
4070                dAngle1c += dAngleTic;
4071                dDeltaX1 = Math.cos(dAngle1c) * dRadius;
4072                dDeltaY1 = Math.sin(dAngle1c) * dRadius;
4073                pts[0].x = ptCenter.x - dDeltaX1;
4074                pts[0].y = ptCenter.y - dDeltaY1;
4075                pLinePoints[counter]=new POINT2(pts[0]);
4076                pLinePoints[counter].style=0;
4077                counter++;
4078                pts[1].x = pts[0].x - dDeltaX2;
4079                pts[1].y = pts[0].y - dDeltaY2;
4080                pLinePoints[counter]=new POINT2(pts[1]);
4081                pLinePoints[counter].style=5;
4082                counter++;
4083            }
4084        }
4085        catch(Exception exc)
4086        {
4087            ErrorLogger.LogException(_className ,"AmbushPointsDouble",
4088                    new RendererException("Failed inside AmbushPointsDouble", exc));
4089        }
4090        return counter;
4091    }
4092}