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

org.apache.harmony.awt.geom.CrossingHelper 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.ArrayList;
import java.util.Iterator;
import java.util.List;


public class CrossingHelper {

    private double[][] coords;
    private int[] sizes;
    private List isectPoints = new ArrayList();

    public CrossingHelper(double[][] coords, int[] sizes) {
        this.coords = coords;
        this.sizes = sizes;
    }

    public IntersectPoint[] findCrossing() {
        int pointCount1 = sizes[0] / 2;
        int pointCount2 = sizes[1] / 2;
        int[] indices = new int[pointCount1 + pointCount2];

        for(int i = 0; i < pointCount1 + pointCount2; i++) {
            indices[i] = i;
        }

        sort(coords[0], pointCount1, coords[1], pointCount2, indices);
        // the set for the shapes edges storing
        List edges = new ArrayList();
        Edge edge;
        int begIndex, endIndex;
        int areaNumber;

        for (int i = 0; i < indices.length; i++) {
            if (indices[i] < pointCount1) {
                begIndex = indices[i];
                endIndex = indices[i] - 1;

                if (endIndex < 0) {
                    endIndex = pointCount1 - 1;
                }

                areaNumber = 0;
            } else if (indices[i] < pointCount1 + pointCount2) {
                begIndex = indices[i] - pointCount1;
                endIndex = indices[i] - 1 - pointCount1;

                if (endIndex < 0) {
                    endIndex = pointCount2 - 1;
                }

                areaNumber = 1;
            } else {
                throw new IndexOutOfBoundsException();
            }

            if (!removeEdge(edges, begIndex, endIndex)) {
                edge = new Edge(begIndex, endIndex, areaNumber);
                intersectShape(edges, coords[0], pointCount1,
                        coords[1], pointCount2, edge);
                edges.add(edge);
            }

            begIndex = indices[i];
            endIndex = indices[i] + 1;

            if ((begIndex < pointCount1) && (endIndex == pointCount1)) {
                endIndex = 0;
            } else if ((begIndex >= pointCount1) &&
                    (endIndex == (pointCount2 + pointCount1))) {
                endIndex = pointCount1;
            }

            if (endIndex < pointCount1) {
                areaNumber = 0;
            } else {
                areaNumber = 1;
                endIndex -= pointCount1;
                begIndex -= pointCount1;
            }

            if (!removeEdge(edges, begIndex, endIndex)) {
                edge = new Edge(begIndex, endIndex, areaNumber);
                intersectShape(edges, coords[0], pointCount1,
                        coords[1], pointCount2, edge);
                edges.add(edge);
            }
        }

        return isectPoints.toArray(new IntersectPoint[isectPoints.size()]);
    }

    private boolean removeEdge(List edges,  int begIndex, int endIndex) {

        for (Edge edge : edges) {
            if (edge.reverseCompare(begIndex, endIndex)) {
                edges.remove(edge);
                return true;
            }
        }

        return false;
    }

