All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.harmony.awt.geom.CurveCrossingHelper Maven / Gradle / Ivy

The newest version!
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.harmony.awt.geom;

import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

import com.google.code.appengine.awt.geom.PathIterator;



public class CurveCrossingHelper {
    private double[][] coords;
    private int[][] rules;
    private int[] sizes;
    private int[] rulesSizes;
    private int[][] offsets;
    private List isectPoints = new ArrayList();

    public CurveCrossingHelper(double[][] coords, int[] sizes,
            int[][] rules, int[] rulesSizes,
            int[][] offsets) {
        this.coords = coords;
        this.rules = rules;
        this.sizes = sizes;
        this.rulesSizes = rulesSizes;
        this.offsets = offsets;
    }

    public IntersectPoint[] findCrossing() {
        double[] edge1 = new double[8];
        double[] edge2 = new double[8];
        double[] points = new double[6];
        double[] params = new double[6];
        double[] mp1 = new double[2];
        double[] cp1 = new double[2];
        double[] mp2 = new double[2];
        double[] cp2 = new double[2];
        int rule1, rule2, endIndex1, endIndex2;
        int ipCount = 0;

        for (int i = 0; i < rulesSizes[0]; i++) {
            rule1 = rules[0][i];
            endIndex1 = getCurrentEdge(0, i, edge1, mp1, cp1);
            for (int j = 0; j < rulesSizes[1]; j++) {
                ipCount = 0;
                rule2 = rules[1][j];
                endIndex2 = getCurrentEdge(1, j, edge2, mp2, cp2);
                if (((rule1 == PathIterator.SEG_LINETO) ||
                        (rule1 == PathIterator.SEG_CLOSE)) &&
                        ((rule2 == PathIterator.SEG_LINETO) ||
                                (rule2 == PathIterator.SEG_CLOSE))) {

                    ipCount = GeometryUtil.intersectLinesWithParams(
                            edge1[0], edge1[1], edge1[2], edge1[3],
                            edge2[0], edge2[1], edge2[2], edge2[3],
                            params);

                    if (ipCount != 0) {
                        points[0] = GeometryUtil.line(
                                params[0], edge1[0], edge1[2]);
                        points[1] = GeometryUtil.line(
                                params[0], edge1[1], edge1[3]);
                    }
                } else if (((rule1 == PathIterator.SEG_LINETO) ||
                        (rule1 == PathIterator.SEG_CLOSE)) &&
                        (rule2 == PathIterator.SEG_QUADTO)) {
                    ipCount = GeometryUtil.intersectLineAndQuad(
                            edge1[0], edge1[1], edge1[2],
                            edge1[3], edge2[0], edge2[1],
                            edge2[2], edge2[3], edge2[4],
                            edge2[5],  params);
                    for (int k = 0; k < ipCount; k++) {
                        points[2*k] = GeometryUtil.line(params[2*k], edge1[0], edge1[2]);
                        points[2*k + 1] = GeometryUtil.line(params[2*k], edge1[1], edge1[3]);
                    }
                } else if (rule1 == PathIterator.SEG_QUADTO &&
                        (rule2 == PathIterator.SEG_LINETO || rule2 == PathIterator.SEG_CLOSE)) {
                    ipCount = GeometryUtil.intersectLineAndQuad(
                            edge2[0], edge2[1], edge2[2],
                            edge2[3], edge1[0], edge1[1],
                            edge1[2], edge1[3], edge1[4],
                            edge1[5], params);
                    for (int k = 0; k < ipCount; k++) {
                        points[2*k] = GeometryUtil.line(
                                params[2*k + 1], edge2[0], edge2[2]);
                        points[2*k + 1] = GeometryUtil.line(
                                params[2*k + 1], edge2[1], edge2[3]);
                    }
                } else if ((rule1 == PathIterator.SEG_CUBICTO) &&
                        ((rule2 == PathIterator.SEG_LINETO) ||
                                (rule2 == PathIterator.SEG_CLOSE))) {
                    ipCount = GeometryUtil.intersectLineAndCubic(
                            edge1[0], edge1[1], edge1[2],
                            edge1[3], edge1[4], edge1[5],
                            edge1[6], edge1[7], edge2[0],
                            edge2[1], edge2[2], edge2[3],
                            params);

                    for (int k = 0; k < ipCount; k++) {
                        points[2*k] = GeometryUtil.line(
                                params[2*k + 1], edge2[0], edge2[2]);
                        points[2*k + 1] = GeometryUtil.line(
                                params[2*k + 1], edge2[1], edge2[3]);
                    }
                } else if (((rule1 == PathIterator.SEG_LINETO) ||
                        (rule1 == PathIterator.SEG_CLOSE)) &&
                        (rule2 == PathIterator.SEG_CUBICTO)) {
                    ipCount = GeometryUtil.intersectLineAndCubic(
                            edge1[0], edge1[1], edge1[2],
                            edge1[3], edge2[0], edge2[1],
                            edge2[2], edge2[3], edge2[4],
                            edge2[5], edge2[6], edge2[7],
                            params);

                    for (int k = 0; k < ipCount; k++) {
                        points[2*k] = GeometryUtil.line(
                                params[2*k], edge1[0], edge1[2]);
                        points[2*k + 1] = GeometryUtil.line(
                                params[2*k], edge1[1], edge1[3]);
                    }
                } else if ((rule1 == PathIterator.SEG_QUADTO) &&
                        (rule2 == PathIterator.SEG_QUADTO)) {
                    ipCount = GeometryUtil.intersectQuads(
                            edge1[0], edge1[1], edge1[2], edge1[3],
                            edge1[4], edge1[5], edge2[0], edge2[1],
                            edge2[2], edge2[3], edge2[4], edge2[5],
                            params);
                    for (int k = 0; k < ipCount; k++) {
                        points[2*k] = GeometryUtil.quad(
                                params[2*k], edge1[0], edge1[2], edge1[4]);
                        points[2*k + 1] = GeometryUtil.quad(
                                params[2*k], edge1[1], edge1[3], edge1[5]);
                    }
                } else if ((rule1 == PathIterator.SEG_QUADTO) &&
                        (rule2 == PathIterator.SEG_CUBICTO)) {
                    ipCount = GeometryUtil.intersectQuadAndCubic(
                            edge1[0], edge1[1], edge1[2],
                            edge1[3], edge1[4], edge1[5],
                            edge2[0], edge2[1], edge2[2],
                            edge2[3], edge2[4], edge2[5],
                            edge2[6], edge2[7], params);

                    for (int k = 0; k < ipCount; k++) {
                        points[2*k] = GeometryUtil.quad(
                                params[2*k], edge1[0], edge1[2], edge1[4]);
                        points[2*k + 1] = GeometryUtil.quad(
                                params[2*k], edge1[1], edge1[3], edge1[5]);
                    }
                } else if ((rule1 == PathIterator.SEG_CUBICTO) &&
                        (rule2 == PathIterator.SEG_QUADTO)) {
                    ipCount = GeometryUtil.intersectQuadAndCubic(
                            edge2[0], edge2[1], edge2[2],
                            edge2[3], edge2[4], edge2[5],
                            edge1[0], edge1[1], edge1[2],
                            edge1[3], edge1[4], edge1[5],
                            edge2[6], edge2[7], params);

                    for (int k = 0; k < ipCount; k++) {
                        points[2*k] = GeometryUtil.quad(
                                params[2*k + 1], edge2[0], edge2[2], edge2[4]);
                        points[2*k + 1] = GeometryUtil.quad(
                                params[2*k + 1], edge2[1], edge2[3], edge2[5]);
                    }
                } else if ((rule1 == PathIterator.SEG_CUBICTO) &&
                        (rule2 == PathIterator.SEG_CUBICTO)) {
                    ipCount = GeometryUtil.intersectCubics(
                            edge1[0], edge1[1], edge1[2], edge1[3],
                            edge1[4], edge1[5], edge1[6], edge1[7],
                            edge2[0], edge2[1], edge2[2], edge2[3],
                            edge2[4], edge2[5], edge2[6], edge2[7],
                            params);

                    for (int k = 0; k < ipCount; k++) {
                        points[2*k] = GeometryUtil.cubic(
                                params[2*k], edge1[0], edge1[2], edge1[4], edge1[6]);
                        points[2*k + 1] = GeometryUtil.cubic(
                                params[2*k], edge1[1], edge1[3], edge1[5], edge1[7]);
                    }
                }

                endIndex1 = i;
                endIndex2 = j;
                int begIndex1 = i - 1;
                int begIndex2 = j - 1;

                for (int k = 0; k < ipCount; k++) {
                    IntersectPoint ip = null;
                    if (!containsPoint(points[2*k], points[2*k + 1])) {
                        for (Iterator iter = isectPoints.iterator();
                        iter.hasNext(); ) {
                            ip = iter.next();
                            if ((begIndex1 == ip.getBegIndex(true)) &&
                                    (endIndex1 == ip.getEndIndex(true))) {

                                if (ip.getParam(true) > params[2*k]) {
                                    endIndex1 = - (isectPoints.indexOf(ip) + 1);
                                    ip.setBegIndex1(-(isectPoints.size() + 1));
                                } else {
                                    begIndex1 = - (isectPoints.indexOf(ip) + 1);
                                    ip.setEndIndex1(-(isectPoints.size() + 1));
                                }
                            }

                            if ((begIndex2 == ip.getBegIndex(false)) &&
                                    (endIndex2 == ip.getEndIndex(false))) {

                                if (ip.getParam(false) > params[2*k + 1]) {
                                    endIndex2 = - (isectPoints.indexOf(ip) + 1);
                                    ip.setBegIndex2(-(isectPoints.size() + 1));
                                } else {
                                    begIndex2 = - (isectPoints.indexOf(ip) + 1);
                                    ip.setEndIndex2(-(isectPoints.size() + 1));
                                }
                            }
                        }

                        if (rule1 == PathIterator.SEG_CLOSE) {
                            rule1 = PathIterator.SEG_LINETO;
                        }

                        if (rule2 == PathIterator.SEG_CLOSE) {
                            rule2 = PathIterator.SEG_LINETO;
                        }

                        isectPoints.add(new IntersectPoint(begIndex1, endIndex1,
                                rule1, i,
                                begIndex2, endIndex2,
                                rule2, j,
                                points[2*k], points[2*k + 1],
                                params[2*k], params[2*k + 1]));
                    }
                }
            }
        }
        return isectPoints.toArray(new IntersectPoint[isectPoints.size()]);
    }

