Source Code Cross Referenced for RadialGradientPaintContext.java in  » XML-UI » xui32 » com » xoetrope » batik » ext » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML UI » xui32 » com.xoetrope.batik.ext.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Copyright 2001-2003  The Apache Software Foundation 
004:
005:           Licensed under the Apache License, Version 2.0 (the "License");
006:           you may not use this file except in compliance with the License.
007:           You may obtain a copy of the License at
008:
009:               http://www.apache.org/licenses/LICENSE-2.0
010:
011:           Unless required by applicable law or agreed to in writing, software
012:           distributed under the License is distributed on an "AS IS" BASIS,
013:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:           See the License for the specific language governing permissions and
015:           limitations under the License.
016:
017:         */
018:        package com.xoetrope.batik.ext.awt;
019:
020:        import java.awt.Color;
021:        import java.awt.Rectangle;
022:        import java.awt.RenderingHints;
023:        import java.awt.geom.AffineTransform;
024:        import java.awt.geom.NoninvertibleTransformException;
025:        import java.awt.geom.Rectangle2D;
026:        import java.awt.image.ColorModel;
027:
028:        /**
029:         * Provides the actual implementation for the RadialGradientPaint.
030:         * This is where the pixel processing is done.  A RadialGradienPaint
031:         * only supports circular gradients, but it should be possible to scale
032:         * the circle to look approximately elliptical, by means of a
033:         * gradient transform passed into the RadialGradientPaint constructor.
034:         *
035:         * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
036:         * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
037:         * @version $Id: RadialGradientPaintContext.java,v 1.2 2006/08/31 09:28:47 val Exp $
038:         *
039:         */
040:        final class RadialGradientPaintContext extends
041:                MultipleGradientPaintContext {
042:
043:            /** True when (focus == center)  */
044:            private boolean isSimpleFocus = false;
045:
046:            /** True when (cycleMethod == NO_CYCLE) */
047:            private boolean isNonCyclic = false;
048:
049:            /** Radius of the outermost circle defining the 100% gradient stop. */
050:            private float radius;
051:
052:            /** Variables representing center and focus points. */
053:            private float centerX, centerY, focusX, focusY;
054:
055:            /** Radius of the gradient circle squared. */
056:            private float radiusSq;
057:
058:            /** Constant part of X, Y user space coordinates. */
059:            private float constA, constB;
060:
061:            /** This value represents the solution when focusX == X.  It is called
062:             * trivial because it is easier to calculate than the general case.
063:             */
064:            private float trivial;
065:
066:            private static final int FIXED_POINT_IMPL = 1;
067:            private static final int DEFAULT_IMPL = 2;
068:            private static final int ANTI_ALIAS_IMPL = 3;
069:
070:            private int fillMethod;
071:
072:            /** Amount for offset when clamping focus. */
073:            private static final float SCALEBACK = .97f;
074:
075:            /** 
076:             * Constructor for RadialGradientPaintContext.
077:             *
078:             *  @param cm {@link ColorModel} that receives
079:             *  the <code>Paint</code> data. This is used only as a hint.
080:             *
081:             *  @param deviceBounds the device space bounding box of the 
082:             *  graphics primitive being rendered
083:             *
084:             *  @param userBounds the user space bounding box of the 
085:             *  graphics primitive being rendered
086:             * 
087:             *  @param t the {@link AffineTransform} from user
088:             *  space into device space (gradientTransform should be 
089:             *  concatenated with this)    
090:             *
091:             *  @param hints the hints that the context object uses to choose
092:             *  between rendering alternatives
093:             *       
094:             *  @param cx the center point in user space of the circle defining 
095:             *  the gradient.  The last color of the gradient is mapped to the 
096:             *  perimeter of this circle X coordinate
097:             *
098:             *  @param cy the center point in user space of the circle defining 
099:             *  the gradient.  The last color of the gradient is mapped to the 
100:             *  perimeter of this circle Y coordinate
101:             *     
102:             *  @param r the radius of the circle defining the extents of the 
103:             *  color gradient
104:             *
105:             *  @param fx the point in user space to which the first color is mapped
106:             *  X coordinate
107:             *
108:             *  @param fy the point in user space to which the first color is mapped
109:             *  Y coordinate
110:             *
111:             *  @param fractions the fractions specifying the gradient distribution
112:             *
113:             *  @param colors the gradient colors
114:             *
115:             *  @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
116:             *
117:             *  @param colorSpace which colorspace to use for interpolation, 
118:             *  either SRGB or LINEAR_RGB
119:             *
120:             */
121:            public RadialGradientPaintContext(ColorModel cm,
122:                    Rectangle deviceBounds, Rectangle2D userBounds,
123:                    AffineTransform t, RenderingHints hints, float cx,
124:                    float cy, float r, float fx, float fy, float[] fractions,
125:                    Color[] colors,
126:                    MultipleGradientPaint.CycleMethodEnum cycleMethod,
127:                    MultipleGradientPaint.ColorSpaceEnum colorSpace)
128:                    throws NoninvertibleTransformException {
129:                super (cm, deviceBounds, userBounds, t, hints, fractions,
130:                        colors, cycleMethod, colorSpace);
131:
132:                //copy some parameters.
133:                centerX = cx;
134:                centerY = cy;
135:                focusX = fx;
136:                focusY = fy;
137:                radius = r;
138:
139:                this .isSimpleFocus = (focusX == centerX) && (focusY == centerY);
140:                this .isNonCyclic = (cycleMethod == RadialGradientPaint.NO_CYCLE);
141:
142:                //for use in the quadractic equation
143:                radiusSq = radius * radius;
144:
145:                float dX = focusX - centerX;
146:                float dY = focusY - centerY;
147:
148:                double dist = Math.sqrt((dX * dX) + (dY * dY));
149:
150:                //test if distance from focus to center is greater than the radius
151:                if (dist > radius * SCALEBACK) { //clamp focus to radius
152:                    double angle = Math.atan2(dY, dX);
153:
154:                    //x = r cos theta, y = r sin theta
155:                    focusX = (float) (SCALEBACK * radius * Math.cos(angle))
156:                            + centerX;
157:
158:                    focusY = (float) (SCALEBACK * radius * Math.sin(angle))
159:                            + centerY;
160:                }
161:
162:                //calculate the solution to be used in the case where X == focusX
163:                //in cyclicCircularGradientFillRaster
164:                dX = focusX - centerX;
165:                trivial = (float) Math.sqrt(radiusSq - (dX * dX));
166:
167:                // constant parts of X, Y user space coordinates 
168:                constA = a02 - centerX;
169:                constB = a12 - centerY;
170:
171:                Object colorRend = hints
172:                        .get(RenderingHints.KEY_COLOR_RENDERING);
173:                Object rend = hints.get(RenderingHints.KEY_RENDERING);
174:
175:                fillMethod = 0;
176:
177:                if ((rend == RenderingHints.VALUE_RENDER_QUALITY)
178:                        || (colorRend == RenderingHints.VALUE_COLOR_RENDER_QUALITY)) {
179:                    // System.out.println("AAHints set: " + rend + ", " + colorRend);
180:                    fillMethod = ANTI_ALIAS_IMPL;
181:                }
182:
183:                if ((rend == RenderingHints.VALUE_RENDER_SPEED)
184:                        || (colorRend == RenderingHints.VALUE_COLOR_RENDER_SPEED)) {
185:                    // System.out.println("SPHints set: " + rend + ", " + colorRend);
186:                    fillMethod = DEFAULT_IMPL;
187:                }
188:
189:                // We are in the 'default' case, no hint or hint set to
190:                // DEFAULT values...
191:                if (fillMethod == 0) {
192:                    // For now we will always use the 'default' impl if 
193:                    // one is not specified.
194:                    fillMethod = DEFAULT_IMPL;
195:
196:                    if (false) {
197:                        // This could be used for a 'smart' choice in
198:                        // the default case, if the gradient has obvious
199:                        // discontinuites use AA, otherwise default
200:                        if (hasDiscontinuity) {
201:                            fillMethod = ANTI_ALIAS_IMPL;
202:                        } else {
203:                            fillMethod = DEFAULT_IMPL;
204:                        }
205:                    }
206:                }
207:
208:                if ((fillMethod == DEFAULT_IMPL)
209:                        && (isSimpleFocus && isNonCyclic && isSimpleLookup)) {
210:                    this .calculateFixedPointSqrtLookupTable();
211:                    fillMethod = FIXED_POINT_IMPL;
212:                }
213:            }
214:
215:            /**
216:             * Return a Raster containing the colors generated for the graphics
217:             * operation.
218:             * @param x,y,w,h The area in device space for which colors are
219:             * generated.
220:             */
221:            protected void fillRaster(int pixels[], int off, int adjust, int x,
222:                    int y, int w, int h) {
223:                switch (fillMethod) {
224:                case FIXED_POINT_IMPL:
225:                    // System.out.println("Calling FP");
226:                    fixedPointSimplestCaseNonCyclicFillRaster(pixels, off,
227:                            adjust, x, y, w, h);
228:                    break;
229:                case ANTI_ALIAS_IMPL:
230:                    // System.out.println("Calling AA");
231:                    antiAliasFillRaster(pixels, off, adjust, x, y, w, h);
232:                    break;
233:                case DEFAULT_IMPL:
234:                default:
235:                    // System.out.println("Calling Default");
236:                    cyclicCircularGradientFillRaster(pixels, off, adjust, x, y,
237:                            w, h);
238:                }
239:            }
240:
241:            /**
242:             * This code works in the simplest of cases, where the focus == center 
243:             * point, the gradient is noncyclic, and the gradient lookup method is 
244:             * fast (single array index, no conversion necessary).
245:             *
246:             */
247:            private void fixedPointSimplestCaseNonCyclicFillRaster(
248:                    int pixels[], int off, int adjust, int x, int y, int w,
249:                    int h) {
250:                float iSq = 0; // Square distance index
251:                final float indexFactor = fastGradientArraySize / radius;
252:
253:                //constant part of X and Y coordinates for the entire raster
254:                final float constX = (a00 * x) + (a01 * y) + constA;
255:                final float constY = (a10 * x) + (a11 * y) + constB;
256:                final float deltaX = indexFactor * a00; //incremental change in dX
257:                final float deltaY = indexFactor * a10; //incremental change in dY
258:                float dX, dY; //the current distance from center
259:                final int fixedArraySizeSq = (fastGradientArraySize * fastGradientArraySize);
260:                float g, gDelta, gDeltaDelta, temp; //gradient square value
261:                int gIndex; // integer number used to index gradient array
262:                int iSqInt; // Square distance index       		   
263:
264:                int end, j; //indexing variables
265:                int indexer = off;//used to index pixels array
266:
267:                temp = ((deltaX * deltaX) + (deltaY * deltaY));
268:                gDeltaDelta = ((temp * 2));
269:
270:                if (temp > fixedArraySizeSq) {
271:                    // This combination of scale and circle radius means
272:                    // essentially no pixels will be anything but the end
273:                    // stop color.  This also avoids math problems.
274:                    final int val = gradientOverflow;
275:                    for (j = 0; j < h; j++) { //for every row
276:                        //for every column (inner loop begins here)
277:                        for (end = indexer + w; indexer < end; indexer++)
278:                            pixels[indexer] = val;
279:                        indexer += adjust;
280:                    }
281:                    return;
282:                }
283:
284:                // For every point in the raster, calculate the color at that point
285:                for (j = 0; j < h; j++) { //for every row
286:                    //x and y (in user space) of the first pixel of this row
287:                    dX = indexFactor * ((a01 * j) + constX);
288:                    dY = indexFactor * ((a11 * j) + constY);
289:
290:                    // these values below here allow for an incremental calculation
291:                    // of dX^2 + dY^2 
292:
293:                    //initialize to be equal to distance squared
294:                    g = (((dY * dY) + (dX * dX)));
295:                    gDelta = (((((deltaY * dY) + (deltaX * dX)) * 2) + temp));
296:
297:                    //for every column (inner loop begins here)
298:                    for (end = indexer + w; indexer < end; indexer++) {
299:                        //determine the distance to the center
300:
301:                        //since this is a non cyclic fill raster, crop at "1" and 0
302:                        if (g >= fixedArraySizeSq) {
303:                            pixels[indexer] = gradientOverflow;
304:                        }
305:
306:                        // This should not happen as gIndex is a square
307:                        // quantity. Code commented out on purpose, can't underflow.
308:                        // else if (g < 0) {
309:                        //    gIndex = 0;		    
310:                        // }
311:
312:                        else {
313:                            iSq = (g * invSqStepFloat);
314:
315:                            iSqInt = (int) iSq; //chop off fractional part
316:                            iSq -= iSqInt;
317:                            gIndex = sqrtLutFixed[iSqInt];
318:                            gIndex += (int) (iSq * (sqrtLutFixed[iSqInt + 1] - gIndex));
319:                            pixels[indexer] = gradient[gIndex];
320:                        }
321:
322:                        //incremental calculation
323:                        g += gDelta;
324:                        gDelta += gDeltaDelta;
325:                    }
326:                    indexer += adjust;
327:                }
328:            }
329:
330:            /** Length of a square distance intervale in the lookup table */
331:            private float invSqStepFloat;
332:
333:            /** Used to limit the size of the square root lookup table */
334:            private int MAX_PRECISION = 256;
335:
336:            /** Square root lookup table */
337:            private int sqrtLutFixed[] = new int[MAX_PRECISION];
338:
339:            /**
340:             * Build square root lookup table
341:             */
342:            private void calculateFixedPointSqrtLookupTable() {
343:                float sqStepFloat;
344:                sqStepFloat = ((fastGradientArraySize * fastGradientArraySize) / (MAX_PRECISION - 2));
345:
346:                // The last two values are the same so that linear square root 
347:                // interpolation can happen on the maximum reachable element in the 
348:                // lookup table (precision-2)
349:                int i;
350:                for (i = 0; i < MAX_PRECISION - 1; i++) {
351:                    sqrtLutFixed[i] = (int) (Math.sqrt(i * sqStepFloat));
352:                }
353:                sqrtLutFixed[i] = sqrtLutFixed[i - 1];
354:                invSqStepFloat = 1 / sqStepFloat;
355:            }
356:
357:            /** Fill the raster, cycling the gradient colors when a point falls outside
358:             *  of the perimeter of the 100% stop circle.          
359:             * 
360:             *  This calculation first computes the intersection point of the line
361:             *  from the focus through the current point in the raster, and the
362:             *  perimeter of the gradient circle.
363:             * 
364:             *  Then it determines the percentage distance of the current point along
365:             *  that line (focus is 0%, perimeter is 100%). 
366:             *
367:             *  Equation of a circle centered at (a,b) with radius r:
368:             *  (x-a)^2 + (y-b)^2 = r^2
369:             *  Equation of a line with slope m and y-intercept b
370:             *  y = mx + b
371:             *  replacing y in the cirlce equation and solving using the quadratic
372:             *  formula produces the following set of equations.  Constant factors have
373:             *  been extracted out of the inner loop.
374:             *
375:             */
376:            private void cyclicCircularGradientFillRaster(int pixels[],
377:                    int off, int adjust, int x, int y, int w, int h) {
378:                // Constant part of the C factor of the quadratic equation
379:                final double constC = -(radiusSq) + (centerX * centerX)
380:                        + (centerY * centerY);
381:                double A; //coefficient of the quadratic equation (Ax^2 + Bx + C = 0)
382:                double B; //coefficient of the quadratic equation
383:                double C; //coefficient of the quadratic equation
384:                double slope; //slope of the focus-perimeter line
385:                double yintcpt; //y-intercept of the focus-perimeter line
386:                double solutionX;//intersection with circle X coordinate
387:                double solutionY;//intersection with circle Y coordinate       
388:                final float constX = (a00 * x) + (a01 * y) + a02;//const part of X coord
389:                final float constY = (a10 * x) + (a11 * y) + a12; //const part of Y coord
390:                final float precalc2 = 2 * centerY;//const in inner loop quad. formula
391:                final float precalc3 = -2 * centerX;//const in inner loop quad. formula
392:                float X; // User space point X coordinate 
393:                float Y; // User space point Y coordinate
394:                float g;//value between 0 and 1 specifying position in the gradient
395:                float det; //determinant of quadratic formula (should always be >0)
396:                float currentToFocusSq;//sq distance from the current pt. to focus
397:                float intersectToFocusSq;//sq distance from the intersect pt. to focus
398:                float deltaXSq; //temp variable for a change in X squared.
399:                float deltaYSq; //temp variable for a change in Y squared.
400:                int indexer = off; //index variable for pixels array
401:                int i, j; //indexing variables for FOR loops
402:                int pixInc = w + adjust;//incremental index change for pixels array
403:
404:                for (j = 0; j < h; j++) { //for every row
405:
406:                    X = (a01 * j) + constX; //constants from column to column
407:                    Y = (a11 * j) + constY;
408:
409:                    //for every column (inner loop begins here)
410:                    for (i = 0; i < w; i++) {
411:
412:                        // special case to avoid divide by zero or very near zero
413:                        if (((X - focusX) > -0.000001)
414:                                && ((X - focusX) < 0.000001)) {
415:                            solutionX = focusX;
416:
417:                            solutionY = centerY;
418:
419:                            solutionY += (Y > focusY) ? trivial : -trivial;
420:                        }
421:
422:                        else {
423:
424:                            //slope of the focus-current line
425:                            slope = (Y - focusY) / (X - focusX);
426:
427:                            yintcpt = Y - (slope * X); //y-intercept of that same line
428:
429:                            //use the quadratic formula to calculate the intersection
430:                            //point		  
431:                            A = (slope * slope) + 1;
432:
433:                            B = precalc3 + (-2 * slope * (centerY - yintcpt));
434:
435:                            C = constC + (yintcpt * (yintcpt - precalc2));
436:
437:                            det = (float) Math.sqrt((B * B) - (4 * A * C));
438:
439:                            solutionX = -B;
440:
441:                            //choose the positive or negative root depending
442:                            //on where the X coord lies with respect to the focus.
443:                            solutionX += (X < focusX) ? -det : det;
444:
445:                            solutionX = solutionX / (2 * A);//divisor
446:
447:                            solutionY = (slope * solutionX) + yintcpt;
448:                        }
449:
450:                        //calculate the square of the distance from the current point 
451:                        //to the focus and the square of the distance from the 
452:                        //intersection point to the focus. Want the squares so we can
453:                        //do 1 square root after division instead of 2 before.
454:
455:                        deltaXSq = (float) solutionX - focusX;
456:                        deltaXSq = deltaXSq * deltaXSq;
457:
458:                        deltaYSq = (float) solutionY - focusY;
459:                        deltaYSq = deltaYSq * deltaYSq;
460:
461:                        intersectToFocusSq = deltaXSq + deltaYSq;
462:
463:                        deltaXSq = X - focusX;
464:                        deltaXSq = deltaXSq * deltaXSq;
465:
466:                        deltaYSq = Y - focusY;
467:                        deltaYSq = deltaYSq * deltaYSq;
468:
469:                        currentToFocusSq = deltaXSq + deltaYSq;
470:
471:                        //want the percentage (0-1) of the current point along the 
472:                        //focus-circumference line
473:                        g = (float) Math.sqrt(currentToFocusSq
474:                                / intersectToFocusSq);
475:
476:                        //Get the color at this point
477:                        pixels[indexer + i] = indexIntoGradientsArrays(g);
478:
479:                        X += a00; //incremental change in X, Y
480:                        Y += a10;
481:                    } //end inner loop
482:                    indexer += pixInc;
483:                } //end outer loop
484:            }
485:
486:            /** Fill the raster, cycling the gradient colors when a point
487:             *  falls outside of the perimeter of the 100% stop circle. Use
488:             *  the anti-aliased gradient lookup.
489:             *
490:             *  This calculation first computes the intersection point of the line
491:             *  from the focus through the current point in the raster, and the
492:             *  perimeter of the gradient circle.
493:             * 
494:             *  Then it determines the percentage distance of the current point along
495:             *  that line (focus is 0%, perimeter is 100%). 
496:             *
497:             *  Equation of a circle centered at (a,b) with radius r:
498:             *  (x-a)^2 + (y-b)^2 = r^2
499:             *  Equation of a line with slope m and y-intercept b
500:             *  y = mx + b
501:             *  replacing y in the cirlce equation and solving using the quadratic
502:             *  formula produces the following set of equations.  Constant factors have
503:             *  been extracted out of the inner loop.
504:             * */
505:            private void antiAliasFillRaster(int pixels[], int off, int adjust,
506:                    int x, int y, int w, int h) {
507:                // Constant part of the C factor of the quadratic equation
508:                final double constC = -(radiusSq) + (centerX * centerX)
509:                        + (centerY * centerY);
510:                //coefficients of the quadratic equation (Ax^2 + Bx + C = 0)
511:                final float precalc2 = 2 * centerY;//const in inner loop quad. formula
512:                final float precalc3 = -2 * centerX;//const in inner loop quad. formula
513:
514:                //const part of X,Y coord (shifted to bottom left corner of pixel.
515:                final float constX = (a00 * (x - .5f)) + (a01 * (y + .5f))
516:                        + a02;
517:                final float constY = (a10 * (x - .5f)) + (a11 * (y + .5f))
518:                        + a12;
519:                float X; // User space point X coordinate 
520:                float Y; // User space point Y coordinate
521:                int i, j; //indexing variables for FOR loops
522:                int indexer = off - 1; //index variable for pixels array
523:
524:                double[] prevGs = new double[w + 1];
525:                double deltaXSq, deltaYSq;
526:                double solutionX, solutionY;
527:                double slope, yintcpt, A, B, C, det;
528:                double intersectToFocusSq, currentToFocusSq;
529:                double g00, g01, g10, g11;
530:
531:                // Set X,Y to top left corner of first pixel of first row.
532:                X = constX - a01;
533:                Y = constY - a11;
534:
535:                // Calc top row of g's.
536:                for (i = 0; i <= w; i++) {
537:                    // special case to avoid divide by zero or very near zero
538:                    if (((X - focusX) > -0.000001) && ((X - focusX) < 0.000001)) {
539:                        solutionX = focusX;
540:                        solutionY = centerY;
541:                        solutionY += (Y > focusY) ? trivial : -trivial;
542:                    } else {
543:                        // Formula for Circle: (X-Xc)^2 + (Y-Yc)^2 - R^2 = 0
544:                        // Formula line:        Y = Slope*x + Y0;
545:                        // 
546:                        // So you substitue line into Circle and apply
547:                        // Quadradic formula.
548:
549:                        //slope of the focus-current line
550:                        slope = (Y - focusY) / (X - focusX);
551:
552:                        yintcpt = Y - (slope * X); //y-intercept of that same line
553:
554:                        //use the quadratic formula to calculate the intersection
555:                        //point		  
556:                        A = (slope * slope) + 1;
557:
558:                        B = precalc3 + (-2 * slope * (centerY - yintcpt));
559:
560:                        C = constC + (yintcpt * (yintcpt - precalc2));
561:
562:                        det = Math.sqrt((B * B) - (4 * A * C));
563:
564:                        solutionX = -B;
565:
566:                        //choose the positive or negative root depending
567:                        //on where the X coord lies with respect to the focus.
568:                        solutionX += (X < focusX) ? -det : det;
569:
570:                        solutionX = solutionX / (2 * A);//divisor
571:
572:                        solutionY = (slope * solutionX) + yintcpt;
573:                    }
574:
575:                    //calculate the square of the distance from the current point 
576:                    //to the focus and the square of the distance from the 
577:                    //intersection point to the focus. Want the squares so we can
578:                    //do 1 square root after division instead of 2 before.
579:                    deltaXSq = solutionX - focusX;
580:                    deltaXSq = deltaXSq * deltaXSq;
581:
582:                    deltaYSq = solutionY - focusY;
583:                    deltaYSq = deltaYSq * deltaYSq;
584:
585:                    intersectToFocusSq = deltaXSq + deltaYSq;
586:
587:                    deltaXSq = X - focusX;
588:                    deltaXSq = deltaXSq * deltaXSq;
589:
590:                    deltaYSq = Y - focusY;
591:                    deltaYSq = deltaYSq * deltaYSq;
592:
593:                    currentToFocusSq = deltaXSq + deltaYSq;
594:
595:                    //want the percentage (0-1) of the current point along the 
596:                    //focus-circumference line
597:                    prevGs[i] = Math
598:                            .sqrt(currentToFocusSq / intersectToFocusSq);
599:
600:                    X += a00; //incremental change in X, Y
601:                    Y += a10;
602:                }
603:
604:                for (j = 0; j < h; j++) { //for every row
605:
606:                    // Set X,Y to bottom edge of pixel row.
607:                    X = (a01 * j) + constX; //constants from row to row
608:                    Y = (a11 * j) + constY;
609:
610:                    g10 = prevGs[0];
611:                    // special case to avoid divide by zero or very near zero
612:                    if (((X - focusX) > -0.000001) && ((X - focusX) < 0.000001)) {
613:                        solutionX = focusX;
614:                        solutionY = centerY;
615:                        solutionY += (Y > focusY) ? trivial : -trivial;
616:                    } else {
617:                        // Formula for Circle: (X-Xc)^2 + (Y-Yc)^2 - R^2 = 0
618:                        // Formula line:        Y = Slope*x + Y0;
619:                        // 
620:                        // So you substitue line into Circle and apply
621:                        // Quadradic formula.
622:
623:                        //slope of the focus-current line
624:                        slope = (Y - focusY) / (X - focusX);
625:
626:                        yintcpt = Y - (slope * X); //y-intercept of that same line
627:
628:                        //use the quadratic formula to calculate the intersection
629:                        //point		  
630:                        A = (slope * slope) + 1;
631:
632:                        B = precalc3 + (-2 * slope * (centerY - yintcpt));
633:
634:                        C = constC + (yintcpt * (yintcpt - precalc2));
635:
636:                        det = Math.sqrt((B * B) - (4 * A * C));
637:
638:                        solutionX = -B;
639:
640:                        //choose the positive or negative root depending
641:                        //on where the X coord lies with respect to the focus.
642:                        solutionX += (X < focusX) ? -det : det;
643:
644:                        solutionX = solutionX / (2 * A);//divisor
645:
646:                        solutionY = (slope * solutionX) + yintcpt;
647:                    }
648:
649:                    //calculate the square of the distance from the current point 
650:                    //to the focus and the square of the distance from the 
651:                    //intersection point to the focus. Want the squares so we can
652:                    //do 1 square root after division instead of 2 before.
653:                    deltaXSq = solutionX - focusX;
654:                    deltaXSq = deltaXSq * deltaXSq;
655:
656:                    deltaYSq = solutionY - focusY;
657:                    deltaYSq = deltaYSq * deltaYSq;
658:
659:                    intersectToFocusSq = deltaXSq + deltaYSq;
660:
661:                    deltaXSq = X - focusX;
662:                    deltaXSq = deltaXSq * deltaXSq;
663:
664:                    deltaYSq = Y - focusY;
665:                    deltaYSq = deltaYSq * deltaYSq;
666:
667:                    currentToFocusSq = deltaXSq + deltaYSq;
668:                    g11 = Math.sqrt(currentToFocusSq / intersectToFocusSq);
669:                    prevGs[0] = g11;
670:
671:                    X += a00; //incremental change in X, Y
672:                    Y += a10;
673:
674:                    //for every column (inner loop begins here)
675:                    for (i = 1; i <= w; i++) {
676:                        g00 = g10;
677:                        g01 = g11;
678:                        g10 = prevGs[i];
679:
680:                        // special case to avoid divide by zero or very near zero
681:                        if (((X - focusX) > -0.000001)
682:                                && ((X - focusX) < 0.000001)) {
683:                            solutionX = focusX;
684:                            solutionY = centerY;
685:                            solutionY += (Y > focusY) ? trivial : -trivial;
686:                        } else {
687:                            // Formula for Circle: (X-Xc)^2 + (Y-Yc)^2 - R^2 = 0
688:                            // Formula line:        Y = Slope*x + Y0;
689:                            // 
690:                            // So you substitue line into Circle and apply
691:                            // Quadradic formula.
692:
693:                            //slope of the focus-current line
694:                            slope = (Y - focusY) / (X - focusX);
695:
696:                            yintcpt = Y - (slope * X); //y-intercept of that same line
697:
698:                            //use the quadratic formula to calculate the intersection
699:                            //point		  
700:                            A = (slope * slope) + 1;
701:
702:                            B = precalc3 + (-2 * slope * (centerY - yintcpt));
703:
704:                            C = constC + (yintcpt * (yintcpt - precalc2));
705:
706:                            det = Math.sqrt((B * B) - (4 * A * C));
707:
708:                            solutionX = -B;
709:
710:                            //choose the positive or negative root depending
711:                            //on where the X coord lies with respect to the focus.
712:                            solutionX += (X < focusX) ? -det : det;
713:
714:                            solutionX = solutionX / (2 * A);//divisor
715:
716:                            solutionY = (slope * solutionX) + yintcpt;
717:                        }
718:
719:                        //calculate the square of the distance from the current point 
720:                        //to the focus and the square of the distance from the 
721:                        //intersection point to the focus. Want the squares so we can
722:                        //do 1 square root after division instead of 2 before.
723:                        deltaXSq = solutionX - focusX;
724:                        deltaXSq = deltaXSq * deltaXSq;
725:
726:                        deltaYSq = solutionY - focusY;
727:                        deltaYSq = deltaYSq * deltaYSq;
728:
729:                        intersectToFocusSq = deltaXSq + deltaYSq;
730:
731:                        deltaXSq = X - focusX;
732:                        deltaXSq = deltaXSq * deltaXSq;
733:
734:                        deltaYSq = Y - focusY;
735:                        deltaYSq = deltaYSq * deltaYSq;
736:
737:                        currentToFocusSq = deltaXSq + deltaYSq;
738:                        g11 = Math.sqrt(currentToFocusSq / intersectToFocusSq);
739:                        prevGs[i] = g11;
740:
741:                        //Get the color at this point
742:                        pixels[indexer + i] = indexGradientAntiAlias(
743:                                (float) ((g00 + g01 + g10 + g11) / 4),
744:                                (float) Math.max(Math.abs(g11 - g00), Math
745:                                        .abs(g10 - g01)));
746:
747:                        X += a00; //incremental change in X, Y
748:                        Y += a10;
749:                    } //end inner loop
750:                    indexer += (w + adjust);
751:                } //end outer loop
752:            }
753:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.