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