Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/arranger/jarl/stroke/base/Sin.java


1   package com.arranger.jarl.stroke.base;
2   
3   import com.arranger.jarl.base.IContext;
4   import com.arranger.jarl.base.IJarlObjectInfo;
5   import com.arranger.jarl.stroke.BaseSegmentStroke;
6   import com.arranger.jarl.util.*;
7   import com.arranger.jarl.widget.IWidget;
8   import org.w3c.dom.Element;
9   
10  import java.awt.*;
11  import java.awt.geom.Point2D;
12  
13  /**
14   * Sin creates a sin curve instead of the normal outline
15   *
16   * @strokeAttribute frequency ## xs:float ## the frequency of the sin curve
17   * @strokeAttribute amplitude ## xs:float ## the amplitude of the sin curve
18   * @strokeAttribute rand ## xs:float ## the amount of randomness to apply to the amplitude  (less then 0 means no rand)
19   *
20   * @strokeAttribute startFrequency ## xs:float ## the starting frequency
21   * @strokeAttribute endFrequency ## xs:float ## the ending frequency
22   * @strokeAttribute startAmplitude ## xs:float ## the starting amplitude
23   * @strokeAttribute endAmplitude ## xs:float ## the ending amplitude
24   * @strokeAttribute startRand ## xs:float ## the starting amount of randomness to apply to the amplitude (less then 0 means no rand)
25   * @strokeAttribute endRand ## xs:float ## the ending amount of randomness to apply to the amplitude (less then 0 means no rand)
26   */
27  public class Sin extends BaseSegmentStroke {
28  
29      protected double m_frequency = Double.NEGATIVE_INFINITY;
30      protected double m_amplitude = Double.NEGATIVE_INFINITY;
31      protected double m_rand = Double.NEGATIVE_INFINITY;
32  
33      protected double m_startFrequency = Double.NEGATIVE_INFINITY;
34      protected double m_startAmplitude = Double.NEGATIVE_INFINITY;
35      protected double m_endFrequency = Double.NEGATIVE_INFINITY;
36      protected double m_endAmplitude = Double.NEGATIVE_INFINITY;
37      protected double m_startRand = Double.NEGATIVE_INFINITY;
38      protected double m_endRand = Double.NEGATIVE_INFINITY;
39  
40  
41      /**
42       * This will perform custom drawing of the shape
43       * onto the graphics on behalf of the widget
44       *
45       * @param widget
46       * @param context
47       * @param graphics2D
48       * @param shape
49       */
50      public Shape processShape(IWidget widget,
51                                IContext context,
52                                Graphics2D graphics2D,
53                                Shape shape) {
54          double currentFrequency;
55          double currentAmplitude;
56          double currentRand;
57  
58          //update stuff
59          if (m_frequency != Double.NEGATIVE_INFINITY && m_amplitude != Double.NEGATIVE_INFINITY && m_rand != Double.NEGATIVE_INFINITY) {
60              currentFrequency = m_frequency;
61              currentAmplitude = m_amplitude;
62              currentRand = m_rand;
63          } else if (m_startFrequency != Double.NEGATIVE_INFINITY &&
64                  m_startAmplitude != Double.NEGATIVE_INFINITY &&
65                  m_endFrequency != Double.NEGATIVE_INFINITY &&
66                  m_endAmplitude != Double.NEGATIVE_INFINITY &&
67                  m_startRand != Double.NEGATIVE_INFINITY &&
68                  m_endRand != Double.NEGATIVE_INFINITY) {
69  
70              currentFrequency = InterpolateUtil.interpolate(widget.getStartTime(),
71                      widget.getEndTime(),
72                      m_startFrequency,
73                      m_endFrequency,
74                      context.getTime());
75  
76              currentAmplitude = InterpolateUtil.interpolate(widget.getStartTime(),
77                      widget.getEndTime(),
78                      m_startAmplitude,
79                      m_endAmplitude,
80                      context.getTime());
81  
82              currentRand = InterpolateUtil.interpolate(widget.getStartTime(),
83                      widget.getEndTime(),
84                      m_startRand,
85                      m_endRand,
86                      context.getTime());
87          } else {
88              SinConfigSegment sinConfigSegment = (SinConfigSegment) getCurrentSegment(widget, context);
89              double currentPct = getCurrentSegmentTimePct(widget, context, sinConfigSegment);
90  
91              currentFrequency = InterpolateUtil.interpolate(0,
92                      1,
93                      sinConfigSegment.getStartFrequency(),
94                      sinConfigSegment.getEndFrequency(),
95                      currentPct);
96              currentAmplitude = InterpolateUtil.interpolate(0,
97                      1,
98                      sinConfigSegment.getStartAmplitude(),
99                      sinConfigSegment.getEndAmplitude(),
100                     currentPct);
101             currentRand = InterpolateUtil.interpolate(0,
102                     1,
103                     sinConfigSegment.getStartRand(),
104                     sinConfigSegment.getEndRand(),
105                     currentPct);
106         }
107 
108         Point2D[] points = WidgetUtil.transform(shape,
109                 new SinWidgetTransfrom(currentFrequency,
110                         currentAmplitude,
111                         currentRand));
112         return WidgetUtil.pointsToShape(points, false);
113     }
114 
115     /**
116      * Create a concrete {@link WidgetConfigSegment} based on this element
117      * @param element
118      * @return a specific {@link WidgetConfigSegment}
119      */
120     public WidgetConfigSegment createSegment(Element element) {
121         return new SinConfigSegment(element);
122     }
123 
124     /**
125      * Always remember some attrs might not be there
126      * @param context
127      */
128     protected void initAttributes(IContext context) {
129         super.initAttributes(context);
130 
131         ObjectUtil.initializeField("frequency", m_configElement, this, ObjectUtil.PRIMITIVE_CONVERSION);
132         ObjectUtil.initializeField("amplitude", m_configElement, this, ObjectUtil.PRIMITIVE_CONVERSION);
133         ObjectUtil.initializeField("rand", m_configElement, this, ObjectUtil.PRIMITIVE_CONVERSION);
134 
135         ObjectUtil.initializeField("startFrequency", m_configElement, this, ObjectUtil.PRIMITIVE_CONVERSION);
136         ObjectUtil.initializeField("startAmplitude", m_configElement, this, ObjectUtil.PRIMITIVE_CONVERSION);
137         ObjectUtil.initializeField("startRand", m_configElement, this, ObjectUtil.PRIMITIVE_CONVERSION);
138         ObjectUtil.initializeField("endAmplitude", m_configElement, this, ObjectUtil.PRIMITIVE_CONVERSION);
139         ObjectUtil.initializeField("amplitude", m_configElement, this, ObjectUtil.PRIMITIVE_CONVERSION);
140         ObjectUtil.initializeField("endRand", m_configElement, this, ObjectUtil.PRIMITIVE_CONVERSION);
141     }
142 
143     /**
144      * Override this, and for every field that you're using, call {@link #populateInfo}
145      * for example:
146      * <code>
147      *   populateInfo(jarlObjectInfo, "zOrder", "Z-Order", JarlInfoUtil.PRIMITIVE_DISPLAY);
148      * </code>
149      *
150      * @param jarlObjectInfo
151      *
152      * @see JarlInfoUtil#PRIMITIVE_DISPLAY
153      * @see #populateInfo
154      * @see ObjectUtil#initializeField
155      */
156     protected void addJarlObjectInfo(IJarlObjectInfo jarlObjectInfo) {
157         super.addJarlObjectInfo(jarlObjectInfo);
158         populateInfo(jarlObjectInfo, "frequency", "Frequency", JarlInfoUtil.PRIMITIVE_DISPLAY);
159         populateInfo(jarlObjectInfo, "amplitude", "Amplitude", JarlInfoUtil.PRIMITIVE_DISPLAY);
160         populateInfo(jarlObjectInfo, "rand", "Random (seed)", JarlInfoUtil.PRIMITIVE_DISPLAY);
161 
162         populateInfo(jarlObjectInfo, "startFrequency", "Start Frequency", JarlInfoUtil.PRIMITIVE_DISPLAY);
163         populateInfo(jarlObjectInfo, "startAmplitude", "Start Amplitude", JarlInfoUtil.PRIMITIVE_DISPLAY);
164         populateInfo(jarlObjectInfo, "startRand", "Start Random (seed)", JarlInfoUtil.PRIMITIVE_DISPLAY);
165         populateInfo(jarlObjectInfo, "endFrequency", "End Frequency", JarlInfoUtil.PRIMITIVE_DISPLAY);
166         populateInfo(jarlObjectInfo, "endAmplitude", "End Amplitude", JarlInfoUtil.PRIMITIVE_DISPLAY);
167         populateInfo(jarlObjectInfo, "endRand", "End Random (seed)", JarlInfoUtil.PRIMITIVE_DISPLAY);
168     }
169 
170     protected static class SinConfigSegment extends WidgetConfigSegment {
171 
172         protected double m_startFrequency = Double.NEGATIVE_INFINITY;
173         protected double m_startAmplitude = Double.NEGATIVE_INFINITY;
174         protected double m_endFrequency = Double.NEGATIVE_INFINITY;
175         protected double m_endAmplitude = Double.NEGATIVE_INFINITY;
176         protected double m_startRand = Double.NEGATIVE_INFINITY;
177         protected double m_endRand = Double.NEGATIVE_INFINITY;
178 
179         public SinConfigSegment(Element element) {
180             super(element);
181 
182             ObjectUtil.initializeFieldStrict("startFrequency", element, this, ObjectUtil.PRIMITIVE_CONVERSION);
183             ObjectUtil.initializeFieldStrict("startAmplitude", element, this, ObjectUtil.PRIMITIVE_CONVERSION);
184             ObjectUtil.initializeFieldStrict("startRand", element, this, ObjectUtil.PRIMITIVE_CONVERSION);
185             ObjectUtil.initializeFieldStrict("endFrequency", element, this, ObjectUtil.PRIMITIVE_CONVERSION);
186             ObjectUtil.initializeFieldStrict("endAmplitude", element, this, ObjectUtil.PRIMITIVE_CONVERSION);
187             ObjectUtil.initializeFieldStrict("startRand", element, this, ObjectUtil.PRIMITIVE_CONVERSION);
188             ObjectUtil.initializeFieldStrict("endRand", element, this, ObjectUtil.PRIMITIVE_CONVERSION);
189         }
190 
191         protected void addJarlObjectInfo(IJarlObjectInfo jarlObjectInfo) {
192             super.addJarlObjectInfo(jarlObjectInfo);
193             populateInfo(jarlObjectInfo, "startFrequency", "Start Frequency", JarlInfoUtil.PRIMITIVE_DISPLAY);
194             populateInfo(jarlObjectInfo, "startAmplitude", "Start Amplitude", JarlInfoUtil.PRIMITIVE_DISPLAY);
195             populateInfo(jarlObjectInfo, "startRand", "Start Random (seed)", JarlInfoUtil.PRIMITIVE_DISPLAY);
196             populateInfo(jarlObjectInfo, "endFrequency", "End Frequency", JarlInfoUtil.PRIMITIVE_DISPLAY);
197             populateInfo(jarlObjectInfo, "endAmplitude", "End Amplitude", JarlInfoUtil.PRIMITIVE_DISPLAY);
198             populateInfo(jarlObjectInfo, "endRand", "End Random (seed)", JarlInfoUtil.PRIMITIVE_DISPLAY);
199         }
200 
201         public double getStartFrequency() {
202             return m_startFrequency;
203         }
204 
205         public double getStartAmplitude() {
206             return m_startAmplitude;
207         }
208 
209         public double getEndFrequency() {
210             return m_endFrequency;
211         }
212 
213         public double getEndAmplitude() {
214             return m_endAmplitude;
215         }
216 
217         public double getStartRand() {
218             return m_startRand;
219         }
220 
221         public double getEndRand() {
222             return m_endRand;
223         }
224     }
225 
226     public static class SinWidgetTransfrom implements IWidgetTransform {
227         protected double m_currentFrequency;
228         protected double m_currentAmplitude;
229         protected double m_currentRand = 1.0;
230 
231         public SinWidgetTransfrom(double currentFrequency, double currentAmplitude, double currentRand) {
232             m_currentFrequency = currentFrequency;
233             m_currentAmplitude = currentAmplitude;
234             m_currentRand = currentRand;
235         }
236 
237         /**
238          * Initialize the transform, returning the offset if needed
239          *
240          * @param shapePoints the original shape points
241          * @return the offset into the array of points.  return 0 for no offset
242          */
243         public double initializeTransform(Point2D[] shapePoints) {
244             return 0;
245         }
246 
247         /**
248          * Generate a series of points that will be used to transform
249          * other lines
250          *
251          * @param distance the total x requested (pt[N].x - pt[0].x == x)
252          * @param offset an offset into the internal algortihm
253          * @param precision how frequent to get points
254          * @return an arry of points of the form: x1, y1, x2, y2, .... xN, yN
255          */
256         public double[] getPoints(double distance, double offset, double precision) {
257             double[] points = new double[(int) ((distance / precision) + 1) * 2];
258 
259             int writeIndex = 0;
260             for (double x = 0; x <= distance; x += precision) {
261                 double degrees = (offset + x) * m_currentFrequency;
262                 double y = Math.sin(Math.toRadians(degrees)) * m_currentAmplitude;
263                 if (m_currentRand > 0) {
264                     y *= RandomUtil.getRandomRange(1.0, m_currentRand);
265                 }
266 
267                 points[writeIndex++] = x;
268                 points[writeIndex++] = y;
269             }
270 
271             if (writeIndex != points.length) {
272                 double[] filteredPoints = new double[writeIndex];
273                 System.arraycopy(points, 0, filteredPoints, 0, writeIndex);
274                 points = filteredPoints;
275             }
276 
277             return points;
278         }
279 
280         /**
281          * Whether or not to reverse through the points
282          * @return true for reversing, false for normal
283          */
284         public boolean isReverse() {
285             return false;
286         }
287     }
288 }