    private int getCurrentEdge(int areaIndex, int index,
            double[] c, double[] mp, double[] cp) {
        int endIndex = 0;

        switch (rules[areaIndex][index]) {
        case PathIterator.SEG_MOVETO:
            cp[0] = mp[0] = coords[areaIndex][offsets[areaIndex][index]];
            cp[1] = mp[1] = coords[areaIndex][offsets[areaIndex][index] + 1];
            break;
        case PathIterator.SEG_LINETO:
            c[0] = cp[0];
            c[1] = cp[1];
            cp[0] = c[2] = coords[areaIndex][offsets[areaIndex][index]];
            cp[1] = c[3] = coords[areaIndex][offsets[areaIndex][index] + 1];
            endIndex = 0;
            break;
        case PathIterator.SEG_QUADTO:
            c[0] = cp[0];
            c[1] = cp[1];
            c[2] = coords[areaIndex][offsets[areaIndex][index]];
            c[3] = coords[areaIndex][offsets[areaIndex][index] + 1];
            cp[0] = c[4] = coords[areaIndex][offsets[areaIndex][index] + 2];
            cp[1] = c[5] = coords[areaIndex][offsets[areaIndex][index] + 3];
            endIndex = 2;
            break;
        case PathIterator.SEG_CUBICTO:
            c[0] = cp[0];
            c[1] = cp[1];
            c[2] = coords[areaIndex][offsets[areaIndex][index]];
            c[3] = coords[areaIndex][offsets[areaIndex][index] + 1];
            c[4] = coords[areaIndex][offsets[areaIndex][index] + 2];
            c[5] = coords[areaIndex][offsets[areaIndex][index] + 3];
            cp[0] = c[6] = coords[areaIndex][offsets[areaIndex][index] + 4];
            cp[1] = c[7] = coords[areaIndex][offsets[areaIndex][index] + 5];
            endIndex = 4;
            break;
        case PathIterator.SEG_CLOSE:
            c[0] = cp[0];
            c[1] = cp[1];
            cp[0] = c[2] = mp[0];
            cp[1] = c[3] = mp[1];
            if (offsets[areaIndex][index] >= sizes[areaIndex]) {
                endIndex = -sizes[areaIndex];
            } else {
                endIndex = 0;
            }
            break;
        }
        return offsets[areaIndex][index] + endIndex;
    }

    private boolean containsPoint(double x, double y) {
        IntersectPoint ipoint;

        for (Iterator i = isectPoints.iterator(); i.hasNext(); ) {
            ipoint = i.next();

            if ((Math.abs(ipoint.getX() - x) < Math.pow(10, -6)) &&
                    (Math.abs(ipoint.getY() - y) < Math.pow(10, -6))) {
                return true;
            }
        }

        return false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy