1 /* 2 * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt; 27 28 import java.awt.geom.AffineTransform; 29 import java.awt.geom.Point2D; 30 import java.awt.geom.Rectangle2D; 31 import java.awt.image.ColorModel; 32 import java.beans.ConstructorProperties; 33 34 /** 35 * The {@code RadialGradientPaint} class provides a way to fill a shape with 36 * a circular radial color gradient pattern. The user may specify 2 or more 37 * gradient colors, and this paint will provide an interpolation between 38 * each color. 39 * <p> 40 * The user must specify the circle controlling the gradient pattern, 41 * which is described by a center point and a radius. The user can also 42 * specify a separate focus point within that circle, which controls the 43 * location of the first color of the gradient. By default the focus is 44 * set to be the center of the circle. 45 * <p> 46 * This paint will map the first color of the gradient to the focus point, 47 * and the last color to the perimeter of the circle, interpolating 48 * smoothly for any in-between colors specified by the user. Any line drawn 49 * from the focus point to the circumference will thus span all the gradient 50 * colors. 51 * <p> 52 * Specifying a focus point outside of the radius of the circle will cause 53 * the rings of the gradient pattern to be centered on the point just inside 54 * the edge of the circle in the direction of the focus point. 55 * The rendering will internally use this modified location as if it were 56 * the specified focus point. 57 * <p> 58 * The user must provide an array of floats specifying how to distribute the 59 * colors along the gradient. These values should range from 0.0 to 1.0 and 60 * act like keyframes along the gradient (they mark where the gradient should 61 * be exactly a particular color). 62 * <p> 63 * In the event that the user does not set the first keyframe value equal 64 * to 0 and/or the last keyframe value equal to 1, keyframes will be created 65 * at these positions and the first and last colors will be replicated there. 66 * So, if a user specifies the following arrays to construct a gradient:<br> 67 * <pre> 68 * {Color.BLUE, Color.RED}, {.3f, .7f} 69 * </pre> 70 * this will be converted to a gradient with the following keyframes:<br> 71 * <pre> 72 * {Color.BLUE, Color.BLUE, Color.RED, Color.RED}, {0f, .3f, .7f, 1f} 73 * </pre> 74 * 75 * <p> 76 * The user may also select what action the {@code RadialGradientPaint} object 77 * takes when it is filling the space outside the circle's radius by 78 * setting {@code CycleMethod} to either {@code REFLECTION} or {@code REPEAT}. 79 * The gradient color proportions are equal for any particular line drawn 80 * from the focus point. The following figure shows that the distance AB 81 * is equal to the distance BC, and the distance AD is equal to the distance DE. 82 * <center> 83 * <img src = "doc-files/RadialGradientPaint-3.png" alt="image showing the 84 * distance AB=BC, and AD=DE"> 85 * </center> 86 * If the gradient and graphics rendering transforms are uniformly scaled and 87 * the user sets the focus so that it coincides with the center of the circle, 88 * the gradient color proportions are equal for any line drawn from the center. 89 * The following figure shows the distances AB, BC, AD, and DE. They are all equal. 90 * <center> 91 * <img src = "doc-files/RadialGradientPaint-4.png" alt="image showing the 92 * distance of AB, BC, AD, and DE are all equal"> 93 * </center> 94 * Note that some minor variations in distances may occur due to sampling at 95 * the granularity of a pixel. 96 * If no cycle method is specified, {@code NO_CYCLE} will be chosen by 97 * default, which means the last keyframe color will be used to fill the 98 * remaining area. 99 * <p> 100 * The colorSpace parameter allows the user to specify in which colorspace 101 * the interpolation should be performed, default sRGB or linearized RGB. 102 * 103 * <p> 104 * The following code demonstrates typical usage of 105 * {@code RadialGradientPaint}, where the center and focus points are 106 * the same: 107 * <pre> 108 * Point2D center = new Point2D.Float(50, 50); 109 * float radius = 25; 110 * float[] dist = {0.0f, 0.2f, 1.0f}; 111 * Color[] colors = {Color.RED, Color.WHITE, Color.BLUE}; 112 * RadialGradientPaint p = 113 * new RadialGradientPaint(center, radius, dist, colors); 114 * </pre> 115 * 116 * <p> 117 * This image demonstrates the example code above, with default 118 * (centered) focus for each of the three cycle methods: 119 * <center> 120 * <img src = "doc-files/RadialGradientPaint-1.png" alt="image showing the 121 * output of the sameple code"> 122 * </center> 123 * 124 * <p> 125 * It is also possible to specify a non-centered focus point, as 126 * in the following code: 127 * <pre> 128 * Point2D center = new Point2D.Float(50, 50); 129 * float radius = 25; 130 * Point2D focus = new Point2D.Float(40, 40); 131 * float[] dist = {0.0f, 0.2f, 1.0f}; 132 * Color[] colors = {Color.RED, Color.WHITE, Color.BLUE}; 133 * RadialGradientPaint p = 134 * new RadialGradientPaint(center, radius, focus, 135 * dist, colors, 136 * CycleMethod.NO_CYCLE); 137 * </pre> 138 * 139 * <p> 140 * This image demonstrates the previous example code, with non-centered 141 * focus for each of the three cycle methods: 142 * <center> 143 * <img src = "doc-files/RadialGradientPaint-2.png" alt="image showing the 144 * output of the sample code"> 145 * </center> 146 * 147 * @see java.awt.Paint 148 * @see java.awt.Graphics2D#setPaint 149 * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans 150 * @since 1.6 151 */ 152 public final class RadialGradientPaint extends MultipleGradientPaint { 153 154 /** Focus point which defines the 0% gradient stop X coordinate. */ 155 private final Point2D focus; 156 157 /** Center of the circle defining the 100% gradient stop X coordinate. */ 158 private final Point2D center; 159 160 /** Radius of the outermost circle defining the 100% gradient stop. */ 161 private final float radius; 162 163 /** 164 * Constructs a {@code RadialGradientPaint} with a default 165 * {@code NO_CYCLE} repeating method and {@code SRGB} color space, 166 * using the center as the focus point. 167 * 168 * @param cx the X coordinate in user space of the center point of the 169 * circle defining the gradient. The last color of the 170 * gradient is mapped to the perimeter of this circle. 171 * @param cy the Y coordinate in user space of the center point of the 172 * circle defining the gradient. The last color of the 173 * gradient is mapped to the perimeter of this circle. 174 * @param radius the radius of the circle defining the extents of the 175 * color gradient 176 * @param fractions numbers ranging from 0.0 to 1.0 specifying the 177 * distribution of colors along the gradient 178 * @param colors array of colors to use in the gradient. The first color 179 * is used at the focus point, the last color around the 180 * perimeter of the circle. 181 * 182 * @throws NullPointerException 183 * if {@code fractions} array is null, 184 * or {@code colors} array is null 185 * @throws IllegalArgumentException 186 * if {@code radius} is non-positive, 187 * or {@code fractions.length != colors.length}, 188 * or {@code colors} is less than 2 in size, 189 * or a {@code fractions} value is less than 0.0 or greater than 1.0, 190 * or the {@code fractions} are not provided in strictly increasing order 191 */ 192 public RadialGradientPaint(float cx, float cy, float radius, 193 float[] fractions, Color[] colors) 194 { 195 this(cx, cy, 196 radius, 197 cx, cy, 198 fractions, 199 colors, 200 CycleMethod.NO_CYCLE); 201 } 202 203 /** 204 * Constructs a {@code RadialGradientPaint} with a default 205 * {@code NO_CYCLE} repeating method and {@code SRGB} color space, 206 * using the center as the focus point. 207 * 208 * @param center the center point, in user space, of the circle defining 209 * the gradient 210 * @param radius the radius of the circle defining the extents of the 211 * color gradient 212 * @param fractions numbers ranging from 0.0 to 1.0 specifying the 213 * distribution of colors along the gradient 214 * @param colors array of colors to use in the gradient. The first color 215 * is used at the focus point, the last color around the 216 * perimeter of the circle. 217 * 218 * @throws NullPointerException 219 * if {@code center} point is null, 220 * or {@code fractions} array is null, 221 * or {@code colors} array is null 222 * @throws IllegalArgumentException 223 * if {@code radius} is non-positive, 224 * or {@code fractions.length != colors.length}, 225 * or {@code colors} is less than 2 in size, 226 * or a {@code fractions} value is less than 0.0 or greater than 1.0, 227 * or the {@code fractions} are not provided in strictly increasing order 228 */ 229 public RadialGradientPaint(Point2D center, float radius, 230 float[] fractions, Color[] colors) 231 { 232 this(center, 233 radius, 234 center, 235 fractions, 236 colors, 237 CycleMethod.NO_CYCLE); 238 } 239 240 /** 241 * Constructs a {@code RadialGradientPaint} with a default 242 * {@code SRGB} color space, using the center as the focus point. 243 * 244 * @param cx the X coordinate in user space of the center point of the 245 * circle defining the gradient. The last color of the 246 * gradient is mapped to the perimeter of this circle. 247 * @param cy the Y coordinate in user space of the center point of the 248 * circle defining the gradient. The last color of the 249 * gradient is mapped to the perimeter of this circle. 250 * @param radius the radius of the circle defining the extents of the 251 * color gradient 252 * @param fractions numbers ranging from 0.0 to 1.0 specifying the 253 * distribution of colors along the gradient 254 * @param colors array of colors to use in the gradient. The first color 255 * is used at the focus point, the last color around the 256 * perimeter of the circle. 257 * @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT}, 258 * or {@code REPEAT} 259 * 260 * @throws NullPointerException 261 * if {@code fractions} array is null, 262 * or {@code colors} array is null, 263 * or {@code cycleMethod} is null 264 * @throws IllegalArgumentException 265 * if {@code radius} is non-positive, 266 * or {@code fractions.length != colors.length}, 267 * or {@code colors} is less than 2 in size, 268 * or a {@code fractions} value is less than 0.0 or greater than 1.0, 269 * or the {@code fractions} are not provided in strictly increasing order 270 */ 271 public RadialGradientPaint(float cx, float cy, float radius, 272 float[] fractions, Color[] colors, 273 CycleMethod cycleMethod) 274 { 275 this(cx, cy, 276 radius, 277 cx, cy, 278 fractions, 279 colors, 280 cycleMethod); 281 } 282 283 /** 284 * Constructs a {@code RadialGradientPaint} with a default 285 * {@code SRGB} color space, using the center as the focus point. 286 * 287 * @param center the center point, in user space, of the circle defining 288 * the gradient 289 * @param radius the radius of the circle defining the extents of the 290 * color gradient 291 * @param fractions numbers ranging from 0.0 to 1.0 specifying the 292 * distribution of colors along the gradient 293 * @param colors array of colors to use in the gradient. The first color 294 * is used at the focus point, the last color around the 295 * perimeter of the circle. 296 * @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT}, 297 * or {@code REPEAT} 298 * 299 * @throws NullPointerException 300 * if {@code center} point is null, 301 * or {@code fractions} array is null, 302 * or {@code colors} array is null, 303 * or {@code cycleMethod} is null 304 * @throws IllegalArgumentException 305 * if {@code radius} is non-positive, 306 * or {@code fractions.length != colors.length}, 307 * or {@code colors} is less than 2 in size, 308 * or a {@code fractions} value is less than 0.0 or greater than 1.0, 309 * or the {@code fractions} are not provided in strictly increasing order 310 */ 311 public RadialGradientPaint(Point2D center, float radius, 312 float[] fractions, Color[] colors, 313 CycleMethod cycleMethod) 314 { 315 this(center, 316 radius, 317 center, 318 fractions, 319 colors, 320 cycleMethod); 321 } 322 323 /** 324 * Constructs a {@code RadialGradientPaint} with a default 325 * {@code SRGB} color space. 326 * 327 * @param cx the X coordinate in user space of the center point of the 328 * circle defining the gradient. The last color of the 329 * gradient is mapped to the perimeter of this circle. 330 * @param cy the Y coordinate in user space of the center point of the 331 * circle defining the gradient. The last color of the 332 * gradient is mapped to the perimeter of this circle. 333 * @param radius the radius of the circle defining the extents of the 334 * color gradient 335 * @param fx the X coordinate of the point in user space to which the 336 * first color is mapped 337 * @param fy the Y coordinate of the point in user space to which the 338 * first color is mapped 339 * @param fractions numbers ranging from 0.0 to 1.0 specifying the 340 * distribution of colors along the gradient 341 * @param colors array of colors to use in the gradient. The first color 342 * is used at the focus point, the last color around the 343 * perimeter of the circle. 344 * @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT}, 345 * or {@code REPEAT} 346 * 347 * @throws NullPointerException 348 * if {@code fractions} array is null, 349 * or {@code colors} array is null, 350 * or {@code cycleMethod} is null 351 * @throws IllegalArgumentException 352 * if {@code radius} is non-positive, 353 * or {@code fractions.length != colors.length}, 354 * or {@code colors} is less than 2 in size, 355 * or a {@code fractions} value is less than 0.0 or greater than 1.0, 356 * or the {@code fractions} are not provided in strictly increasing order 357 */ 358 public RadialGradientPaint(float cx, float cy, float radius, 359 float fx, float fy, 360 float[] fractions, Color[] colors, 361 CycleMethod cycleMethod) 362 { 363 this(new Point2D.Float(cx, cy), 364 radius, 365 new Point2D.Float(fx, fy), 366 fractions, 367 colors, 368 cycleMethod); 369 } 370 371 /** 372 * Constructs a {@code RadialGradientPaint} with a default 373 * {@code SRGB} color space. 374 * 375 * @param center the center point, in user space, of the circle defining 376 * the gradient. The last color of the gradient is mapped 377 * to the perimeter of this circle. 378 * @param radius the radius of the circle defining the extents of the color 379 * gradient 380 * @param focus the point in user space to which the first color is mapped 381 * @param fractions numbers ranging from 0.0 to 1.0 specifying the 382 * distribution of colors along the gradient 383 * @param colors array of colors to use in the gradient. The first color 384 * is used at the focus point, the last color around the 385 * perimeter of the circle. 386 * @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT}, 387 * or {@code REPEAT} 388 * 389 * @throws NullPointerException 390 * if one of the points is null, 391 * or {@code fractions} array is null, 392 * or {@code colors} array is null, 393 * or {@code cycleMethod} is null 394 * @throws IllegalArgumentException 395 * if {@code radius} is non-positive, 396 * or {@code fractions.length != colors.length}, 397 * or {@code colors} is less than 2 in size, 398 * or a {@code fractions} value is less than 0.0 or greater than 1.0, 399 * or the {@code fractions} are not provided in strictly increasing order 400 */ 401 public RadialGradientPaint(Point2D center, float radius, 402 Point2D focus, 403 float[] fractions, Color[] colors, 404 CycleMethod cycleMethod) 405 { 406 this(center, 407 radius, 408 focus, 409 fractions, 410 colors, 411 cycleMethod, 412 ColorSpaceType.SRGB, 413 new AffineTransform()); 414 } 415 416 /** 417 * Constructs a {@code RadialGradientPaint}. 418 * 419 * @param center the center point in user space of the circle defining the 420 * gradient. The last color of the gradient is mapped to 421 * the perimeter of this circle. 422 * @param radius the radius of the circle defining the extents of the 423 * color gradient 424 * @param focus the point in user space to which the first color is mapped 425 * @param fractions numbers ranging from 0.0 to 1.0 specifying the 426 * distribution of colors along the gradient 427 * @param colors array of colors to use in the gradient. The first color 428 * is used at the focus point, the last color around the 429 * perimeter of the circle. 430 * @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT}, 431 * or {@code REPEAT} 432 * @param colorSpace which color space to use for interpolation, 433 * either {@code SRGB} or {@code LINEAR_RGB} 434 * @param gradientTransform transform to apply to the gradient 435 * 436 * @throws NullPointerException 437 * if one of the points is null, 438 * or {@code fractions} array is null, 439 * or {@code colors} array is null, 440 * or {@code cycleMethod} is null, 441 * or {@code colorSpace} is null, 442 * or {@code gradientTransform} is null 443 * @throws IllegalArgumentException 444 * if {@code radius} is non-positive, 445 * or {@code fractions.length != colors.length}, 446 * or {@code colors} is less than 2 in size, 447 * or a {@code fractions} value is less than 0.0 or greater than 1.0, 448 * or the {@code fractions} are not provided in strictly increasing order 449 */ 450 @ConstructorProperties({ "centerPoint", "radius", "focusPoint", "fractions", "colors", "cycleMethod", "colorSpace", "transform" }) 451 public RadialGradientPaint(Point2D center, 452 float radius, 453 Point2D focus, 454 float[] fractions, Color[] colors, 455 CycleMethod cycleMethod, 456 ColorSpaceType colorSpace, 457 AffineTransform gradientTransform) 458 { 459 super(fractions, colors, cycleMethod, colorSpace, gradientTransform); 460 461 // check input arguments 462 if (center == null) { 463 throw new NullPointerException("Center point must be non-null"); 464 } 465 466 if (focus == null) { 467 throw new NullPointerException("Focus point must be non-null"); 468 } 469 470 if (radius <= 0) { 471 throw new IllegalArgumentException("Radius must be greater " + 472 "than zero"); 473 } 474 475 // copy parameters 476 this.center = new Point2D.Double(center.getX(), center.getY()); 477 this.focus = new Point2D.Double(focus.getX(), focus.getY()); 478 this.radius = radius; 479 } 480 481 /** 482 * Constructs a {@code RadialGradientPaint} with a default 483 * {@code SRGB} color space. 484 * The gradient circle of the {@code RadialGradientPaint} is defined 485 * by the given bounding box. 486 * <p> 487 * This constructor is a more convenient way to express the 488 * following (equivalent) code:<br> 489 * 490 * <pre> 491 * double gw = gradientBounds.getWidth(); 492 * double gh = gradientBounds.getHeight(); 493 * double cx = gradientBounds.getCenterX(); 494 * double cy = gradientBounds.getCenterY(); 495 * Point2D center = new Point2D.Double(cx, cy); 496 * 497 * AffineTransform gradientTransform = new AffineTransform(); 498 * gradientTransform.translate(cx, cy); 499 * gradientTransform.scale(gw / 2, gh / 2); 500 * gradientTransform.translate(-cx, -cy); 501 * 502 * RadialGradientPaint gp = 503 * new RadialGradientPaint(center, 1.0f, center, 504 * fractions, colors, 505 * cycleMethod, 506 * ColorSpaceType.SRGB, 507 * gradientTransform); 508 * </pre> 509 * 510 * @param gradientBounds the bounding box, in user space, of the circle 511 * defining the outermost extent of the gradient 512 * @param fractions numbers ranging from 0.0 to 1.0 specifying the 513 * distribution of colors along the gradient 514 * @param colors array of colors to use in the gradient. The first color 515 * is used at the focus point, the last color around the 516 * perimeter of the circle. 517 * @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT}, 518 * or {@code REPEAT} 519 * 520 * @throws NullPointerException 521 * if {@code gradientBounds} is null, 522 * or {@code fractions} array is null, 523 * or {@code colors} array is null, 524 * or {@code cycleMethod} is null 525 * @throws IllegalArgumentException 526 * if {@code gradientBounds} is empty, 527 * or {@code fractions.length != colors.length}, 528 * or {@code colors} is less than 2 in size, 529 * or a {@code fractions} value is less than 0.0 or greater than 1.0, 530 * or the {@code fractions} are not provided in strictly increasing order 531 */ 532 public RadialGradientPaint(Rectangle2D gradientBounds, 533 float[] fractions, Color[] colors, 534 CycleMethod cycleMethod) 535 { 536 // gradient center/focal point is the center of the bounding box, 537 // radius is set to 1.0, and then we set a scale transform 538 // to achieve an elliptical gradient defined by the bounding box 539 this(new Point2D.Double(gradientBounds.getCenterX(), 540 gradientBounds.getCenterY()), 541 1.0f, 542 new Point2D.Double(gradientBounds.getCenterX(), 543 gradientBounds.getCenterY()), 544 fractions, 545 colors, 546 cycleMethod, 547 ColorSpaceType.SRGB, 548 createGradientTransform(gradientBounds)); 549 550 if (gradientBounds.isEmpty()) { 551 throw new IllegalArgumentException("Gradient bounds must be " + 552 "non-empty"); 553 } 554 } 555 556 private static AffineTransform createGradientTransform(Rectangle2D r) { 557 double cx = r.getCenterX(); 558 double cy = r.getCenterY(); 559 AffineTransform xform = AffineTransform.getTranslateInstance(cx, cy); 560 xform.scale(r.getWidth()/2, r.getHeight()/2); 561 xform.translate(-cx, -cy); 562 return xform; 563 } 564 565 /** 566 * Creates and returns a {@link PaintContext} used to 567 * generate a circular radial color gradient pattern. 568 * See the description of the {@link Paint#createContext createContext} method 569 * for information on null parameter handling. 570 * 571 * @param cm the preferred {@link ColorModel} which represents the most convenient 572 * format for the caller to receive the pixel data, or {@code null} 573 * if there is no preference. 574 * @param deviceBounds the device space bounding box 575 * of the graphics primitive being rendered. 576 * @param userBounds the user space bounding box 577 * of the graphics primitive being rendered. 578 * @param transform the {@link AffineTransform} from user 579 * space into device space. 580 * @param hints the set of hints that the context object can use to 581 * choose between rendering alternatives. 582 * @return the {@code PaintContext} for 583 * generating color patterns. 584 * @see Paint 585 * @see PaintContext 586 * @see ColorModel 587 * @see Rectangle 588 * @see Rectangle2D 589 * @see AffineTransform 590 * @see RenderingHints 591 */ 592 public PaintContext createContext(ColorModel cm, 593 Rectangle deviceBounds, 594 Rectangle2D userBounds, 595 AffineTransform transform, 596 RenderingHints hints) 597 { 598 // avoid modifying the user's transform... 599 transform = new AffineTransform(transform); 600 // incorporate the gradient transform 601 transform.concatenate(gradientTransform); 602 603 return new RadialGradientPaintContext(this, cm, 604 deviceBounds, userBounds, 605 transform, hints, 606 (float)center.getX(), 607 (float)center.getY(), 608 radius, 609 (float)focus.getX(), 610 (float)focus.getY(), 611 fractions, colors, 612 cycleMethod, colorSpace); 613 } 614 615 /** 616 * Returns a copy of the center point of the radial gradient. 617 * 618 * @return a {@code Point2D} object that is a copy of the center point 619 */ 620 public Point2D getCenterPoint() { 621 return new Point2D.Double(center.getX(), center.getY()); 622 } 623 624 /** 625 * Returns a copy of the focus point of the radial gradient. 626 * Note that if the focus point specified when the radial gradient 627 * was constructed lies outside of the radius of the circle, this 628 * method will still return the original focus point even though 629 * the rendering may center the rings of color on a different 630 * point that lies inside the radius. 631 * 632 * @return a {@code Point2D} object that is a copy of the focus point 633 */ 634 public Point2D getFocusPoint() { 635 return new Point2D.Double(focus.getX(), focus.getY()); 636 } 637 638 /** 639 * Returns the radius of the circle defining the radial gradient. 640 * 641 * @return the radius of the circle defining the radial gradient 642 */ 643 public float getRadius() { 644 return radius; 645 } 646 }