    // return the quantity of intersect points
    private void intersectShape(List edges,
            double[] coords1, int length1,
            double[] coords2, int length2,
            Edge initEdge) {
        int areaOfEdge1, areaOfEdge2;
        int initBegin, initEnd;
        int addBegin, addEnd;
        double x1, y1, x2, y2, x3, y3, x4, y4;
        double[] point = new double[2];
        Edge edge;

        if (initEdge.areaNumber == 0) {
            x1 = coords1[2* initEdge.begIndex];
            y1 = coords1[2* initEdge.begIndex + 1];
            x2 = coords1[2* initEdge.endIndex];
            y2 = coords1[2* initEdge.endIndex + 1];
            areaOfEdge1 = 0;
        } else {
            x1 = coords2[2* initEdge.begIndex];
            y1 = coords2[2* initEdge.begIndex + 1];
            x2 = coords2[2* initEdge.endIndex];
            y2 = coords2[2* initEdge.endIndex + 1];
            areaOfEdge1 = 1;
        }

        for (Iterator iter = edges.iterator(); iter.hasNext(); ) {
            edge = iter.next();

            if (edge.areaNumber == 0) {
                x3 = coords1[2* edge.begIndex];
                y3 = coords1[2* edge.begIndex + 1];
                x4 = coords1[2* edge.endIndex];
                y4 = coords1[2* edge.endIndex + 1];
                areaOfEdge2 = 0;
            } else {
                x3 = coords2[2* edge.begIndex];
                y3 = coords2[2* edge.begIndex + 1];
                x4 = coords2[2* edge.endIndex];
                y4 = coords2[2* edge.endIndex + 1];
                areaOfEdge2 = 1;
            }

            if ((areaOfEdge1 != areaOfEdge2) &&
                    (GeometryUtil.intersectLines(
                            x1, y1, x2, y2, x3, y3, x4, y4, point) == 1) &&
                            (!containsPoint(point))) {

                if (initEdge.areaNumber == 0) {
                    initBegin = initEdge.begIndex;
                    initEnd = initEdge.endIndex;
                    addBegin = edge.begIndex;
                    addEnd = edge.endIndex;
                } else {
                    initBegin = edge.begIndex;
                    initEnd = edge.endIndex;
                    addBegin = initEdge.begIndex;
                    addEnd = initEdge.endIndex;
                }

                if (((initEnd == length1 - 1) &&
                        (initBegin == 0 && initEnd > initBegin)) ||
                        (((initEnd != length1 - 1) || (initBegin != 0)) &&
                                ((initBegin != length1 - 1) || (initEnd != 0)) &&
                                (initBegin > initEnd))) {

                    int temp = initBegin;
                    initBegin = initEnd;
                    initEnd = temp;
                }

                if (((addEnd == length2 - 1) && (addBegin == 0) && (addEnd > addBegin)) ||
                        (((addEnd != length2 - 1) || (addBegin != 0)) &&
                                ((addBegin != length2 - 1) || (addEnd != 0)) && (addBegin > addEnd))) {

                    int temp = addBegin;
                    addBegin = addEnd;
                    addEnd = temp;
                }

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

                    if ((initBegin == ip.getBegIndex(true)) &&
                            (initEnd == ip.getEndIndex(true))) {

                        if (compare(ip.getX(), ip.getY(), point[0], point[1]) > 0) {
                            initEnd = - (isectPoints.indexOf(ip) + 1);
                            ip.setBegIndex1(-(isectPoints.size() + 1));
                        } else {
                            initBegin = - (isectPoints.indexOf(ip) + 1);
                            ip.setEndIndex1(-(isectPoints.size() + 1));
                        }
                    }

                    if ((addBegin == ip.getBegIndex(false)) &&
                            (addEnd == ip.getEndIndex(false))) {

                        if (compare(ip.getX(), ip.getY(), point[0], point[1]) > 0) {
                            addEnd = - (isectPoints.indexOf(ip) + 1);
                            ip.setBegIndex2(-(isectPoints.size() + 1));
                        } else {
                            addBegin = - (isectPoints.indexOf(ip) + 1);
                            ip.setEndIndex2(-(isectPoints.size() + 1));
                        }
                    }
                }

                isectPoints.add(new IntersectPoint(initBegin, initEnd,
                        addBegin, addEnd,
                        point[0], point[1]));
            }
        }
    }

    // the array sorting
    private static void sort(double[] coords1, int length1,
            double[] coords2, int length2,
            int[] array) {
        int temp;
        int length = length1 + length2;
        double x1, y1, x2, y2;

        for (int i = 1; i < length; i++) {
            if (array[i-1] < length1) {
                x1 = coords1[2*array[i-1]];
                y1 = coords1[2*array[i-1] + 1];
            } else {
                x1 = coords2[2*(array[i-1] - length1)];
                y1 = coords2[2*(array[i-1] - length1) + 1];
            }
            if (array[i] < length1) {
                x2 = coords1[2*array[i]];
                y2 = coords1[2*array[i] + 1];
            } else {
                x2 = coords2[2*(array[i] - length1)];
                y2 = coords2[2*(array[i] - length1) + 1];
            }
            int j = i;
            while (j > 0 && compare(x1, y1, x2, y2) <= 0) {
                temp = array[j];
                array[j] = array[j-1];
                array[j-1] = temp;
                j--;
                if (j > 0) {
                    if (array[j-1] < length1) {
                        x1 = coords1[2*array[j-1]];
                        y1 = coords1[2*array[j-1] + 1];
                    } else {
                        x1 = coords2[2*(array[j-1] - length1)];
                        y1 = coords2[2*(array[j-1] - length1) + 1];
                    }
                    if (array[j] < length1) {
                        x2 = coords1[2*array[j]];
                        y2 = coords1[2*array[j] + 1];
                    } else {
                        x2 = coords2[2*(array[j] - length1)];
                        y2 = coords2[2*(array[j] - length1) + 1];
                    }
                }
            }
        }
    }

    public boolean containsPoint(double[] point) {
        IntersectPoint ipoint;

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

            if (ipoint.getX() == point[0] && ipoint.getY() == point[1]) {
                return true;
            }
        }

        return false;
    }

    public static int compare(double x1, double y1, double x2, double y2) {

        if ((x1 < x2) || (x1 == x2 && y1 < y2)) {
            return 1;
        } else if (x1 == x2 && y1 == y2) {
            return 0;
        }

        return -1;
    }

    private static final class Edge {
        final int begIndex;
        final int endIndex;
        final int areaNumber;

        Edge(int begIndex, int endIndex, int areaNumber) {
            this.begIndex = begIndex;
            this.endIndex = endIndex;
            this.areaNumber = areaNumber;
        }

        boolean reverseCompare (int begIndex, int endIndex) {
            return this.begIndex == endIndex && this.endIndex == begIndex;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy