jdk/src/share/classes/java/awt/geom/CubicCurve2D.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.awt.geom;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Shape;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.Rectangle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.Serializable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import sun.awt.geom.Curve;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * The <code>CubicCurve2D</code> class defines a cubic parametric curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * segment in {@code (x,y)} coordinate space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * This class is only the abstract superclass for all objects which
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * store a 2D cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * The actual storage representation of the coordinates is left to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * the subclass.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * @author      Jim Graham
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
public abstract class CubicCurve2D implements Shape, Cloneable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
     * A cubic parametric curve segment specified with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
     * {@code float} coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    public static class Float extends CubicCurve2D implements Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
         * The X coordinate of the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
        public float x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
         * The Y coordinate of the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        public float y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
         * The X coordinate of the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        public float ctrlx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
         * The Y coordinate of the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        public float ctrly1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
         * The X coordinate of the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        public float ctrlx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
         * The Y coordinate of the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        public float ctrly2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
         * The X coordinate of the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        public float x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
         * The Y coordinate of the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        public float y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
         * Constructs and initializes a CubicCurve with coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
         * (0, 0, 0, 0, 0, 0, 0, 0).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        public Float() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
         * Constructs and initializes a {@code CubicCurve2D} from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
         * the specified {@code float} coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
         * @param x1 the X coordinate for the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
         *           of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
         * @param y1 the Y coordinate for the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
         *           of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
         * @param ctrlx1 the X coordinate for the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
         *               of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
         * @param ctrly1 the Y coordinate for the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
         *               of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
         * @param ctrlx2 the X coordinate for the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
         *               of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
         * @param ctrly2 the Y coordinate for the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
         *               of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
         * @param x2 the X coordinate for the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
         *           of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
         * @param y2 the Y coordinate for the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
         *           of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        public Float(float x1, float y1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                     float ctrlx1, float ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                     float ctrlx2, float ctrly2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                     float x2, float y2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        public double getX1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            return (double) x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        public double getY1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            return (double) y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        public Point2D getP1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
            return new Point2D.Float(x1, y1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        public double getCtrlX1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            return (double) ctrlx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        public double getCtrlY1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            return (double) ctrly1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        public Point2D getCtrlP1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            return new Point2D.Float(ctrlx1, ctrly1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        public double getCtrlX2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            return (double) ctrlx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        public double getCtrlY2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            return (double) ctrly2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        public Point2D getCtrlP2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            return new Point2D.Float(ctrlx2, ctrly2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        public double getX2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            return (double) x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        public double getY2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            return (double) y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        public Point2D getP2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            return new Point2D.Float(x2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        public void setCurve(double x1, double y1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                             double ctrlx1, double ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                             double ctrlx2, double ctrly2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                             double x2, double y2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            this.x1     = (float) x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            this.y1     = (float) y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            this.ctrlx1 = (float) ctrlx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            this.ctrly1 = (float) ctrly1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            this.ctrlx2 = (float) ctrlx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            this.ctrly2 = (float) ctrly2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            this.x2     = (float) x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            this.y2     = (float) y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
         * Sets the location of the end points and control points
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
         * of this curve to the specified {@code float} coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
         * @param x1 the X coordinate used to set the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
         *           of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
         * @param y1 the Y coordinate used to set the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
         *           of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
         * @param ctrlx1 the X coordinate used to set the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
         *               of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
         * @param ctrly1 the Y coordinate used to set the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
         *               of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
         * @param ctrlx2 the X coordinate used to set the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
         *               of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
         * @param ctrly2 the Y coordinate used to set the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
         *               of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
         * @param x2 the X coordinate used to set the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
         *           of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
         * @param y2 the Y coordinate used to set the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
         *           of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        public void setCurve(float x1, float y1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                             float ctrlx1, float ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                             float ctrlx2, float ctrly2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                             float x2, float y2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            this.x1     = x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            this.y1     = y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            this.ctrlx1 = ctrlx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            this.ctrly1 = ctrly1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            this.ctrlx2 = ctrlx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            this.ctrly2 = ctrly2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            this.x2     = x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            this.y2     = y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        public Rectangle2D getBounds2D() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            float left   = Math.min(Math.min(x1, x2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                                    Math.min(ctrlx1, ctrlx2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            float top    = Math.min(Math.min(y1, y2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                                    Math.min(ctrly1, ctrly2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            float right  = Math.max(Math.max(x1, x2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                                    Math.max(ctrlx1, ctrlx2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            float bottom = Math.max(Math.max(y1, y2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                                    Math.max(ctrly1, ctrly2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            return new Rectangle2D.Float(left, top,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                                         right - left, bottom - top);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
         * JDK 1.6 serialVersionUID
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        private static final long serialVersionUID = -1272015596714244385L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     * A cubic parametric curve segment specified with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     * {@code double} coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    public static class Double extends CubicCurve2D implements Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
         * The X coordinate of the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        public double x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
         * The Y coordinate of the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        public double y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
         * The X coordinate of the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        public double ctrlx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
         * The Y coordinate of the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        public double ctrly1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
         * The X coordinate of the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        public double ctrlx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
         * The Y coordinate of the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        public double ctrly2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
         * The X coordinate of the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        public double x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
         * The Y coordinate of the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
         * of the cubic curve segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
         * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        public double y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
         * Constructs and initializes a CubicCurve with coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
         * (0, 0, 0, 0, 0, 0, 0, 0).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        public Double() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
         * Constructs and initializes a {@code CubicCurve2D} from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
         * the specified {@code double} coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
         * @param x1 the X coordinate for the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
         *           of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
         * @param y1 the Y coordinate for the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
         *           of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
         * @param ctrlx1 the X coordinate for the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
         *               of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
         * @param ctrly1 the Y coordinate for the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
         *               of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
         * @param ctrlx2 the X coordinate for the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
         *               of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
         * @param ctrly2 the Y coordinate for the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
         *               of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
         * @param x2 the X coordinate for the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
         *           of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
         * @param y2 the Y coordinate for the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
         *           of the resulting {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        public Double(double x1, double y1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                      double ctrlx1, double ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
                      double ctrlx2, double ctrly2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                      double x2, double y2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        public double getX1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            return x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        public double getY1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            return y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        public Point2D getP1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            return new Point2D.Double(x1, y1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        public double getCtrlX1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
            return ctrlx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        public double getCtrlY1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            return ctrly1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        public Point2D getCtrlP1() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
            return new Point2D.Double(ctrlx1, ctrly1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        public double getCtrlX2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            return ctrlx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        public double getCtrlY2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            return ctrly2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        public Point2D getCtrlP2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            return new Point2D.Double(ctrlx2, ctrly2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        public double getX2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
            return x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        public double getY2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            return y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        public Point2D getP2() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            return new Point2D.Double(x2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        public void setCurve(double x1, double y1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                             double ctrlx1, double ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                             double ctrlx2, double ctrly2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                             double x2, double y2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            this.x1     = x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            this.y1     = y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            this.ctrlx1 = ctrlx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            this.ctrly1 = ctrly1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            this.ctrlx2 = ctrlx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            this.ctrly2 = ctrly2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            this.x2     = x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            this.y2     = y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
         * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
         * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        public Rectangle2D getBounds2D() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            double left   = Math.min(Math.min(x1, x2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                                     Math.min(ctrlx1, ctrlx2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
            double top    = Math.min(Math.min(y1, y2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                                     Math.min(ctrly1, ctrly2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            double right  = Math.max(Math.max(x1, x2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                                     Math.max(ctrlx1, ctrlx2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            double bottom = Math.max(Math.max(y1, y2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                                     Math.max(ctrly1, ctrly2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
            return new Rectangle2D.Double(left, top,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                                          right - left, bottom - top);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
         * JDK 1.6 serialVersionUID
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        private static final long serialVersionUID = -4202960122839707295L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     * This is an abstract class that cannot be instantiated directly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     * Type-specific implementation subclasses are available for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
     * instantiation and provide a number of formats for storing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
     * the information necessary to satisfy the various accessor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
     * methods below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
     * @see java.awt.geom.CubicCurve2D.Float
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
     * @see java.awt.geom.CubicCurve2D.Double
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    protected CubicCurve2D() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
     * Returns the X coordinate of the start point in double precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
     * @return the X coordinate of the start point of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
     *         {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    public abstract double getX1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     * Returns the Y coordinate of the start point in double precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
     * @return the Y coordinate of the start point of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
     *         {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    public abstract double getY1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * Returns the start point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     * @return a {@code Point2D} that is the start point of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     *         the {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    public abstract Point2D getP1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     * Returns the X coordinate of the first control point in double precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     * @return the X coordinate of the first control point of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
     *         {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
    public abstract double getCtrlX1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
     * Returns the Y coordinate of the first control point in double precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
     * @return the Y coordinate of the first control point of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
     *         {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    public abstract double getCtrlY1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
     * Returns the first control point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
     * @return a {@code Point2D} that is the first control point of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
     *         the {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    public abstract Point2D getCtrlP1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     * Returns the X coordinate of the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
     * in double precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     * @return the X coordinate of the second control point of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     *         {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    public abstract double getCtrlX2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     * Returns the Y coordinate of the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     * in double precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     * @return the Y coordinate of the second control point of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     *         {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    public abstract double getCtrlY2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     * Returns the second control point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     * @return a {@code Point2D} that is the second control point of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     *         the {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    public abstract Point2D getCtrlP2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
     * Returns the X coordinate of the end point in double precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * @return the X coordinate of the end point of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     *         {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
    public abstract double getX2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
     * Returns the Y coordinate of the end point in double precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
     * @return the Y coordinate of the end point of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
     *         {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    public abstract double getY2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     * Returns the end point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
     * @return a {@code Point2D} that is the end point of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
     *         the {@code CubicCurve2D}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    public abstract Point2D getP2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * Sets the location of the end points and control points of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     * to the specified double coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
     * @param x1 the X coordinate used to set the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
     *           of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * @param y1 the Y coordinate used to set the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     *           of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
     * @param ctrlx1 the X coordinate used to set the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
     *               of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
     * @param ctrly1 the Y coordinate used to set the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
     *               of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
     * @param ctrlx2 the X coordinate used to set the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
     *               of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
     * @param ctrly2 the Y coordinate used to set the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
     *               of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
     * @param x2 the X coordinate used to set the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
     *           of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
     * @param y2 the Y coordinate used to set the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
     *           of this {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
    public abstract void setCurve(double x1, double y1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                                  double ctrlx1, double ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                                  double ctrlx2, double ctrly2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                                  double x2, double y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
     * Sets the location of the end points and control points of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
     * to the double coordinates at the specified offset in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     * array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
     * @param coords a double array containing coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     * @param offset the index of <code>coords</code> from which to begin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
     *          setting the end points and control points of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
     *          to the coordinates contained in <code>coords</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    public void setCurve(double[] coords, int offset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        setCurve(coords[offset + 0], coords[offset + 1],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
                 coords[offset + 2], coords[offset + 3],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
                 coords[offset + 4], coords[offset + 5],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
                 coords[offset + 6], coords[offset + 7]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
     * Sets the location of the end points and control points of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
     * to the specified <code>Point2D</code> coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
     * @param p1 the first specified <code>Point2D</code> used to set the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
     *          start point of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
     * @param cp1 the second specified <code>Point2D</code> used to set the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
     *          first control point of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
     * @param cp2 the third specified <code>Point2D</code> used to set the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
     *          second control point of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
     * @param p2 the fourth specified <code>Point2D</code> used to set the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
     *          end point of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    public void setCurve(Point2D p1, Point2D cp1, Point2D cp2, Point2D p2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        setCurve(p1.getX(), p1.getY(), cp1.getX(), cp1.getY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                 cp2.getX(), cp2.getY(), p2.getX(), p2.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
     * Sets the location of the end points and control points of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
     * to the coordinates of the <code>Point2D</code> objects at the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
     * offset in the specified array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
     * @param pts an array of <code>Point2D</code> objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
     * @param offset  the index of <code>pts</code> from which to begin setting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
     *          the end points and control points of this curve to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
     *          points contained in <code>pts</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
    public void setCurve(Point2D[] pts, int offset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        setCurve(pts[offset + 0].getX(), pts[offset + 0].getY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                 pts[offset + 1].getX(), pts[offset + 1].getY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                 pts[offset + 2].getX(), pts[offset + 2].getY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                 pts[offset + 3].getX(), pts[offset + 3].getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
     * Sets the location of the end points and control points of this curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
     * to the same as those in the specified <code>CubicCurve2D</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
     * @param c the specified <code>CubicCurve2D</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
    public void setCurve(CubicCurve2D c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        setCurve(c.getX1(), c.getY1(), c.getCtrlX1(), c.getCtrlY1(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                 c.getCtrlX2(), c.getCtrlY2(), c.getX2(), c.getY2());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
     * Returns the square of the flatness of the cubic curve specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
     * by the indicated control points. The flatness is the maximum distance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
     * of a control point from the line connecting the end points.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
     * @param x1 the X coordinate that specifies the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
     *           of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
     * @param y1 the Y coordinate that specifies the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
     *           of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
     * @param ctrlx1 the X coordinate that specifies the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
     *               of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
     * @param ctrly1 the Y coordinate that specifies the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     *               of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
     * @param ctrlx2 the X coordinate that specifies the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
     *               of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
     * @param ctrly2 the Y coordinate that specifies the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
     *               of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
     * @param x2 the X coordinate that specifies the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
     *           of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
     * @param y2 the Y coordinate that specifies the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
     *           of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
     * @return the square of the flatness of the {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
     *          represented by the specified coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
    public static double getFlatnessSq(double x1, double y1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                                       double ctrlx1, double ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                                       double ctrlx2, double ctrly2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
                                       double x2, double y2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        return Math.max(Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx1, ctrly1),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                        Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx2, ctrly2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
     * Returns the flatness of the cubic curve specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
     * by the indicated control points. The flatness is the maximum distance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
     * of a control point from the line connecting the end points.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
     * @param x1 the X coordinate that specifies the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
     *           of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
     * @param y1 the Y coordinate that specifies the start point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
     *           of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
     * @param ctrlx1 the X coordinate that specifies the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
     *               of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
     * @param ctrly1 the Y coordinate that specifies the first control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
     *               of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
     * @param ctrlx2 the X coordinate that specifies the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
     *               of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
     * @param ctrly2 the Y coordinate that specifies the second control point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
     *               of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
     * @param x2 the X coordinate that specifies the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
     *           of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
     * @param y2 the Y coordinate that specifies the end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
     *           of a {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
     * @return the flatness of the {@code CubicCurve2D}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
     *          represented by the specified coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    public static double getFlatness(double x1, double y1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                                     double ctrlx1, double ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                                     double ctrlx2, double ctrly2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                                     double x2, double y2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
        return Math.sqrt(getFlatnessSq(x1, y1, ctrlx1, ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                                       ctrlx2, ctrly2, x2, y2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
     * Returns the square of the flatness of the cubic curve specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
     * by the control points stored in the indicated array at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
     * indicated index. The flatness is the maximum distance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
     * of a control point from the line connecting the end points.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
     * @param coords an array containing coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
     * @param offset the index of <code>coords</code> from which to begin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
     *          getting the end points and control points of the curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
     * @return the square of the flatness of the <code>CubicCurve2D</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
     *          specified by the coordinates in <code>coords</code> at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
     *          the specified offset.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
    public static double getFlatnessSq(double coords[], int offset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        return getFlatnessSq(coords[offset + 0], coords[offset + 1],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                             coords[offset + 2], coords[offset + 3],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                             coords[offset + 4], coords[offset + 5],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                             coords[offset + 6], coords[offset + 7]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
     * Returns the flatness of the cubic curve specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
     * by the control points stored in the indicated array at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
     * indicated index.  The flatness is the maximum distance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
     * of a control point from the line connecting the end points.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
     * @param coords an array containing coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
     * @param offset the index of <code>coords</code> from which to begin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
     *          getting the end points and control points of the curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
     * @return the flatness of the <code>CubicCurve2D</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
     *          specified by the coordinates in <code>coords</code> at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
     *          the specified offset.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
    public static double getFlatness(double coords[], int offset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
        return getFlatness(coords[offset + 0], coords[offset + 1],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                           coords[offset + 2], coords[offset + 3],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                           coords[offset + 4], coords[offset + 5],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                           coords[offset + 6], coords[offset + 7]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
     * Returns the square of the flatness of this curve.  The flatness is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
     * maximum distance of a control point from the line connecting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
     * end points.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
     * @return the square of the flatness of this curve.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
    public double getFlatnessSq() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        return getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
                             getCtrlX2(), getCtrlY2(), getX2(), getY2());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
     * Returns the flatness of this curve.  The flatness is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
     * maximum distance of a control point from the line connecting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
     * end points.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
     * @return the flatness of this curve.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
    public double getFlatness() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        return getFlatness(getX1(), getY1(), getCtrlX1(), getCtrlY1(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
                           getCtrlX2(), getCtrlY2(), getX2(), getY2());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
     * Subdivides this cubic curve and stores the resulting two
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
     * subdivided curves into the left and right curve parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
     * Either or both of the left and right objects may be the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
     * as this object or null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
     * @param left the cubic curve object for storing for the left or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
     * first half of the subdivided curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
     * @param right the cubic curve object for storing for the right or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
     * second half of the subdivided curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
    public void subdivide(CubicCurve2D left, CubicCurve2D right) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
        subdivide(this, left, right);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
     * Subdivides the cubic curve specified by the <code>src</code> parameter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
     * and stores the resulting two subdivided curves into the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
     * <code>left</code> and <code>right</code> curve parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
     * Either or both of the <code>left</code> and <code>right</code> objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
     * may be the same as the <code>src</code> object or <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
     * @param src the cubic curve to be subdivided
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
     * @param left the cubic curve object for storing the left or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
     * first half of the subdivided curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
     * @param right the cubic curve object for storing the right or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
     * second half of the subdivided curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
    public static void subdivide(CubicCurve2D src,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
                                 CubicCurve2D left,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
                                 CubicCurve2D right) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
        double x1 = src.getX1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
        double y1 = src.getY1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
        double ctrlx1 = src.getCtrlX1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        double ctrly1 = src.getCtrlY1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
        double ctrlx2 = src.getCtrlX2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
        double ctrly2 = src.getCtrlY2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
        double x2 = src.getX2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
        double y2 = src.getY2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
        double centerx = (ctrlx1 + ctrlx2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
        double centery = (ctrly1 + ctrly2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
        ctrlx1 = (x1 + ctrlx1) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        ctrly1 = (y1 + ctrly1) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        ctrlx2 = (x2 + ctrlx2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
        ctrly2 = (y2 + ctrly2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        double ctrlx12 = (ctrlx1 + centerx) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
        double ctrly12 = (ctrly1 + centery) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
        double ctrlx21 = (ctrlx2 + centerx) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
        double ctrly21 = (ctrly2 + centery) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        centerx = (ctrlx12 + ctrlx21) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
        centery = (ctrly12 + ctrly21) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
        if (left != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
            left.setCurve(x1, y1, ctrlx1, ctrly1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
                          ctrlx12, ctrly12, centerx, centery);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
        if (right != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
            right.setCurve(centerx, centery, ctrlx21, ctrly21,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
                           ctrlx2, ctrly2, x2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
     * Subdivides the cubic curve specified by the coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
     * stored in the <code>src</code> array at indices <code>srcoff</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
     * through (<code>srcoff</code>&nbsp;+&nbsp;7) and stores the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
     * resulting two subdivided curves into the two result arrays at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
     * corresponding indices.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
     * Either or both of the <code>left</code> and <code>right</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
     * arrays may be <code>null</code> or a reference to the same array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
     * as the <code>src</code> array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
     * Note that the last point in the first subdivided curve is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
     * same as the first point in the second subdivided curve. Thus,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
     * it is possible to pass the same array for <code>left</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
     * and <code>right</code> and to use offsets, such as <code>rightoff</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
     * equals (<code>leftoff</code> + 6), in order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
     * to avoid allocating extra storage for this common point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
     * @param src the array holding the coordinates for the source curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
     * @param srcoff the offset into the array of the beginning of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
     * the 6 source coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
     * @param left the array for storing the coordinates for the first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
     * half of the subdivided curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
     * @param leftoff the offset into the array of the beginning of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
     * the 6 left coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
     * @param right the array for storing the coordinates for the second
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
     * half of the subdivided curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
     * @param rightoff the offset into the array of the beginning of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
     * the 6 right coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    public static void subdivide(double src[], int srcoff,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                                 double left[], int leftoff,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
                                 double right[], int rightoff) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
        double x1 = src[srcoff + 0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
        double y1 = src[srcoff + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
        double ctrlx1 = src[srcoff + 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
        double ctrly1 = src[srcoff + 3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
        double ctrlx2 = src[srcoff + 4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
        double ctrly2 = src[srcoff + 5];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
        double x2 = src[srcoff + 6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
        double y2 = src[srcoff + 7];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
        if (left != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
            left[leftoff + 0] = x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
            left[leftoff + 1] = y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
        if (right != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
            right[rightoff + 6] = x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
            right[rightoff + 7] = y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
        x1 = (x1 + ctrlx1) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
        y1 = (y1 + ctrly1) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
        x2 = (x2 + ctrlx2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
        y2 = (y2 + ctrly2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
        double centerx = (ctrlx1 + ctrlx2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
        double centery = (ctrly1 + ctrly2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
        ctrlx1 = (x1 + centerx) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        ctrly1 = (y1 + centery) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
        ctrlx2 = (x2 + centerx) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
        ctrly2 = (y2 + centery) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
        centerx = (ctrlx1 + ctrlx2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
        centery = (ctrly1 + ctrly2) / 2.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        if (left != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
            left[leftoff + 2] = x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
            left[leftoff + 3] = y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            left[leftoff + 4] = ctrlx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
            left[leftoff + 5] = ctrly1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
            left[leftoff + 6] = centerx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
            left[leftoff + 7] = centery;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
        if (right != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
            right[rightoff + 0] = centerx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
            right[rightoff + 1] = centery;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
            right[rightoff + 2] = ctrlx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
            right[rightoff + 3] = ctrly2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
            right[rightoff + 4] = x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
            right[rightoff + 5] = y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
     * Solves the cubic whose coefficients are in the <code>eqn</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
     * array and places the non-complex roots back into the same array,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
     * returning the number of roots.  The solved cubic is represented
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
     * by the equation:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
     *     eqn = {c, b, a, d}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
     *     dx^3 + ax^2 + bx + c = 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
     * A return value of -1 is used to distinguish a constant equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
     * that might be always 0 or never 0 from an equation that has no
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
     * zeroes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
     * @param eqn an array containing coefficients for a cubic
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
     * @return the number of roots, or -1 if the equation is a constant.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
    public static int solveCubic(double eqn[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
        return solveCubic(eqn, eqn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
     * Solve the cubic whose coefficients are in the <code>eqn</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
     * array and place the non-complex roots into the <code>res</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
     * array, returning the number of roots.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
     * The cubic solved is represented by the equation:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
     *     eqn = {c, b, a, d}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
     *     dx^3 + ax^2 + bx + c = 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
     * A return value of -1 is used to distinguish a constant equation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
     * which may be always 0 or never 0, from an equation which has no
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
     * zeroes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
     * @param eqn the specified array of coefficients to use to solve
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
     *        the cubic equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
     * @param res the array that contains the non-complex roots
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
     *        resulting from the solution of the cubic equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
     * @return the number of roots, or -1 if the equation is a constant
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
    public static int solveCubic(double eqn[], double res[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
        // From Numerical Recipes, 5.6, Quadratic and Cubic Equations
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
        double d = eqn[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
        if (d == 0.0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
            // The cubic has degenerated to quadratic (or line or ...).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
            return QuadCurve2D.solveQuadratic(eqn, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
        double a = eqn[2] / d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
        double b = eqn[1] / d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
        double c = eqn[0] / d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
        int roots = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
        double Q = (a * a - 3.0 * b) / 9.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
        double R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
        double R2 = R * R;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
        double Q3 = Q * Q * Q;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
        a = a / 3.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
        if (R2 < Q3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
            double theta = Math.acos(R / Math.sqrt(Q3));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
            Q = -2.0 * Math.sqrt(Q);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
            if (res == eqn) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
                // Copy the eqn so that we don't clobber it with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
                // roots.  This is needed so that fixRoots can do its
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
                // work with the original equation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
                eqn = new double[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
                System.arraycopy(res, 0, eqn, 0, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
            res[roots++] = Q * Math.cos(theta / 3.0) - a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
            res[roots++] = Q * Math.cos((theta + Math.PI * 2.0)/ 3.0) - a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
            res[roots++] = Q * Math.cos((theta - Math.PI * 2.0)/ 3.0) - a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
            fixRoots(res, eqn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
            boolean neg = (R < 0.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
            double S = Math.sqrt(R2 - Q3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
            if (neg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
                R = -R;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
            double A = Math.pow(R + S, 1.0 / 3.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
            if (!neg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
                A = -A;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
            double B = (A == 0.0) ? 0.0 : (Q / A);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
            res[roots++] = (A + B) - a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
        return roots;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
     * This pruning step is necessary since solveCubic uses the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
     * cosine function to calculate the roots when there are 3
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
     * of them.  Since the cosine method can have an error of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
     * +/- 1E-14 we need to make sure that we don't make any
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
     * bad decisions due to an error.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
     * If the root is not near one of the endpoints, then we will
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
     * only have a slight inaccuracy in calculating the x intercept
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
     * which will only cause a slightly wrong answer for some
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
     * points very close to the curve.  While the results in that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
     * case are not as accurate as they could be, they are not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
     * disastrously inaccurate either.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
     * On the other hand, if the error happens near one end of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
     * the curve, then our processing to reject values outside
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
     * of the t=[0,1] range will fail and the results of that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
     * failure will be disastrous since for an entire horizontal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
     * range of test points, we will either overcount or undercount
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
     * the crossings and get a wrong answer for all of them, even
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
     * when they are clearly and obviously inside or outside the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
     * curve.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
     * To work around this problem, we try a couple of Newton-Raphson
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
     * iterations to see if the true root is closer to the endpoint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
     * or further away.  If it is further away, then we can stop
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
     * since we know we are on the right side of the endpoint.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
     * we change direction, then either we are now being dragged away
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
     * from the endpoint in which case the first condition will cause
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
     * us to stop, or we have passed the endpoint and are headed back.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
     * In the second case, we simply evaluate the slope at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
     * endpoint itself and place ourselves on the appropriate side
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
     * of it or on it depending on that result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
    private static void fixRoots(double res[], double eqn[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
        final double EPSILON = 1E-5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
        for (int i = 0; i < 3; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
            double t = res[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
            if (Math.abs(t) < EPSILON) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
                res[i] = findZero(t, 0, eqn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
            } else if (Math.abs(t - 1) < EPSILON) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
                res[i] = findZero(t, 1, eqn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
    private static double solveEqn(double eqn[], int order, double t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        double v = eqn[order];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
        while (--order >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
            v = v * t + eqn[order];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
        return v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
    private static double findZero(double t, double target, double eqn[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
        double slopeqn[] = {eqn[1], 2*eqn[2], 3*eqn[3]};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
        double slope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
        double origdelta = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
        double origt = t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
            slope = solveEqn(slopeqn, 2, t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
            if (slope == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
                // At a local minima - must return
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
                return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
            double y = solveEqn(eqn, 3, t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
            if (y == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
                // Found it! - return it
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
                return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
            // assert(slope != 0 && y != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
            double delta = - (y / slope);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
            // assert(delta != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
            if (origdelta == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
                origdelta = delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
            if (t < target) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
                if (delta < 0) return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
            } else if (t > target) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
                if (delta > 0) return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
            } else { /* t == target */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
                return (delta > 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
                        ? (target + java.lang.Double.MIN_VALUE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
                        : (target - java.lang.Double.MIN_VALUE));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
            double newt = t + delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
            if (t == newt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
                // The deltas are so small that we aren't moving...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
                return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
            if (delta * origdelta < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
                // We have reversed our path.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
                int tag = (origt < t
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
                           ? getTag(target, origt, t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
                           : getTag(target, t, origt));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
                if (tag != INSIDE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
                    // Local minima found away from target - return the middle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
                    return (origt + t) / 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
                // Local minima somewhere near target - move to target
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
                // and let the slope determine the resulting t.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
                t = target;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
                t = newt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
    public boolean contains(double x, double y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
        if (!(x * 0.0 + y * 0.0 == 0.0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
            /* Either x or y was infinite or NaN.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
             * A NaN always produces a negative response to any test
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
             * and Infinity values cannot be "inside" any path so
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
             * they should return false as well.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
        // We count the "Y" crossings to determine if the point is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
        // inside the curve bounded by its closing line.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
        double x1 = getX1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
        double y1 = getY1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
        double x2 = getX2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
        double y2 = getY2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
        int crossings =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
            (Curve.pointCrossingsForLine(x, y, x1, y1, x2, y2) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
             Curve.pointCrossingsForCubic(x, y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
                                          x1, y1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
                                          getCtrlX1(), getCtrlY1(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
                                          getCtrlX2(), getCtrlY2(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
                                          x2, y2, 0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
        return ((crossings & 1) == 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
    public boolean contains(Point2D p) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
        return contains(p.getX(), p.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
     * Fill an array with the coefficients of the parametric equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
     * in t, ready for solving against val with solveCubic.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
     * We currently have:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
     *   val = P(t) = C1(1-t)^3 + 3CP1 t(1-t)^2 + 3CP2 t^2(1-t) + C2 t^3
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
     *              = C1 - 3C1t + 3C1t^2 - C1t^3 +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
     *                3CP1t - 6CP1t^2 + 3CP1t^3 +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
     *                3CP2t^2 - 3CP2t^3 +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
     *                C2t^3
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
     *            0 = (C1 - val) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
     *                (3CP1 - 3C1) t +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
     *                (3C1 - 6CP1 + 3CP2) t^2 +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
     *                (C2 - 3CP2 + 3CP1 - C1) t^3
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
     *            0 = C + Bt + At^2 + Dt^3
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
     *     C = C1 - val
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
     *     B = 3*CP1 - 3*C1
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
     *     A = 3*CP2 - 6*CP1 + 3*C1
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
     *     D = C2 - 3*CP2 + 3*CP1 - C1
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
    private static void fillEqn(double eqn[], double val,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
                                double c1, double cp1, double cp2, double c2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
        eqn[0] = c1 - val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
        eqn[1] = (cp1 - c1) * 3.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
        eqn[2] = (cp2 - cp1 - cp1 + c1) * 3.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
        eqn[3] = c2 + (cp1 - cp2) * 3.0 - c1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
     * Evaluate the t values in the first num slots of the vals[] array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
     * and place the evaluated values back into the same array.  Only
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
     * evaluate t values that are within the range <0, 1>, including
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
     * the 0 and 1 ends of the range iff the include0 or include1
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
     * booleans are true.  If an "inflection" equation is handed in,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
     * then any points which represent a point of inflection for that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
     * cubic equation are also ignored.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
    private static int evalCubic(double vals[], int num,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
                                 boolean include0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
                                 boolean include1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
                                 double inflect[],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
                                 double c1, double cp1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
                                 double cp2, double c2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
        int j = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
        for (int i = 0; i < num; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
            double t = vals[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
            if ((include0 ? t >= 0 : t > 0) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
                (include1 ? t <= 1 : t < 1) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
                (inflect == null ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
                 inflect[1] + (2*inflect[2] + 3*inflect[3]*t)*t != 0))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
                double u = 1 - t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
                vals[j++] = c1*u*u*u + 3*cp1*t*u*u + 3*cp2*t*t*u + c2*t*t*t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
        return j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
    private static final int BELOW = -2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
    private static final int LOWEDGE = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
    private static final int INSIDE = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
    private static final int HIGHEDGE = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
    private static final int ABOVE = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
     * Determine where coord lies with respect to the range from
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
     * low to high.  It is assumed that low <= high.  The return
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
     * value is one of the 5 values BELOW, LOWEDGE, INSIDE, HIGHEDGE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
     * or ABOVE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
    private static int getTag(double coord, double low, double high) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
        if (coord <= low) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
            return (coord < low ? BELOW : LOWEDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
        if (coord >= high) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
            return (coord > high ? ABOVE : HIGHEDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
        return INSIDE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
     * Determine if the pttag represents a coordinate that is already
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
     * in its test range, or is on the border with either of the two
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
     * opttags representing another coordinate that is "towards the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
     * inside" of that test range.  In other words, are either of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
     * two "opt" points "drawing the pt inward"?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
    private static boolean inwards(int pttag, int opt1tag, int opt2tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
        switch (pttag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
        case BELOW:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
        case ABOVE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
        case LOWEDGE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
            return (opt1tag >= INSIDE || opt2tag >= INSIDE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
        case INSIDE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
        case HIGHEDGE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
            return (opt1tag <= INSIDE || opt2tag <= INSIDE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
    public boolean intersects(double x, double y, double w, double h) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
        // Trivially reject non-existant rectangles
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
        if (w <= 0 || h <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
        // Trivially accept if either endpoint is inside the rectangle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
        // (not on its border since it may end there and not go inside)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
        // Record where they lie with respect to the rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
        //     -1 => left, 0 => inside, 1 => right
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
        double x1 = getX1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
        double y1 = getY1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
        int x1tag = getTag(x1, x, x+w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
        int y1tag = getTag(y1, y, y+h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
        if (x1tag == INSIDE && y1tag == INSIDE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
        double x2 = getX2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
        double y2 = getY2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
        int x2tag = getTag(x2, x, x+w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
        int y2tag = getTag(y2, y, y+h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
        if (x2tag == INSIDE && y2tag == INSIDE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
        double ctrlx1 = getCtrlX1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
        double ctrly1 = getCtrlY1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
        double ctrlx2 = getCtrlX2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
        double ctrly2 = getCtrlY2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
        int ctrlx1tag = getTag(ctrlx1, x, x+w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
        int ctrly1tag = getTag(ctrly1, y, y+h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
        int ctrlx2tag = getTag(ctrlx2, x, x+w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
        int ctrly2tag = getTag(ctrly2, y, y+h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
        // Trivially reject if all points are entirely to one side of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
        // the rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
        if (x1tag < INSIDE && x2tag < INSIDE &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
            ctrlx1tag < INSIDE && ctrlx2tag < INSIDE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
            return false;       // All points left
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
        if (y1tag < INSIDE && y2tag < INSIDE &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
            ctrly1tag < INSIDE && ctrly2tag < INSIDE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
            return false;       // All points above
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
        if (x1tag > INSIDE && x2tag > INSIDE &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
            ctrlx1tag > INSIDE && ctrlx2tag > INSIDE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
            return false;       // All points right
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
        if (y1tag > INSIDE && y2tag > INSIDE &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
            ctrly1tag > INSIDE && ctrly2tag > INSIDE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
            return false;       // All points below
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
        // Test for endpoints on the edge where either the segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
        // or the curve is headed "inwards" from them
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
        // Note: These tests are a superset of the fast endpoint tests
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
        //       above and thus repeat those tests, but take more time
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
        //       and cover more cases
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
        if (inwards(x1tag, x2tag, ctrlx1tag) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
            inwards(y1tag, y2tag, ctrly1tag))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
            // First endpoint on border with either edge moving inside
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
        if (inwards(x2tag, x1tag, ctrlx2tag) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
            inwards(y2tag, y1tag, ctrly2tag))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
            // Second endpoint on border with either edge moving inside
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
        // Trivially accept if endpoints span directly across the rectangle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
        boolean xoverlap = (x1tag * x2tag <= 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
        boolean yoverlap = (y1tag * y2tag <= 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
        if (x1tag == INSIDE && x2tag == INSIDE && yoverlap) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
        if (y1tag == INSIDE && y2tag == INSIDE && xoverlap) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
        // We now know that both endpoints are outside the rectangle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
        // but the 4 points are not all on one side of the rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
        // Therefore the curve cannot be contained inside the rectangle,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
        // but the rectangle might be contained inside the curve, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
        // the curve might intersect the boundary of the rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
        double[] eqn = new double[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
        double[] res = new double[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
        if (!yoverlap) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
            // Both y coordinates for the closing segment are above or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
            // below the rectangle which means that we can only intersect
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
            // if the curve crosses the top (or bottom) of the rectangle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
            // in more than one place and if those crossing locations
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
            // span the horizontal range of the rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
            fillEqn(eqn, (y1tag < INSIDE ? y : y+h), y1, ctrly1, ctrly2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
            int num = solveCubic(eqn, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
            num = evalCubic(res, num, true, true, null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
                            x1, ctrlx1, ctrlx2, x2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
            // odd counts imply the crossing was out of [0,1] bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
            // otherwise there is no way for that part of the curve to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
            // "return" to meet its endpoint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
            return (num == 2 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
                    getTag(res[0], x, x+w) * getTag(res[1], x, x+w) <= 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
        // Y ranges overlap.  Now we examine the X ranges
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
        if (!xoverlap) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
            // Both x coordinates for the closing segment are left of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
            // or right of the rectangle which means that we can only
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
            // intersect if the curve crosses the left (or right) edge
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
            // of the rectangle in more than one place and if those
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
            // crossing locations span the vertical range of the rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
            fillEqn(eqn, (x1tag < INSIDE ? x : x+w), x1, ctrlx1, ctrlx2, x2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
            int num = solveCubic(eqn, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
            num = evalCubic(res, num, true, true, null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
                            y1, ctrly1, ctrly2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
            // odd counts imply the crossing was out of [0,1] bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
            // otherwise there is no way for that part of the curve to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
            // "return" to meet its endpoint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
            return (num == 2 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
                    getTag(res[0], y, y+h) * getTag(res[1], y, y+h) <= 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
        // The X and Y ranges of the endpoints overlap the X and Y
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
        // ranges of the rectangle, now find out how the endpoint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
        // line segment intersects the Y range of the rectangle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
        double dx = x2 - x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
        double dy = y2 - y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
        double k = y2 * x1 - x2 * y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
        int c1tag, c2tag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
        if (y1tag == INSIDE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
            c1tag = x1tag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
            c1tag = getTag((k + dx * (y1tag < INSIDE ? y : y+h)) / dy, x, x+w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
        if (y2tag == INSIDE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
            c2tag = x2tag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
            c2tag = getTag((k + dx * (y2tag < INSIDE ? y : y+h)) / dy, x, x+w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
        // If the part of the line segment that intersects the Y range
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
        // of the rectangle crosses it horizontally - trivially accept
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
        if (c1tag * c2tag <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
        // Now we know that both the X and Y ranges intersect and that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
        // the endpoint line segment does not directly cross the rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
        // We can almost treat this case like one of the cases above
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
        // where both endpoints are to one side, except that we may
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
        // get one or three intersections of the curve with the vertical
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
        // side of the rectangle.  This is because the endpoint segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
        // accounts for the other intersection in an even pairing.  Thus,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
        // with the endpoint crossing we end up with 2 or 4 total crossings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
        // (Remember there is overlap in both the X and Y ranges which
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
        //  means that the segment itself must cross at least one vertical
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
        //  edge of the rectangle - in particular, the "near vertical side"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
        //  - leaving an odd number of intersections for the curve.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
        // Now we calculate the y tags of all the intersections on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
        // "near vertical side" of the rectangle.  We will have one with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
        // the endpoint segment, and one or three with the curve.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
        // any pair of those vertical intersections overlap the Y range
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
        // of the rectangle, we have an intersection.  Otherwise, we don't.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
        // c1tag = vertical intersection class of the endpoint segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
        // Choose the y tag of the endpoint that was not on the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
        // side of the rectangle as the subsegment calculated above.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
        // Note that we can "steal" the existing Y tag of that endpoint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
        // since it will be provably the same as the vertical intersection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
        c1tag = ((c1tag * x1tag <= 0) ? y1tag : y2tag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
        // Now we have to calculate an array of solutions of the curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
        // with the "near vertical side" of the rectangle.  Then we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
        // need to sort the tags and do a pairwise range test to see
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
        // if either of the pairs of crossings spans the Y range of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
        // the rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
        // Note that the c2tag can still tell us which vertical edge
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
        // to test against.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
        fillEqn(eqn, (c2tag < INSIDE ? x : x+w), x1, ctrlx1, ctrlx2, x2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
        int num = solveCubic(eqn, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
        num = evalCubic(res, num, true, true, null, y1, ctrly1, ctrly2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
        // Now put all of the tags into a bucket and sort them.  There
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
        // is an intersection iff one of the pairs of tags "spans" the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
        // Y range of the rectangle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
        int tags[] = new int[num+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
        for (int i = 0; i < num; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
            tags[i] = getTag(res[i], y, y+h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
        tags[num] = c1tag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
        Arrays.sort(tags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
        return ((num >= 1 && tags[0] * tags[1] <= 0) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
                (num >= 3 && tags[2] * tags[3] <= 0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
    public boolean intersects(Rectangle2D r) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
    public boolean contains(double x, double y, double w, double h) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
        if (w <= 0 || h <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
        // Assertion: Cubic curves closed by connecting their
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
        // endpoints form either one or two convex halves with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
        // the closing line segment as an edge of both sides.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
        if (!(contains(x, y) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
              contains(x + w, y) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
              contains(x + w, y + h) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
              contains(x, y + h))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
        // Either the rectangle is entirely inside one of the convex
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
        // halves or it crosses from one to the other, in which case
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
        // it must intersect the closing line segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
        Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
        return !rect.intersectsLine(getX1(), getY1(), getX2(), getY2());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
    public boolean contains(Rectangle2D r) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
    public Rectangle getBounds() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
        return getBounds2D().getBounds();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1638
     * Returns an iteration object that defines the boundary of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
     * shape.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
     * The iterator for this class is not multi-threaded safe,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
     * which means that this <code>CubicCurve2D</code> class does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
     * guarantee that modifications to the geometry of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
     * <code>CubicCurve2D</code> object do not affect any iterations of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
     * that geometry that are already in process.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
     * @param at an optional <code>AffineTransform</code> to be applied to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
     * coordinates as they are returned in the iteration, or <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
     * if untransformed coordinates are desired
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
     * @return    the <code>PathIterator</code> object that returns the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
     *          geometry of the outline of this <code>CubicCurve2D</code>, one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
     *          segment at a time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
    public PathIterator getPathIterator(AffineTransform at) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
        return new CubicIterator(this, at);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
     * Return an iteration object that defines the boundary of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
     * flattened shape.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
     * The iterator for this class is not multi-threaded safe,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
     * which means that this <code>CubicCurve2D</code> class does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
     * guarantee that modifications to the geometry of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
     * <code>CubicCurve2D</code> object do not affect any iterations of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
     * that geometry that are already in process.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
     * @param at an optional <code>AffineTransform</code> to be applied to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
     * coordinates as they are returned in the iteration, or <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
     * if untransformed coordinates are desired
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
     * @param flatness the maximum amount that the control points
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
     * for a given curve can vary from colinear before a subdivided
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
     * curve is replaced by a straight line connecting the end points
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
     * @return    the <code>PathIterator</code> object that returns the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
     * geometry of the outline of this <code>CubicCurve2D</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
     * one segment at a time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
    public PathIterator getPathIterator(AffineTransform at, double flatness) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
        return new FlatteningPathIterator(getPathIterator(at), flatness);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
     * Creates a new object of the same class as this object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
     * @return     a clone of this instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
     * @exception  OutOfMemoryError            if there is not enough memory.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
     * @see        java.lang.Cloneable
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
     * @since      1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
    public Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
            return super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
        } catch (CloneNotSupportedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
            // this shouldn't happen, since we are Cloneable
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
            throw new InternalError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
}