001: /*
002: * Copyright (c) 2001-2006 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.animation.renderer;
032:
033: import java.awt.Color;
034: import java.awt.Graphics2D;
035: import java.awt.Shape;
036: import java.awt.geom.GeneralPath;
037: import java.awt.geom.Point2D;
038: import java.util.Random;
039:
040: import com.jgoodies.animation.AnimationRenderer;
041:
042: /**
043: * Paints two colored and often translucent fans that can be rotated.
044: *
045: * @author Karsten Lentzsch
046: * @version $Revision: 1.1 $
047: *
048: * @see com.jgoodies.animation.animations.FanAnimation
049: * @see com.jgoodies.animation.components.FanComponent
050: */
051: public final class FanRenderer implements AnimationRenderer {
052:
053: private static final Random random = new Random(System
054: .currentTimeMillis());
055:
056: private final Triangle[] triangles;
057:
058: private Point2D origin;
059: private double rotation;
060:
061: public FanRenderer(Triangle[] triangles) {
062: this .triangles = triangles;
063: }
064:
065: public FanRenderer(int triangleCount, Color baseColor) {
066: this (createSectors(triangleCount, baseColor));
067: }
068:
069: public static Triangle[] createSectors(int count, Color baseColor) {
070: Triangle[] result = new Triangle[count];
071: double sectorAngle = Math.PI * 2 / count;
072:
073: for (int i = 0; i < count; i++) {
074: double rotation = i * sectorAngle
075: + (random.nextFloat() - 0.5) * Math.PI / 10;
076: double angle = sectorAngle
077: * (0.2 + random.nextFloat() * 0.4);
078: result[i] = new Triangle(rotation, angle,
079: nextColor(baseColor));
080: }
081: return result;
082: }
083:
084: private static Color nextColor(Color baseColor) {
085: float[] hsb = new float[3];
086: Color.RGBtoHSB(baseColor.getRed(), baseColor.getGreen(),
087: baseColor.getBlue(), hsb);
088: float brightness = 0.8f + random.nextFloat() * 0.2f;
089: return Color.getHSBColor(hsb[0], hsb[1], brightness);
090: }
091:
092: public Point2D getOrigin() {
093: return origin;
094: }
095:
096: public void setOrigin(Point2D origin) {
097: this .origin = origin;
098: }
099:
100: public double getRotation() {
101: return rotation;
102: }
103:
104: public void setRotation(double rotation) {
105: this .rotation = rotation;
106: }
107:
108: public void render(Graphics2D g2, int width, int height) {
109: double radius = Math.sqrt(width * width + height * height);
110:
111: Point2D p = getOrigin() != null ? getOrigin()
112: : getDefaultOrigin(width, height);
113:
114: g2.translate(p.getX(), p.getY());
115: g2.rotate(rotation);
116: for (int i = 0; i < triangles.length; i++) {
117: triangles[i].render(g2, radius);
118: }
119: g2.rotate(-rotation);
120: g2.translate(-p.getX(), -p.getY());
121: }
122:
123: private Point2D getDefaultOrigin(int width, int height) {
124: return new Point2D.Double(width * 0.75, height * 0.75);
125: }
126:
127: // Helper Class ***********************************************************
128:
129: /**
130: * A helper class that models and renders a single sector.
131: */
132: private static final class Triangle {
133:
134: private final double aRotation;
135: private final double angle;
136: private final Color color;
137:
138: private Triangle(double rotation, double angle, Color color) {
139: this .aRotation = rotation;
140: this .angle = angle;
141: this .color = color;
142: }
143:
144: private static Shape createPolygon(double rotation,
145: double angle, double radius) {
146: double startAngle = rotation - angle / 2;
147: double stopAngle = startAngle + angle;
148: double hypothenusis = radius / Math.cos(angle / 2);
149:
150: float x0 = 0.0f;
151: float y0 = 0.0f;
152: float x1 = (float) (x0 - hypothenusis
153: * Math.cos(startAngle));
154: float y1 = (float) (y0 - hypothenusis
155: * Math.sin(startAngle));
156: float x2 = (float) (x0 - hypothenusis * Math.cos(stopAngle));
157: float y2 = (float) (y0 - hypothenusis * Math.sin(stopAngle));
158:
159: GeneralPath polygon = new GeneralPath(
160: GeneralPath.WIND_EVEN_ODD, 3);
161: polygon.moveTo(x0, y0);
162: polygon.lineTo(x1, y1);
163: polygon.lineTo(x2, y2);
164: polygon.closePath();
165:
166: return polygon;
167: }
168:
169: void render(Graphics2D g2, double radius) {
170: g2.setColor(color);
171: g2.fill(createPolygon(aRotation, angle, radius));
172: }
173: }
174:
175: }
|