|
Java example source code file (Helpers.java)
The Helpers.java Java example source code/* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.java2d.pisces; import java.util.Arrays; import static java.lang.Math.PI; import static java.lang.Math.cos; import static java.lang.Math.sqrt; import static java.lang.Math.cbrt; import static java.lang.Math.acos; final class Helpers { private Helpers() { throw new Error("This is a non instantiable class"); } static boolean within(final float x, final float y, final float err) { final float d = y - x; return (d <= err && d >= -err); } static boolean within(final double x, final double y, final double err) { final double d = y - x; return (d <= err && d >= -err); } static int quadraticRoots(final float a, final float b, final float c, float[] zeroes, final int off) { int ret = off; float t; if (a != 0f) { final float dis = b*b - 4*a*c; if (dis > 0) { final float sqrtDis = (float)Math.sqrt(dis); // depending on the sign of b we use a slightly different // algorithm than the traditional one to find one of the roots // so we can avoid adding numbers of different signs (which // might result in loss of precision). if (b >= 0) { zeroes[ret++] = (2 * c) / (-b - sqrtDis); zeroes[ret++] = (-b - sqrtDis) / (2 * a); } else { zeroes[ret++] = (-b + sqrtDis) / (2 * a); zeroes[ret++] = (2 * c) / (-b + sqrtDis); } } else if (dis == 0f) { t = (-b) / (2 * a); zeroes[ret++] = t; } } else { if (b != 0f) { t = (-c) / b; zeroes[ret++] = t; } } return ret - off; } // find the roots of g(t) = d*t^3 + a*t^2 + b*t + c in [A,B) static int cubicRootsInAB(float d, float a, float b, float c, float[] pts, final int off, final float A, final float B) { if (d == 0) { int num = quadraticRoots(a, b, c, pts, off); return filterOutNotInAB(pts, off, num, A, B) - off; } // From Graphics Gems: // http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c // (also from awt.geom.CubicCurve2D. But here we don't need as // much accuracy and we don't want to create arrays so we use // our own customized version). /* normal form: x^3 + ax^2 + bx + c = 0 */ a /= d; b /= d; c /= d; // substitute x = y - A/3 to eliminate quadratic term: // x^3 +Px + Q = 0 // // Since we actually need P/3 and Q/2 for all of the // calculations that follow, we will calculate // p = P/3 // q = Q/2 // instead and use those values for simplicity of the code. double sq_A = a * a; double p = 1.0/3 * (-1.0/3 * sq_A + b); double q = 1.0/2 * (2.0/27 * a * sq_A - 1.0/3 * a * b + c); /* use Cardano's formula */ double cb_p = p * p * p; double D = q * q + cb_p; int num; if (D < 0) { // see: http://en.wikipedia.org/wiki/Cubic_function#Trigonometric_.28and_hyperbolic.29_method final double phi = 1.0/3 * acos(-q / sqrt(-cb_p)); final double t = 2 * sqrt(-p); pts[ off+0 ] = (float)( t * cos(phi)); pts[ off+1 ] = (float)(-t * cos(phi + PI / 3)); pts[ off+2 ] = (float)(-t * cos(phi - PI / 3)); num = 3; } else { final double sqrt_D = sqrt(D); final double u = cbrt(sqrt_D - q); final double v = - cbrt(sqrt_D + q); pts[ off ] = (float)(u + v); num = 1; if (within(D, 0, 1e-8)) { pts[off+1] = -(pts[off] / 2); num = 2; } } final float sub = 1.0f/3 * a; for (int i = 0; i < num; ++i) { pts[ off+i ] -= sub; } return filterOutNotInAB(pts, off, num, A, B) - off; } // These use a hardcoded factor of 2 for increasing sizes. Perhaps this // should be provided as an argument. static float[] widenArray(float[] in, final int cursize, final int numToAdd) { if (in.length >= cursize + numToAdd) { return in; } return Arrays.copyOf(in, 2 * (cursize + numToAdd)); } static int[] widenArray(int[] in, final int cursize, final int numToAdd) { if (in.length >= cursize + numToAdd) { return in; } return Arrays.copyOf(in, 2 * (cursize + numToAdd)); } static float evalCubic(final float a, final float b, final float c, final float d, final float t) { return t * (t * (t * a + b) + c) + d; } static float evalQuad(final float a, final float b, final float c, final float t) { return t * (t * a + b) + c; } // returns the index 1 past the last valid element remaining after filtering static int filterOutNotInAB(float[] nums, final int off, final int len, final float a, final float b) { int ret = off; for (int i = off; i < off + len; i++) { if (nums[i] >= a && nums[i] < b) { nums[ret++] = nums[i]; } } return ret; } static float polyLineLength(float[] poly, final int off, final int nCoords) { assert nCoords % 2 == 0 && poly.length >= off + nCoords : ""; float acc = 0; for (int i = off + 2; i < off + nCoords; i += 2) { acc += linelen(poly[i], poly[i+1], poly[i-2], poly[i-1]); } return acc; } static float linelen(float x1, float y1, float x2, float y2) { final float dx = x2 - x1; final float dy = y2 - y1; return (float)Math.sqrt(dx*dx + dy*dy); } static void subdivide(float[] src, int srcoff, float[] left, int leftoff, float[] right, int rightoff, int type) { switch(type) { case 6: Helpers.subdivideQuad(src, srcoff, left, leftoff, right, rightoff); break; case 8: Helpers.subdivideCubic(src, srcoff, left, leftoff, right, rightoff); break; default: throw new InternalError("Unsupported curve type"); } } static void isort(float[] a, int off, int len) { for (int i = off + 1; i < off + len; i++) { float ai = a[i]; int j = i - 1; for (; j >= off && a[j] > ai; j--) { a[j+1] = a[j]; } a[j+1] = ai; } } // Most of these are copied from classes in java.awt.geom because we need // float versions of these functions, and Line2D, CubicCurve2D, // QuadCurve2D don't provide them. /** * Subdivides the cubic curve specified by the coordinates * stored in the <code>src array at indices Other Java examples (source code examples)Here is a short list of links related to this Java Helpers.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.