Save This Page
Home » openjdk-7 » java » awt » geom » [javadoc | source]
    1   /*
    2    * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package java.awt.geom;
   27   
   28   import java.io.Serializable;
   29   
   30   /**
   31    * <CODE>Arc2D</CODE> is the abstract superclass for all objects that
   32    * store a 2D arc defined by a framing rectangle,
   33    * start angle, angular extent (length of the arc), and a closure type
   34    * (<CODE>OPEN</CODE>, <CODE>CHORD</CODE>, or <CODE>PIE</CODE>).
   35    * <p>
   36    * <a name="inscribes">
   37    * The arc is a partial section of a full ellipse which
   38    * inscribes the framing rectangle of its parent {@link RectangularShape}.
   39    * </a>
   40    * <a name="angles">
   41    * The angles are specified relative to the non-square
   42    * framing rectangle such that 45 degrees always falls on the line from
   43    * the center of the ellipse to the upper right corner of the framing
   44    * rectangle.
   45    * As a result, if the framing rectangle is noticeably longer along one
   46    * axis than the other, the angles to the start and end of the arc segment
   47    * will be skewed farther along the longer axis of the frame.
   48    * </a>
   49    * <p>
   50    * The actual storage representation of the coordinates is left to
   51    * the subclass.
   52    *
   53    * @author      Jim Graham
   54    * @since 1.2
   55    */
   56   public abstract class Arc2D extends RectangularShape {
   57   
   58       /**
   59        * The closure type for an open arc with no path segments
   60        * connecting the two ends of the arc segment.
   61        * @since 1.2
   62        */
   63       public final static int OPEN = 0;
   64   
   65       /**
   66        * The closure type for an arc closed by drawing a straight
   67        * line segment from the start of the arc segment to the end of the
   68        * arc segment.
   69        * @since 1.2
   70        */
   71       public final static int CHORD = 1;
   72   
   73       /**
   74        * The closure type for an arc closed by drawing straight line
   75        * segments from the start of the arc segment to the center
   76        * of the full ellipse and from that point to the end of the arc segment.
   77        * @since 1.2
   78        */
   79       public final static int PIE = 2;
   80   
   81       /**
   82        * This class defines an arc specified in {@code float} precision.
   83        * @since 1.2
   84        */
   85       public static class Float extends Arc2D implements Serializable {
   86           /**
   87            * The X coordinate of the upper-left corner of the framing
   88            * rectangle of the arc.
   89            * @since 1.2
   90            * @serial
   91            */
   92           public float x;
   93   
   94           /**
   95            * The Y coordinate of the upper-left corner of the framing
   96            * rectangle of the arc.
   97            * @since 1.2
   98            * @serial
   99            */
  100           public float y;
  101   
  102           /**
  103            * The overall width of the full ellipse of which this arc is
  104            * a partial section (not considering the
  105            * angular extents).
  106            * @since 1.2
  107            * @serial
  108            */
  109           public float width;
  110   
  111           /**
  112            * The overall height of the full ellipse of which this arc is
  113            * a partial section (not considering the
  114            * angular extents).
  115            * @since 1.2
  116            * @serial
  117            */
  118           public float height;
  119   
  120           /**
  121            * The starting angle of the arc in degrees.
  122            * @since 1.2
  123            * @serial
  124            */
  125           public float start;
  126   
  127           /**
  128            * The angular extent of the arc in degrees.
  129            * @since 1.2
  130            * @serial
  131            */
  132           public float extent;
  133   
  134           /**
  135            * Constructs a new OPEN arc, initialized to location (0, 0),
  136            * size (0, 0), angular extents (start = 0, extent = 0).
  137            * @since 1.2
  138            */
  139           public Float() {
  140               super(OPEN);
  141           }
  142   
  143           /**
  144            * Constructs a new arc, initialized to location (0, 0),
  145            * size (0, 0), angular extents (start = 0, extent = 0), and
  146            * the specified closure type.
  147            *
  148            * @param type The closure type for the arc:
  149            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  150            * @since 1.2
  151            */
  152           public Float(int type) {
  153               super(type);
  154           }
  155   
  156           /**
  157            * Constructs a new arc, initialized to the specified location,
  158            * size, angular extents, and closure type.
  159            *
  160            * @param x The X coordinate of the upper-left corner of
  161            *          the arc's framing rectangle.
  162            * @param y The Y coordinate of the upper-left corner of
  163            *          the arc's framing rectangle.
  164            * @param w The overall width of the full ellipse of which
  165            *          this arc is a partial section.
  166            * @param h The overall height of the full ellipse of which this
  167            *          arc is a partial section.
  168            * @param start The starting angle of the arc in degrees.
  169            * @param extent The angular extent of the arc in degrees.
  170            * @param type The closure type for the arc:
  171            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  172            * @since 1.2
  173            */
  174           public Float(float x, float y, float w, float h,
  175                        float start, float extent, int type) {
  176               super(type);
  177               this.x = x;
  178               this.y = y;
  179               this.width = w;
  180               this.height = h;
  181               this.start = start;
  182               this.extent = extent;
  183           }
  184   
  185           /**
  186            * Constructs a new arc, initialized to the specified location,
  187            * size, angular extents, and closure type.
  188            *
  189            * @param ellipseBounds The framing rectangle that defines the
  190            * outer boundary of the full ellipse of which this arc is a
  191            * partial section.
  192            * @param start The starting angle of the arc in degrees.
  193            * @param extent The angular extent of the arc in degrees.
  194            * @param type The closure type for the arc:
  195            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  196            * @since 1.2
  197            */
  198           public Float(Rectangle2D ellipseBounds,
  199                        float start, float extent, int type) {
  200               super(type);
  201               this.x = (float) ellipseBounds.getX();
  202               this.y = (float) ellipseBounds.getY();
  203               this.width = (float) ellipseBounds.getWidth();
  204               this.height = (float) ellipseBounds.getHeight();
  205               this.start = start;
  206               this.extent = extent;
  207           }
  208   
  209           /**
  210            * {@inheritDoc}
  211            * Note that the arc
  212            * <a href="Arc2D.html#inscribes">partially inscribes</a>
  213            * the framing rectangle of this {@code RectangularShape}.
  214            *
  215            * @since 1.2
  216            */
  217           public double getX() {
  218               return (double) x;
  219           }
  220   
  221           /**
  222            * {@inheritDoc}
  223            * Note that the arc
  224            * <a href="Arc2D.html#inscribes">partially inscribes</a>
  225            * the framing rectangle of this {@code RectangularShape}.
  226            *
  227            * @since 1.2
  228            */
  229           public double getY() {
  230               return (double) y;
  231           }
  232   
  233           /**
  234            * {@inheritDoc}
  235            * Note that the arc
  236            * <a href="Arc2D.html#inscribes">partially inscribes</a>
  237            * the framing rectangle of this {@code RectangularShape}.
  238            *
  239            * @since 1.2
  240            */
  241           public double getWidth() {
  242               return (double) width;
  243           }
  244   
  245           /**
  246            * {@inheritDoc}
  247            * Note that the arc
  248            * <a href="Arc2D.html#inscribes">partially inscribes</a>
  249            * the framing rectangle of this {@code RectangularShape}.
  250            *
  251            * @since 1.2
  252            */
  253           public double getHeight() {
  254               return (double) height;
  255           }
  256   
  257           /**
  258            * {@inheritDoc}
  259            * @since 1.2
  260            */
  261           public double getAngleStart() {
  262               return (double) start;
  263           }
  264   
  265           /**
  266            * {@inheritDoc}
  267            * @since 1.2
  268            */
  269           public double getAngleExtent() {
  270               return (double) extent;
  271           }
  272   
  273           /**
  274            * {@inheritDoc}
  275            * @since 1.2
  276            */
  277           public boolean isEmpty() {
  278               return (width <= 0.0 || height <= 0.0);
  279           }
  280   
  281           /**
  282            * {@inheritDoc}
  283            * @since 1.2
  284            */
  285           public void setArc(double x, double y, double w, double h,
  286                              double angSt, double angExt, int closure) {
  287               this.setArcType(closure);
  288               this.x = (float) x;
  289               this.y = (float) y;
  290               this.width = (float) w;
  291               this.height = (float) h;
  292               this.start = (float) angSt;
  293               this.extent = (float) angExt;
  294           }
  295   
  296           /**
  297            * {@inheritDoc}
  298            * @since 1.2
  299            */
  300           public void setAngleStart(double angSt) {
  301               this.start = (float) angSt;
  302           }
  303   
  304           /**
  305            * {@inheritDoc}
  306            * @since 1.2
  307            */
  308           public void setAngleExtent(double angExt) {
  309               this.extent = (float) angExt;
  310           }
  311   
  312           /**
  313            * {@inheritDoc}
  314            * @since 1.2
  315            */
  316           protected Rectangle2D makeBounds(double x, double y,
  317                                            double w, double h) {
  318               return new Rectangle2D.Float((float) x, (float) y,
  319                                            (float) w, (float) h);
  320           }
  321   
  322           /*
  323            * JDK 1.6 serialVersionUID
  324            */
  325           private static final long serialVersionUID = 9130893014586380278L;
  326   
  327           /**
  328            * Writes the default serializable fields to the
  329            * <code>ObjectOutputStream</code> followed by a byte
  330            * indicating the arc type of this <code>Arc2D</code>
  331            * instance.
  332            *
  333            * @serialData
  334            * <ol>
  335            * <li>The default serializable fields.
  336            * <li>
  337            * followed by a <code>byte</code> indicating the arc type
  338            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  339            * </ol>
  340            */
  341           private void writeObject(java.io.ObjectOutputStream s)
  342               throws java.io.IOException
  343           {
  344               s.defaultWriteObject();
  345   
  346               s.writeByte(getArcType());
  347           }
  348   
  349           /**
  350            * Reads the default serializable fields from the
  351            * <code>ObjectInputStream</code> followed by a byte
  352            * indicating the arc type of this <code>Arc2D</code>
  353            * instance.
  354            *
  355            * @serialData
  356            * <ol>
  357            * <li>The default serializable fields.
  358            * <li>
  359            * followed by a <code>byte</code> indicating the arc type
  360            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  361            * </ol>
  362            */
  363           private void readObject(java.io.ObjectInputStream s)
  364               throws java.lang.ClassNotFoundException, java.io.IOException
  365           {
  366               s.defaultReadObject();
  367   
  368               try {
  369                   setArcType(s.readByte());
  370               } catch (IllegalArgumentException iae) {
  371                   throw new java.io.InvalidObjectException(iae.getMessage());
  372               }
  373           }
  374       }
  375   
  376       /**
  377        * This class defines an arc specified in {@code double} precision.
  378        * @since 1.2
  379        */
  380       public static class Double extends Arc2D implements Serializable {
  381           /**
  382            * The X coordinate of the upper-left corner of the framing
  383            * rectangle of the arc.
  384            * @since 1.2
  385            * @serial
  386            */
  387           public double x;
  388   
  389           /**
  390            * The Y coordinate of the upper-left corner of the framing
  391            * rectangle of the arc.
  392            * @since 1.2
  393            * @serial
  394            */
  395           public double y;
  396   
  397           /**
  398            * The overall width of the full ellipse of which this arc is
  399            * a partial section (not considering the angular extents).
  400            * @since 1.2
  401            * @serial
  402            */
  403           public double width;
  404   
  405           /**
  406            * The overall height of the full ellipse of which this arc is
  407            * a partial section (not considering the angular extents).
  408            * @since 1.2
  409            * @serial
  410            */
  411           public double height;
  412   
  413           /**
  414            * The starting angle of the arc in degrees.
  415            * @since 1.2
  416            * @serial
  417            */
  418           public double start;
  419   
  420           /**
  421            * The angular extent of the arc in degrees.
  422            * @since 1.2
  423            * @serial
  424            */
  425           public double extent;
  426   
  427           /**
  428            * Constructs a new OPEN arc, initialized to location (0, 0),
  429            * size (0, 0), angular extents (start = 0, extent = 0).
  430            * @since 1.2
  431            */
  432           public Double() {
  433               super(OPEN);
  434           }
  435   
  436           /**
  437            * Constructs a new arc, initialized to location (0, 0),
  438            * size (0, 0), angular extents (start = 0, extent = 0), and
  439            * the specified closure type.
  440            *
  441            * @param type The closure type for the arc:
  442            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  443            * @since 1.2
  444            */
  445           public Double(int type) {
  446               super(type);
  447           }
  448   
  449           /**
  450            * Constructs a new arc, initialized to the specified location,
  451            * size, angular extents, and closure type.
  452            *
  453            * @param x The X coordinate of the upper-left corner
  454            *          of the arc's framing rectangle.
  455            * @param y The Y coordinate of the upper-left corner
  456            *          of the arc's framing rectangle.
  457            * @param w The overall width of the full ellipse of which this
  458            *          arc is a partial section.
  459            * @param h The overall height of the full ellipse of which this
  460            *          arc is a partial section.
  461            * @param start The starting angle of the arc in degrees.
  462            * @param extent The angular extent of the arc in degrees.
  463            * @param type The closure type for the arc:
  464            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  465            * @since 1.2
  466            */
  467           public Double(double x, double y, double w, double h,
  468                         double start, double extent, int type) {
  469               super(type);
  470               this.x = x;
  471               this.y = y;
  472               this.width = w;
  473               this.height = h;
  474               this.start = start;
  475               this.extent = extent;
  476           }
  477   
  478           /**
  479            * Constructs a new arc, initialized to the specified location,
  480            * size, angular extents, and closure type.
  481            *
  482            * @param ellipseBounds The framing rectangle that defines the
  483            * outer boundary of the full ellipse of which this arc is a
  484            * partial section.
  485            * @param start The starting angle of the arc in degrees.
  486            * @param extent The angular extent of the arc in degrees.
  487            * @param type The closure type for the arc:
  488            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  489            * @since 1.2
  490            */
  491           public Double(Rectangle2D ellipseBounds,
  492                         double start, double extent, int type) {
  493               super(type);
  494               this.x = ellipseBounds.getX();
  495               this.y = ellipseBounds.getY();
  496               this.width = ellipseBounds.getWidth();
  497               this.height = ellipseBounds.getHeight();
  498               this.start = start;
  499               this.extent = extent;
  500           }
  501   
  502           /**
  503            * {@inheritDoc}
  504            * Note that the arc
  505            * <a href="Arc2D.html#inscribes">partially inscribes</a>
  506            * the framing rectangle of this {@code RectangularShape}.
  507            *
  508            * @since 1.2
  509            */
  510           public double getX() {
  511               return x;
  512           }
  513   
  514           /**
  515            * {@inheritDoc}
  516            * Note that the arc
  517            * <a href="Arc2D.html#inscribes">partially inscribes</a>
  518            * the framing rectangle of this {@code RectangularShape}.
  519            *
  520            * @since 1.2
  521            */
  522           public double getY() {
  523               return y;
  524           }
  525   
  526           /**
  527            * {@inheritDoc}
  528            * Note that the arc
  529            * <a href="Arc2D.html#inscribes">partially inscribes</a>
  530            * the framing rectangle of this {@code RectangularShape}.
  531            *
  532            * @since 1.2
  533            */
  534           public double getWidth() {
  535               return width;
  536           }
  537   
  538           /**
  539            * {@inheritDoc}
  540            * Note that the arc
  541            * <a href="Arc2D.html#inscribes">partially inscribes</a>
  542            * the framing rectangle of this {@code RectangularShape}.
  543            *
  544            * @since 1.2
  545            */
  546           public double getHeight() {
  547               return height;
  548           }
  549   
  550           /**
  551            * {@inheritDoc}
  552            * @since 1.2
  553            */
  554           public double getAngleStart() {
  555               return start;
  556           }
  557   
  558           /**
  559            * {@inheritDoc}
  560            * @since 1.2
  561            */
  562           public double getAngleExtent() {
  563               return extent;
  564           }
  565   
  566           /**
  567            * {@inheritDoc}
  568            * @since 1.2
  569            */
  570           public boolean isEmpty() {
  571               return (width <= 0.0 || height <= 0.0);
  572           }
  573   
  574           /**
  575            * {@inheritDoc}
  576            * @since 1.2
  577            */
  578           public void setArc(double x, double y, double w, double h,
  579                              double angSt, double angExt, int closure) {
  580               this.setArcType(closure);
  581               this.x = x;
  582               this.y = y;
  583               this.width = w;
  584               this.height = h;
  585               this.start = angSt;
  586               this.extent = angExt;
  587           }
  588   
  589           /**
  590            * {@inheritDoc}
  591            * @since 1.2
  592            */
  593           public void setAngleStart(double angSt) {
  594               this.start = angSt;
  595           }
  596   
  597           /**
  598            * {@inheritDoc}
  599            * @since 1.2
  600            */
  601           public void setAngleExtent(double angExt) {
  602               this.extent = angExt;
  603           }
  604   
  605           /**
  606            * {@inheritDoc}
  607            * @since 1.2
  608            */
  609           protected Rectangle2D makeBounds(double x, double y,
  610                                            double w, double h) {
  611               return new Rectangle2D.Double(x, y, w, h);
  612           }
  613   
  614           /*
  615            * JDK 1.6 serialVersionUID
  616            */
  617           private static final long serialVersionUID = 728264085846882001L;
  618   
  619           /**
  620            * Writes the default serializable fields to the
  621            * <code>ObjectOutputStream</code> followed by a byte
  622            * indicating the arc type of this <code>Arc2D</code>
  623            * instance.
  624            *
  625            * @serialData
  626            * <ol>
  627            * <li>The default serializable fields.
  628            * <li>
  629            * followed by a <code>byte</code> indicating the arc type
  630            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  631            * </ol>
  632            */
  633           private void writeObject(java.io.ObjectOutputStream s)
  634               throws java.io.IOException
  635           {
  636               s.defaultWriteObject();
  637   
  638               s.writeByte(getArcType());
  639           }
  640   
  641           /**
  642            * Reads the default serializable fields from the
  643            * <code>ObjectInputStream</code> followed by a byte
  644            * indicating the arc type of this <code>Arc2D</code>
  645            * instance.
  646            *
  647            * @serialData
  648            * <ol>
  649            * <li>The default serializable fields.
  650            * <li>
  651            * followed by a <code>byte</code> indicating the arc type
  652            * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  653            * </ol>
  654            */
  655           private void readObject(java.io.ObjectInputStream s)
  656               throws java.lang.ClassNotFoundException, java.io.IOException
  657           {
  658               s.defaultReadObject();
  659   
  660               try {
  661                   setArcType(s.readByte());
  662               } catch (IllegalArgumentException iae) {
  663                   throw new java.io.InvalidObjectException(iae.getMessage());
  664               }
  665           }
  666       }
  667   
  668       private int type;
  669   
  670       /**
  671        * This is an abstract class that cannot be instantiated directly.
  672        * Type-specific implementation subclasses are available for
  673        * instantiation and provide a number of formats for storing
  674        * the information necessary to satisfy the various accessor
  675        * methods below.
  676        * <p>
  677        * This constructor creates an object with a default closure
  678        * type of {@link #OPEN}.  It is provided only to enable
  679        * serialization of subclasses.
  680        *
  681        * @see java.awt.geom.Arc2D.Float
  682        * @see java.awt.geom.Arc2D.Double
  683        */
  684       Arc2D() {
  685           this(OPEN);
  686       }
  687   
  688       /**
  689        * This is an abstract class that cannot be instantiated directly.
  690        * Type-specific implementation subclasses are available for
  691        * instantiation and provide a number of formats for storing
  692        * the information necessary to satisfy the various accessor
  693        * methods below.
  694        *
  695        * @param type The closure type of this arc:
  696        * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  697        * @see java.awt.geom.Arc2D.Float
  698        * @see java.awt.geom.Arc2D.Double
  699        * @since 1.2
  700        */
  701       protected Arc2D(int type) {
  702           setArcType(type);
  703       }
  704   
  705       /**
  706        * Returns the starting angle of the arc.
  707        *
  708        * @return A double value that represents the starting angle
  709        * of the arc in degrees.
  710        * @see #setAngleStart
  711        * @since 1.2
  712        */
  713       public abstract double getAngleStart();
  714   
  715       /**
  716        * Returns the angular extent of the arc.
  717        *
  718        * @return A double value that represents the angular extent
  719        * of the arc in degrees.
  720        * @see #setAngleExtent
  721        * @since 1.2
  722        */
  723       public abstract double getAngleExtent();
  724   
  725       /**
  726        * Returns the arc closure type of the arc: {@link #OPEN},
  727        * {@link #CHORD}, or {@link #PIE}.
  728        * @return One of the integer constant closure types defined
  729        * in this class.
  730        * @see #setArcType
  731        * @since 1.2
  732        */
  733       public int getArcType() {
  734           return type;
  735       }
  736   
  737       /**
  738        * Returns the starting point of the arc.  This point is the
  739        * intersection of the ray from the center defined by the
  740        * starting angle and the elliptical boundary of the arc.
  741        *
  742        * @return A <CODE>Point2D</CODE> object representing the
  743        * x,y coordinates of the starting point of the arc.
  744        * @since 1.2
  745        */
  746       public Point2D getStartPoint() {
  747           double angle = Math.toRadians(-getAngleStart());
  748           double x = getX() + (Math.cos(angle) * 0.5 + 0.5) * getWidth();
  749           double y = getY() + (Math.sin(angle) * 0.5 + 0.5) * getHeight();
  750           return new Point2D.Double(x, y);
  751       }
  752   
  753       /**
  754        * Returns the ending point of the arc.  This point is the
  755        * intersection of the ray from the center defined by the
  756        * starting angle plus the angular extent of the arc and the
  757        * elliptical boundary of the arc.
  758        *
  759        * @return A <CODE>Point2D</CODE> object representing the
  760        * x,y coordinates  of the ending point of the arc.
  761        * @since 1.2
  762        */
  763       public Point2D getEndPoint() {
  764           double angle = Math.toRadians(-getAngleStart() - getAngleExtent());
  765           double x = getX() + (Math.cos(angle) * 0.5 + 0.5) * getWidth();
  766           double y = getY() + (Math.sin(angle) * 0.5 + 0.5) * getHeight();
  767           return new Point2D.Double(x, y);
  768       }
  769   
  770       /**
  771        * Sets the location, size, angular extents, and closure type of
  772        * this arc to the specified double values.
  773        *
  774        * @param x The X coordinate of the upper-left corner of the arc.
  775        * @param y The Y coordinate of the upper-left corner of the arc.
  776        * @param w The overall width of the full ellipse of which
  777        *          this arc is a partial section.
  778        * @param h The overall height of the full ellipse of which
  779        *          this arc is a partial section.
  780        * @param angSt The starting angle of the arc in degrees.
  781        * @param angExt The angular extent of the arc in degrees.
  782        * @param closure The closure type for the arc:
  783        * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  784        * @since 1.2
  785        */
  786       public abstract void setArc(double x, double y, double w, double h,
  787                                   double angSt, double angExt, int closure);
  788   
  789       /**
  790        * Sets the location, size, angular extents, and closure type of
  791        * this arc to the specified values.
  792        *
  793        * @param loc The <CODE>Point2D</CODE> representing the coordinates of
  794        * the upper-left corner of the arc.
  795        * @param size The <CODE>Dimension2D</CODE> representing the width
  796        * and height of the full ellipse of which this arc is
  797        * a partial section.
  798        * @param angSt The starting angle of the arc in degrees.
  799        * @param angExt The angular extent of the arc in degrees.
  800        * @param closure The closure type for the arc:
  801        * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  802        * @since 1.2
  803        */
  804       public void setArc(Point2D loc, Dimension2D size,
  805                          double angSt, double angExt, int closure) {
  806           setArc(loc.getX(), loc.getY(), size.getWidth(), size.getHeight(),
  807                  angSt, angExt, closure);
  808       }
  809   
  810       /**
  811        * Sets the location, size, angular extents, and closure type of
  812        * this arc to the specified values.
  813        *
  814        * @param rect The framing rectangle that defines the
  815        * outer boundary of the full ellipse of which this arc is a
  816        * partial section.
  817        * @param angSt The starting angle of the arc in degrees.
  818        * @param angExt The angular extent of the arc in degrees.
  819        * @param closure The closure type for the arc:
  820        * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  821        * @since 1.2
  822        */
  823       public void setArc(Rectangle2D rect, double angSt, double angExt,
  824                          int closure) {
  825           setArc(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(),
  826                  angSt, angExt, closure);
  827       }
  828   
  829       /**
  830        * Sets this arc to be the same as the specified arc.
  831        *
  832        * @param a The <CODE>Arc2D</CODE> to use to set the arc's values.
  833        * @since 1.2
  834        */
  835       public void setArc(Arc2D a) {
  836           setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(),
  837                  a.getAngleStart(), a.getAngleExtent(), a.type);
  838       }
  839   
  840       /**
  841        * Sets the position, bounds, angular extents, and closure type of
  842        * this arc to the specified values. The arc is defined by a center
  843        * point and a radius rather than a framing rectangle for the full ellipse.
  844        *
  845        * @param x The X coordinate of the center of the arc.
  846        * @param y The Y coordinate of the center of the arc.
  847        * @param radius The radius of the arc.
  848        * @param angSt The starting angle of the arc in degrees.
  849        * @param angExt The angular extent of the arc in degrees.
  850        * @param closure The closure type for the arc:
  851        * {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
  852        * @since 1.2
  853        */
  854       public void setArcByCenter(double x, double y, double radius,
  855                                  double angSt, double angExt, int closure) {
  856           setArc(x - radius, y - radius, radius * 2.0, radius * 2.0,
  857                  angSt, angExt, closure);
  858       }
  859   
  860       /**
  861        * Sets the position, bounds, and angular extents of this arc to the
  862        * specified value. The starting angle of the arc is tangent to the
  863        * line specified by points (p1, p2), the ending angle is tangent to
  864        * the line specified by points (p2, p3), and the arc has the
  865        * specified radius.
  866        *
  867        * @param p1 The first point that defines the arc. The starting
  868        * angle of the arc is tangent to the line specified by points (p1, p2).
  869        * @param p2 The second point that defines the arc. The starting
  870        * angle of the arc is tangent to the line specified by points (p1, p2).
  871        * The ending angle of the arc is tangent to the line specified by
  872        * points (p2, p3).
  873        * @param p3 The third point that defines the arc. The ending angle
  874        * of the arc is tangent to the line specified by points (p2, p3).
  875        * @param radius The radius of the arc.
  876        * @since 1.2
  877        */
  878       public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3,
  879                                   double radius) {
  880           double ang1 = Math.atan2(p1.getY() - p2.getY(),
  881                                    p1.getX() - p2.getX());
  882           double ang2 = Math.atan2(p3.getY() - p2.getY(),
  883                                    p3.getX() - p2.getX());
  884           double diff = ang2 - ang1;
  885           if (diff > Math.PI) {
  886               ang2 -= Math.PI * 2.0;
  887           } else if (diff < -Math.PI) {
  888               ang2 += Math.PI * 2.0;
  889           }
  890           double bisect = (ang1 + ang2) / 2.0;
  891           double theta = Math.abs(ang2 - bisect);
  892           double dist = radius / Math.sin(theta);
  893           double x = p2.getX() + dist * Math.cos(bisect);
  894           double y = p2.getY() + dist * Math.sin(bisect);
  895           // REMIND: This needs some work...
  896           if (ang1 < ang2) {
  897               ang1 -= Math.PI / 2.0;
  898               ang2 += Math.PI / 2.0;
  899           } else {
  900               ang1 += Math.PI / 2.0;
  901               ang2 -= Math.PI / 2.0;
  902           }
  903           ang1 = Math.toDegrees(-ang1);
  904           ang2 = Math.toDegrees(-ang2);
  905           diff = ang2 - ang1;
  906           if (diff < 0) {
  907               diff += 360;
  908           } else {
  909               diff -= 360;
  910           }
  911           setArcByCenter(x, y, radius, ang1, diff, type);
  912       }
  913   
  914       /**
  915        * Sets the starting angle of this arc to the specified double
  916        * value.
  917        *
  918        * @param angSt The starting angle of the arc in degrees.
  919        * @see #getAngleStart
  920        * @since 1.2
  921        */
  922       public abstract void setAngleStart(double angSt);
  923   
  924       /**
  925        * Sets the angular extent of this arc to the specified double
  926        * value.
  927        *
  928        * @param angExt The angular extent of the arc in degrees.
  929        * @see #getAngleExtent
  930        * @since 1.2
  931        */
  932       public abstract void setAngleExtent(double angExt);
  933   
  934       /**
  935        * Sets the starting angle of this arc to the angle that the
  936        * specified point defines relative to the center of this arc.
  937        * The angular extent of the arc will remain the same.
  938        *
  939        * @param p The <CODE>Point2D</CODE> that defines the starting angle.
  940        * @see #getAngleStart
  941        * @since 1.2
  942        */
  943       public void setAngleStart(Point2D p) {
  944           // Bias the dx and dy by the height and width of the oval.
  945           double dx = getHeight() * (p.getX() - getCenterX());
  946           double dy = getWidth() * (p.getY() - getCenterY());
  947           setAngleStart(-Math.toDegrees(Math.atan2(dy, dx)));
  948       }
  949   
  950       /**
  951        * Sets the starting angle and angular extent of this arc using two
  952        * sets of coordinates. The first set of coordinates is used to
  953        * determine the angle of the starting point relative to the arc's
  954        * center. The second set of coordinates is used to determine the
  955        * angle of the end point relative to the arc's center.
  956        * The arc will always be non-empty and extend counterclockwise
  957        * from the first point around to the second point.
  958        *
  959        * @param x1 The X coordinate of the arc's starting point.
  960        * @param y1 The Y coordinate of the arc's starting point.
  961        * @param x2 The X coordinate of the arc's ending point.
  962        * @param y2 The Y coordinate of the arc's ending point.
  963        * @since 1.2
  964        */
  965       public void setAngles(double x1, double y1, double x2, double y2) {
  966           double x = getCenterX();
  967           double y = getCenterY();
  968           double w = getWidth();
  969           double h = getHeight();
  970           // Note: reversing the Y equations negates the angle to adjust
  971           // for the upside down coordinate system.
  972           // Also we should bias atans by the height and width of the oval.
  973           double ang1 = Math.atan2(w * (y - y1), h * (x1 - x));
  974           double ang2 = Math.atan2(w * (y - y2), h * (x2 - x));
  975           ang2 -= ang1;
  976           if (ang2 <= 0.0) {
  977               ang2 += Math.PI * 2.0;
  978           }
  979           setAngleStart(Math.toDegrees(ang1));
  980           setAngleExtent(Math.toDegrees(ang2));
  981       }
  982   
  983       /**
  984        * Sets the starting angle and angular extent of this arc using
  985        * two points. The first point is used to determine the angle of
  986        * the starting point relative to the arc's center.
  987        * The second point is used to determine the angle of the end point
  988        * relative to the arc's center.
  989        * The arc will always be non-empty and extend counterclockwise
  990        * from the first point around to the second point.
  991        *
  992        * @param p1 The <CODE>Point2D</CODE> that defines the arc's
  993        * starting point.
  994        * @param p2 The <CODE>Point2D</CODE> that defines the arc's
  995        * ending point.
  996        * @since 1.2
  997        */
  998       public void setAngles(Point2D p1, Point2D p2) {
  999           setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
 1000       }
 1001   
 1002       /**
 1003        * Sets the closure type of this arc to the specified value:
 1004        * <CODE>OPEN</CODE>, <CODE>CHORD</CODE>, or <CODE>PIE</CODE>.
 1005        *
 1006        * @param type The integer constant that represents the closure
 1007        * type of this arc: {@link #OPEN}, {@link #CHORD}, or
 1008        * {@link #PIE}.
 1009        *
 1010        * @throws IllegalArgumentException if <code>type</code> is not
 1011        * 0, 1, or 2.+
 1012        * @see #getArcType
 1013        * @since 1.2
 1014        */
 1015       public void setArcType(int type) {
 1016           if (type < OPEN || type > PIE) {
 1017               throw new IllegalArgumentException("invalid type for Arc: "+type);
 1018           }
 1019           this.type = type;
 1020       }
 1021   
 1022       /**
 1023        * {@inheritDoc}
 1024        * Note that the arc
 1025        * <a href="Arc2D.html#inscribes">partially inscribes</a>
 1026        * the framing rectangle of this {@code RectangularShape}.
 1027        *
 1028        * @since 1.2
 1029        */
 1030       public void setFrame(double x, double y, double w, double h) {
 1031           setArc(x, y, w, h, getAngleStart(), getAngleExtent(), type);
 1032       }
 1033   
 1034       /**
 1035        * Returns the high-precision framing rectangle of the arc.  The framing
 1036        * rectangle contains only the part of this <code>Arc2D</code> that is
 1037        * in between the starting and ending angles and contains the pie
 1038        * wedge, if this <code>Arc2D</code> has a <code>PIE</code> closure type.
 1039        * <p>
 1040        * This method differs from the
 1041        * {@link RectangularShape#getBounds() getBounds} in that the
 1042        * <code>getBounds</code> method only returns the bounds of the
 1043        * enclosing ellipse of this <code>Arc2D</code> without considering
 1044        * the starting and ending angles of this <code>Arc2D</code>.
 1045        *
 1046        * @return the <CODE>Rectangle2D</CODE> that represents the arc's
 1047        * framing rectangle.
 1048        * @since 1.2
 1049        */
 1050       public Rectangle2D getBounds2D() {
 1051           if (isEmpty()) {
 1052               return makeBounds(getX(), getY(), getWidth(), getHeight());
 1053           }
 1054           double x1, y1, x2, y2;
 1055           if (getArcType() == PIE) {
 1056               x1 = y1 = x2 = y2 = 0.0;
 1057           } else {
 1058               x1 = y1 = 1.0;
 1059               x2 = y2 = -1.0;
 1060           }
 1061           double angle = 0.0;
 1062           for (int i = 0; i < 6; i++) {
 1063               if (i < 4) {
 1064                   // 0-3 are the four quadrants
 1065                   angle += 90.0;
 1066                   if (!containsAngle(angle)) {
 1067                       continue;
 1068                   }
 1069               } else if (i == 4) {
 1070                   // 4 is start angle
 1071                   angle = getAngleStart();
 1072               } else {
 1073                   // 5 is end angle
 1074                   angle += getAngleExtent();
 1075               }
 1076               double rads = Math.toRadians(-angle);
 1077               double xe = Math.cos(rads);
 1078               double ye = Math.sin(rads);
 1079               x1 = Math.min(x1, xe);
 1080               y1 = Math.min(y1, ye);
 1081               x2 = Math.max(x2, xe);
 1082               y2 = Math.max(y2, ye);
 1083           }
 1084           double w = getWidth();
 1085           double h = getHeight();
 1086           x2 = (x2 - x1) * 0.5 * w;
 1087           y2 = (y2 - y1) * 0.5 * h;
 1088           x1 = getX() + (x1 * 0.5 + 0.5) * w;
 1089           y1 = getY() + (y1 * 0.5 + 0.5) * h;
 1090           return makeBounds(x1, y1, x2, y2);
 1091       }
 1092   
 1093       /**
 1094        * Constructs a <code>Rectangle2D</code> of the appropriate precision
 1095        * to hold the parameters calculated to be the framing rectangle
 1096        * of this arc.
 1097        *
 1098        * @param x The X coordinate of the upper-left corner of the
 1099        * framing rectangle.
 1100        * @param y The Y coordinate of the upper-left corner of the
 1101        * framing rectangle.
 1102        * @param w The width of the framing rectangle.
 1103        * @param h The height of the framing rectangle.
 1104        * @return a <code>Rectangle2D</code> that is the framing rectangle
 1105        *     of this arc.
 1106        * @since 1.2
 1107        */
 1108       protected abstract Rectangle2D makeBounds(double x, double y,
 1109                                                 double w, double h);
 1110   
 1111       /*
 1112        * Normalizes the specified angle into the range -180 to 180.
 1113        */
 1114       static double normalizeDegrees(double angle) {
 1115           if (angle > 180.0) {
 1116               if (angle <= (180.0 + 360.0)) {
 1117                   angle = angle - 360.0;
 1118               } else {
 1119                   angle = Math.IEEEremainder(angle, 360.0);
 1120                   // IEEEremainder can return -180 here for some input values...
 1121                   if (angle == -180.0) {
 1122                       angle = 180.0;
 1123                   }
 1124               }
 1125           } else if (angle <= -180.0) {
 1126               if (angle > (-180.0 - 360.0)) {
 1127                   angle = angle + 360.0;
 1128               } else {
 1129                   angle = Math.IEEEremainder(angle, 360.0);
 1130                   // IEEEremainder can return -180 here for some input values...
 1131                   if (angle == -180.0) {
 1132                       angle = 180.0;
 1133                   }
 1134               }
 1135           }
 1136           return angle;
 1137       }
 1138   
 1139       /**
 1140        * Determines whether or not the specified angle is within the
 1141        * angular extents of the arc.
 1142        *
 1143        * @param angle The angle to test.
 1144        *
 1145        * @return <CODE>true</CODE> if the arc contains the angle,
 1146        * <CODE>false</CODE> if the arc doesn't contain the angle.
 1147        * @since 1.2
 1148        */
 1149       public boolean containsAngle(double angle) {
 1150           double angExt = getAngleExtent();
 1151           boolean backwards = (angExt < 0.0);
 1152           if (backwards) {
 1153               angExt = -angExt;
 1154           }
 1155           if (angExt >= 360.0) {
 1156               return true;
 1157           }
 1158           angle = normalizeDegrees(angle) - normalizeDegrees(getAngleStart());
 1159           if (backwards) {
 1160               angle = -angle;
 1161           }
 1162           if (angle < 0.0) {
 1163               angle += 360.0;
 1164           }
 1165   
 1166   
 1167           return (angle >= 0.0) && (angle < angExt);
 1168       }
 1169   
 1170       /**
 1171        * Determines whether or not the specified point is inside the boundary
 1172        * of the arc.
 1173        *
 1174        * @param x The X coordinate of the point to test.
 1175        * @param y The Y coordinate of the point to test.
 1176        *
 1177        * @return <CODE>true</CODE> if the point lies within the bound of
 1178        * the arc, <CODE>false</CODE> if the point lies outside of the
 1179        * arc's bounds.
 1180        * @since 1.2
 1181        */
 1182       public boolean contains(double x, double y) {
 1183           // Normalize the coordinates compared to the ellipse
 1184           // having a center at 0,0 and a radius of 0.5.
 1185           double ellw = getWidth();
 1186           if (ellw <= 0.0) {
 1187               return false;
 1188           }
 1189           double normx = (x - getX()) / ellw - 0.5;
 1190           double ellh = getHeight();
 1191           if (ellh <= 0.0) {
 1192               return false;
 1193           }
 1194           double normy = (y - getY()) / ellh - 0.5;
 1195           double distSq = (normx * normx + normy * normy);
 1196           if (distSq >= 0.25) {
 1197               return false;
 1198           }
 1199           double angExt = Math.abs(getAngleExtent());
 1200           if (angExt >= 360.0) {
 1201               return true;
 1202           }
 1203           boolean inarc = containsAngle(-Math.toDegrees(Math.atan2(normy,
 1204                                                                    normx)));
 1205           if (type == PIE) {
 1206               return inarc;
 1207           }
 1208           // CHORD and OPEN behave the same way
 1209           if (inarc) {
 1210               if (angExt >= 180.0) {
 1211                   return true;
 1212               }
 1213               // point must be outside the "pie triangle"
 1214           } else {
 1215               if (angExt <= 180.0) {
 1216                   return false;
 1217               }
 1218               // point must be inside the "pie triangle"
 1219           }
 1220           // The point is inside the pie triangle iff it is on the same
 1221           // side of the line connecting the ends of the arc as the center.
 1222           double angle = Math.toRadians(-getAngleStart());
 1223           double x1 = Math.cos(angle);
 1224           double y1 = Math.sin(angle);
 1225           angle += Math.toRadians(-getAngleExtent());
 1226           double x2 = Math.cos(angle);
 1227           double y2 = Math.sin(angle);
 1228           boolean inside = (Line2D.relativeCCW(x1, y1, x2, y2, 2*normx, 2*normy) *
 1229                             Line2D.relativeCCW(x1, y1, x2, y2, 0, 0) >= 0);
 1230           return inarc ? !inside : inside;
 1231       }
 1232   
 1233       /**
 1234        * Determines whether or not the interior of the arc intersects
 1235        * the interior of the specified rectangle.
 1236        *
 1237        * @param x The X coordinate of the rectangle's upper-left corner.
 1238        * @param y The Y coordinate of the rectangle's upper-left corner.
 1239        * @param w The width of the rectangle.
 1240        * @param h The height of the rectangle.
 1241        *
 1242        * @return <CODE>true</CODE> if the arc intersects the rectangle,
 1243        * <CODE>false</CODE> if the arc doesn't intersect the rectangle.
 1244        * @since 1.2
 1245        */
 1246       public boolean intersects(double x, double y, double w, double h) {
 1247   
 1248           double aw = getWidth();
 1249           double ah = getHeight();
 1250   
 1251           if ( w <= 0 || h <= 0 || aw <= 0 || ah <= 0 ) {
 1252               return false;
 1253           }
 1254           double ext = getAngleExtent();
 1255           if (ext == 0) {
 1256               return false;
 1257           }
 1258   
 1259           double ax  = getX();
 1260           double ay  = getY();
 1261           double axw = ax + aw;
 1262           double ayh = ay + ah;
 1263           double xw  = x + w;
 1264           double yh  = y + h;
 1265   
 1266           // check bbox
 1267           if (x >= axw || y >= ayh || xw <= ax || yh <= ay) {
 1268               return false;
 1269           }
 1270   
 1271           // extract necessary data
 1272           double axc = getCenterX();
 1273           double ayc = getCenterY();
 1274           Point2D sp = getStartPoint();
 1275           Point2D ep = getEndPoint();
 1276           double sx = sp.getX();
 1277           double sy = sp.getY();
 1278           double ex = ep.getX();
 1279           double ey = ep.getY();
 1280   
 1281           /*
 1282            * Try to catch rectangles that intersect arc in areas
 1283            * outside of rectagle with left top corner coordinates
 1284            * (min(center x, start point x, end point x),
 1285            *  min(center y, start point y, end point y))
 1286            * and rigth bottom corner coordinates
 1287            * (max(center x, start point x, end point x),
 1288            *  max(center y, start point y, end point y)).
 1289            * So we'll check axis segments outside of rectangle above.
 1290            */
 1291           if (ayc >= y && ayc <= yh) { // 0 and 180
 1292               if ((sx < xw && ex < xw && axc < xw &&
 1293                    axw > x && containsAngle(0)) ||
 1294                   (sx > x && ex > x && axc > x &&
 1295                    ax < xw && containsAngle(180))) {
 1296                   return true;
 1297               }
 1298           }
 1299           if (axc >= x && axc <= xw) { // 90 and 270
 1300               if ((sy > y && ey > y && ayc > y &&
 1301                    ay < yh && containsAngle(90)) ||
 1302                   (sy < yh && ey < yh && ayc < yh &&
 1303                    ayh > y && containsAngle(270))) {
 1304                   return true;
 1305               }
 1306           }
 1307   
 1308           /*
 1309            * For PIE we should check intersection with pie slices;
 1310            * also we should do the same for arcs with extent is greater
 1311            * than 180, because we should cover case of rectangle, which
 1312            * situated between center of arc and chord, but does not
 1313            * intersect the chord.
 1314            */
 1315           Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
 1316           if (type == PIE || Math.abs(ext) > 180) {
 1317               // for PIE: try to find intersections with pie slices
 1318               if (rect.intersectsLine(axc, ayc, sx, sy) ||
 1319                   rect.intersectsLine(axc, ayc, ex, ey)) {
 1320                   return true;
 1321               }
 1322           } else {
 1323               // for CHORD and OPEN: try to find intersections with chord
 1324               if (rect.intersectsLine(sx, sy, ex, ey)) {
 1325                   return true;
 1326               }
 1327           }
 1328   
 1329           // finally check the rectangle corners inside the arc
 1330           if (contains(x, y) || contains(x + w, y) ||
 1331               contains(x, y + h) || contains(x + w, y + h)) {
 1332               return true;
 1333           }
 1334   
 1335           return false;
 1336       }
 1337   
 1338       /**
 1339        * Determines whether or not the interior of the arc entirely contains
 1340        * the specified rectangle.
 1341        *
 1342        * @param x The X coordinate of the rectangle's upper-left corner.
 1343        * @param y The Y coordinate of the rectangle's upper-left corner.
 1344        * @param w The width of the rectangle.
 1345        * @param h The height of the rectangle.
 1346        *
 1347        * @return <CODE>true</CODE> if the arc contains the rectangle,
 1348        * <CODE>false</CODE> if the arc doesn't contain the rectangle.
 1349        * @since 1.2
 1350        */
 1351       public boolean contains(double x, double y, double w, double h) {
 1352           return contains(x, y, w, h, null);
 1353       }
 1354   
 1355       /**
 1356        * Determines whether or not the interior of the arc entirely contains
 1357        * the specified rectangle.
 1358        *
 1359        * @param r The <CODE>Rectangle2D</CODE> to test.
 1360        *
 1361        * @return <CODE>true</CODE> if the arc contains the rectangle,
 1362        * <CODE>false</CODE> if the arc doesn't contain the rectangle.
 1363        * @since 1.2
 1364        */
 1365       public boolean contains(Rectangle2D r) {
 1366           return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight(), r);
 1367       }
 1368   
 1369       private boolean contains(double x, double y, double w, double h,
 1370                                Rectangle2D origrect) {
 1371           if (!(contains(x, y) &&
 1372                 contains(x + w, y) &&
 1373                 contains(x, y + h) &&
 1374                 contains(x + w, y + h))) {
 1375               return false;
 1376           }
 1377           // If the shape is convex then we have done all the testing
 1378           // we need.  Only PIE arcs can be concave and then only if
 1379           // the angular extents are greater than 180 degrees.
 1380           if (type != PIE || Math.abs(getAngleExtent()) <= 180.0) {
 1381               return true;
 1382           }
 1383           // For a PIE shape we have an additional test for the case where
 1384           // the angular extents are greater than 180 degrees and all four
 1385           // rectangular corners are inside the shape but one of the
 1386           // rectangle edges spans across the "missing wedge" of the arc.
 1387           // We can test for this case by checking if the rectangle intersects
 1388           // either of the pie angle segments.
 1389           if (origrect == null) {
 1390               origrect = new Rectangle2D.Double(x, y, w, h);
 1391           }
 1392           double halfW = getWidth() / 2.0;
 1393           double halfH = getHeight() / 2.0;
 1394           double xc = getX() + halfW;
 1395           double yc = getY() + halfH;
 1396           double angle = Math.toRadians(-getAngleStart());
 1397           double xe = xc + halfW * Math.cos(angle);
 1398           double ye = yc + halfH * Math.sin(angle);
 1399           if (origrect.intersectsLine(xc, yc, xe, ye)) {
 1400               return false;
 1401           }
 1402           angle += Math.toRadians(-getAngleExtent());
 1403           xe = xc + halfW * Math.cos(angle);
 1404           ye = yc + halfH * Math.sin(angle);
 1405           return !origrect.intersectsLine(xc, yc, xe, ye);
 1406       }
 1407   
 1408       /**
 1409        * Returns an iteration object that defines the boundary of the
 1410        * arc.
 1411        * This iterator is multithread safe.
 1412        * <code>Arc2D</code> guarantees that
 1413        * modifications to the geometry of the arc
 1414        * do not affect any iterations of that geometry that
 1415        * are already in process.
 1416        *
 1417        * @param at an optional <CODE>AffineTransform</CODE> to be applied
 1418        * to the coordinates as they are returned in the iteration, or null
 1419        * if the untransformed coordinates are desired.
 1420        *
 1421        * @return A <CODE>PathIterator</CODE> that defines the arc's boundary.
 1422        * @since 1.2
 1423        */
 1424       public PathIterator getPathIterator(AffineTransform at) {
 1425           return new ArcIterator(this, at);
 1426       }
 1427   
 1428       /**
 1429        * Returns the hashcode for this <code>Arc2D</code>.
 1430        * @return the hashcode for this <code>Arc2D</code>.
 1431        * @since 1.6
 1432        */
 1433       public int hashCode() {
 1434           long bits = java.lang.Double.doubleToLongBits(getX());
 1435           bits += java.lang.Double.doubleToLongBits(getY()) * 37;
 1436           bits += java.lang.Double.doubleToLongBits(getWidth()) * 43;
 1437           bits += java.lang.Double.doubleToLongBits(getHeight()) * 47;
 1438           bits += java.lang.Double.doubleToLongBits(getAngleStart()) * 53;
 1439           bits += java.lang.Double.doubleToLongBits(getAngleExtent()) * 59;
 1440           bits += getArcType() * 61;
 1441           return (((int) bits) ^ ((int) (bits >> 32)));
 1442       }
 1443   
 1444       /**
 1445        * Determines whether or not the specified <code>Object</code> is
 1446        * equal to this <code>Arc2D</code>.  The specified
 1447        * <code>Object</code> is equal to this <code>Arc2D</code>
 1448        * if it is an instance of <code>Arc2D</code> and if its
 1449        * location, size, arc extents and type are the same as this
 1450        * <code>Arc2D</code>.
 1451        * @param obj  an <code>Object</code> to be compared with this
 1452        *             <code>Arc2D</code>.
 1453        * @return  <code>true</code> if <code>obj</code> is an instance
 1454        *          of <code>Arc2D</code> and has the same values;
 1455        *          <code>false</code> otherwise.
 1456        * @since 1.6
 1457        */
 1458       public boolean equals(Object obj) {
 1459           if (obj == this) {
 1460               return true;
 1461           }
 1462           if (obj instanceof Arc2D) {
 1463               Arc2D a2d = (Arc2D) obj;
 1464               return ((getX() == a2d.getX()) &&
 1465                       (getY() == a2d.getY()) &&
 1466                       (getWidth() == a2d.getWidth()) &&
 1467                       (getHeight() == a2d.getHeight()) &&
 1468                       (getAngleStart() == a2d.getAngleStart()) &&
 1469                       (getAngleExtent() == a2d.getAngleExtent()) &&
 1470                       (getArcType() == a2d.getArcType()));
 1471           }
 1472           return false;
 1473       }
 1474   }

Save This Page
Home » openjdk-7 » java » awt » geom » [javadoc | source]