/******************************************************************************* * Copyright (c) 2011, 2015 itemis AG and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Alexander Nyßen (itemis AG) - initial API and implementation * Matthias Wienand (itemis AG) - contribution for Bugzilla #355997 * *******************************************************************************/ package org.eclipse.gef.geometry.internal.utils; import org.eclipse.gef.geometry.planar.Line; import org.eclipse.gef.geometry.planar.Point; import org.eclipse.gef.geometry.planar.Polygon; import org.eclipse.gef.geometry.planar.Polyline; /** * Common utilities for point manipulations as needed e.g. within * {@link Polygon} and {@link Polyline}. * * @author anyssen * @author mwienand * */ public class PointListUtils { /** * Converts a given array of {@link Point} into an array of doubles * containing the x and y coordinates of the given points, where the x and y * coordinates of the n-th {@link Point} can be found at positions 2*n and * 2*n+1. * * @param points * an array of {@link Point}s to convert * @return a new array of doubles, containing the x and y coordinates of the * given {@link Point}s */ public static double[] toCoordinatesArray(Point[] points) { if (points == null || points.length == 0) { return new double[] {}; } double[] coordinates = new double[points.length * 2]; for (int i = 0; i < points.length; i++) { coordinates[i * 2] = points[i].x; coordinates[i * 2 + 1] = points[i].y; } return coordinates; } /** * Converts an array of double values into an array of integer values by * casting them. * * @param doubles * an array of doubles to convert * @return a new array of integer values, which is created by casting the * double values */ public static int[] toIntegerArray(double[] doubles) { if (doubles == null || doubles.length == 0) { return new int[] {}; } int[] ints = new int[doubles.length]; for (int i = 0; i < doubles.length; i++) { ints[i] = (int) doubles[i]; } return ints; } /** * Converts a given array of x/y coordinate values into an array of * {@link Point}s. * * @param coordinates * The array of coordinates. * @return a new array of {@link Point}s, representing the given x and y * coordinates */ public static Point[] toPointsArray(double[] coordinates) { if (coordinates.length % 2 != 0) { throw new IllegalArgumentException( "The coordinates array may not have an odd number of items."); } Point[] points = new Point[coordinates.length / 2]; for (int i = 0; i < points.length; i++) { points[i] = new Point(coordinates[2 * i], coordinates[2 * i + 1]); } return points; } /** * Transforms a sequence of {@link Line}s into a list of {@link Point}s. * Consecutive {@link Line}s are expected to share one of their end * {@link Point}s. The start {@link Point}s of the {@link Line}s are * returned. Additionally, the end {@link Point} of the last {@link Line} is * returned, too if the given boolean flag <code>open</code> is set to * <code>false</code>. * * @param segmentsArray * The array of {@link Line}s. * @param open * indicates whether to omit the end {@link Point} of the last * {@link Line} * @return the start {@link Point}s of the {@link Line}s and the end * {@link Point} of the last {@link Line} according to * <code>open</code> */ public static Point[] toPointsArray(Line[] segmentsArray, boolean open) { if (segmentsArray == null || segmentsArray.length == 0) { return new Point[] {}; } Point[] points = new Point[segmentsArray.length + (open ? 0 : 1)]; for (int i = 0; i < segmentsArray.length; i++) { points[i] = segmentsArray[i].getP1(); } if (!open) { points[points.length - 1] = segmentsArray[segmentsArray.length - 1] .getP2(); } return points; } /** * Transforms a sequence of {@link Point} coordinates into a sequence of * {@link Line} segments, by creating a {@link Line} segment for each two * adjacent points in the array. In case it is specified to close the * segment list, a {@link Line} segment is furthermore created between the * last and the first point in the list. * * @param points * the array of {@link Point}s to convert * @param close * a flag indicating whether a line segment will be created from * the last point in the list back to the first one * @return an array of {@link Line} segments, which is created by creating a * {@link Line} for each two adjacent {@link Point}s in the given * array, which includes a {@link Line} segment between the last * point in the given array in the first one, if and only if the * parameter close is given as <code>true</code> */ public static Line[] toSegmentsArray(Point[] points, boolean close) { // cannot construct lines for less than 2 points if (points == null || points.length < 2) { return new Line[] {}; } int segmentCount = close ? points.length : points.length - 1; Line[] segments = new Line[segmentCount]; for (int i = 0; i < segmentCount; i++) { segments[i] = new Line(points[i], points[i + 1 < points.length ? i + 1 : 0]); } return segments; } private PointListUtils() { // this class should not be instantiated by clients } }