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