Extend GeometryUtils, ArrayUtils (#662)
This commit is contained in:
parent
777d33a4de
commit
1f0b5509ed
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
* Copyright 2016 Andrey Novikov
|
||||
* Copyright 2017 Gustl22
|
||||
* Copyright 2017-2019 Gustl22
|
||||
*
|
||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||
*
|
||||
@ -18,6 +18,9 @@
|
||||
*/
|
||||
package org.oscim.core;
|
||||
|
||||
import org.oscim.utils.ArrayUtils;
|
||||
import org.oscim.utils.geom.GeometryUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/* TODO
|
||||
@ -450,22 +453,34 @@ public class GeometryBuffer {
|
||||
/**
|
||||
* Calculates geometry area, only polygon outer ring is taken into account.
|
||||
*
|
||||
* @return polygon area, 0 for other geometries
|
||||
* @return unsigned polygon area, 0 for other geometries
|
||||
*/
|
||||
public float area() {
|
||||
float area = isClockwise();
|
||||
return area < 0 ? -area : area;
|
||||
}
|
||||
|
||||
public float isClockwise() {
|
||||
if (isPoint() || isLine() || getNumPoints() < 3)
|
||||
return 0f;
|
||||
|
||||
float area = 0f;
|
||||
// use only outer ring
|
||||
int n = index[0];
|
||||
return GeometryUtils.isClockwise(points, index[0]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n - 2; i += 2) {
|
||||
area = area + (points[i] * points[i + 3]) - (points[i + 1] * points[i + 2]);
|
||||
/**
|
||||
* Reverse the order of points for lines and polygons.
|
||||
*/
|
||||
public void reverse() {
|
||||
if (isLine() || isPoly()) {
|
||||
int count = 0;
|
||||
for (int num : index) {
|
||||
if (num < 0)
|
||||
break;
|
||||
ArrayUtils.reverse(points, count, count + num, 2);
|
||||
count += num;
|
||||
}
|
||||
}
|
||||
area = area + (points[n - 2] * points[1]) - (points[n - 1] * points[0]);
|
||||
|
||||
return 0.5f * area;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -317,6 +317,8 @@ public final class S3DBUtils {
|
||||
public static boolean calcPyramidalMesh(GeometryBuffer element, float minHeight, float maxHeight) {
|
||||
float[] points = element.points;
|
||||
int[] index = element.index;
|
||||
float[] topPoint = new float[3];
|
||||
topPoint[2] = maxHeight;
|
||||
|
||||
for (int i = 0, pointPos = 0; i < index.length; i++) {
|
||||
if (index[i] < 0) {
|
||||
@ -327,27 +329,13 @@ public final class S3DBUtils {
|
||||
int numPoints = index[i] / 2;
|
||||
if (numPoints < 0) continue;
|
||||
|
||||
float centerX = 0;
|
||||
float centerY = 0;
|
||||
// Init top of roof (attention with pointPos)
|
||||
GeometryUtils.center(points, pointPos, numPoints << 1, topPoint);
|
||||
|
||||
List<float[]> point3Fs = new ArrayList<>();
|
||||
|
||||
// Calculate center and load points
|
||||
for (int j = 0; j < (numPoints * 2); j += 2, pointPos += 2) {
|
||||
float x = points[pointPos];
|
||||
float y = points[pointPos + 1];
|
||||
|
||||
point3Fs.add(new float[]{x, y, minHeight});
|
||||
|
||||
centerX += x;
|
||||
centerY += y;
|
||||
}
|
||||
|
||||
centerX = centerX / numPoints;
|
||||
centerY = centerY / numPoints;
|
||||
|
||||
// Init top of roof
|
||||
float[] topPoint = new float[]{centerX, centerY, maxHeight};
|
||||
// Load points
|
||||
for (int j = 0; j < (numPoints * 2); j += 2, pointPos += 2)
|
||||
point3Fs.add(new float[]{points[pointPos], points[pointPos + 1], minHeight});
|
||||
|
||||
// Write index: index gives the first point of triangle mesh (divided 3)
|
||||
int[] meshIndex = new int[numPoints * 3];
|
||||
@ -717,7 +705,7 @@ public final class S3DBUtils {
|
||||
if (Arrays.equals(ridgePoints.get(k), ridgePoints.get(secIndex)))
|
||||
ridgeSkipFaceIndex.add(k);
|
||||
}
|
||||
if (isClockwise > 0 && IMPROVE_RIDGE_CALCULATION) {
|
||||
if (isClockwise < 0 && IMPROVE_RIDGE_CALCULATION) {
|
||||
// TODO Improve handling of counter clockwise faces and support multiple faces
|
||||
isTessellateAble = false;
|
||||
break;
|
||||
@ -862,7 +850,7 @@ public final class S3DBUtils {
|
||||
}
|
||||
}
|
||||
// Scale of normal vec
|
||||
maxDist = Math.signum(GeometryUtils.isTrisClockwise(
|
||||
maxDist = -Math.signum(GeometryUtils.isTrisClockwise(
|
||||
pL,
|
||||
GeometryUtils.sumVec(pL, vL),
|
||||
splitLinePoint)) * (maxDist / 2);
|
||||
@ -878,7 +866,7 @@ public final class S3DBUtils {
|
||||
List<float[]> elementPoints2 = new ArrayList<>();
|
||||
float[] secSplitPoint = GeometryUtils.sumVec(splitLinePoint, vL);
|
||||
float sideLastPoint = Math.signum(GeometryUtils.isTrisClockwise(splitLinePoint, secSplitPoint, point3Fs.get(groundSize - 1)));
|
||||
degreeNormL = sideLastPoint > 0 ? degreeNormL : (degreeNormL + 180f) % 360; // Correct angle
|
||||
degreeNormL = sideLastPoint < 0 ? degreeNormL : (degreeNormL + 180f) % 360; // Correct angle
|
||||
List<Integer> intersection1 = new ArrayList<>(), intersection2 = new ArrayList<>();
|
||||
for (int k = 0; k < groundSize; k++) {
|
||||
// If point is not on the same side as the previous point, the split line intersect and can calc split point
|
||||
|
@ -457,7 +457,7 @@ public class LwHttp implements HttpEngine {
|
||||
for (int n = val; n > 0; n = n / 10, i++)
|
||||
buf[pos + i] = (byte) ('0' + n % 10);
|
||||
|
||||
ArrayUtils.reverse(buf, pos, pos + i);
|
||||
ArrayUtils.reverse(buf, pos, pos + i, 1);
|
||||
|
||||
return pos + i;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
* Copyright 2019 Gustl22
|
||||
*
|
||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||
*
|
||||
@ -35,6 +36,32 @@ public class ArrayUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse an array.
|
||||
*
|
||||
* @param data the base array to be reversed
|
||||
* @param left the left index to be reversed
|
||||
* @param right the right index (excluded)
|
||||
* @param stride the stride
|
||||
*/
|
||||
public static <T> void reverse(T[] data, int left, int right, int stride) {
|
||||
right -= stride;
|
||||
|
||||
while (left < right) {
|
||||
for (int i = 0; i < stride; i++) {
|
||||
T tmp = data[left + i];
|
||||
data[left + i] = data[right + i];
|
||||
data[right + i] = tmp;
|
||||
}
|
||||
left += stride;
|
||||
right -= stride;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the array for primitive short.
|
||||
* see {@link #reverse(Object[], int, int, int)}
|
||||
*/
|
||||
public static void reverse(short[] data, int left, int right, int stride) {
|
||||
right -= stride;
|
||||
|
||||
@ -49,16 +76,39 @@ public class ArrayUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void reverse(byte[] data, int left, int right) {
|
||||
right -= 1;
|
||||
/**
|
||||
* Reverse the array for primitive float.
|
||||
* see {@link #reverse(Object[], int, int, int)}
|
||||
*/
|
||||
public static void reverse(float[] data, int left, int right, int stride) {
|
||||
right -= stride;
|
||||
|
||||
while (left < right) {
|
||||
byte tmp = data[left];
|
||||
data[left] = data[right];
|
||||
data[right] = tmp;
|
||||
for (int i = 0; i < stride; i++) {
|
||||
float tmp = data[left + i];
|
||||
data[left + i] = data[right + i];
|
||||
data[right + i] = tmp;
|
||||
}
|
||||
left += stride;
|
||||
right -= stride;
|
||||
}
|
||||
}
|
||||
|
||||
left++;
|
||||
right--;
|
||||
/**
|
||||
* Reverse the array for primitive byte.
|
||||
* see {@link #reverse(Object[], int, int, int)}
|
||||
*/
|
||||
public static void reverse(byte[] data, int left, int right, int stride) {
|
||||
right -= stride;
|
||||
|
||||
while (left < right) {
|
||||
for (int i = 0; i < stride; i++) {
|
||||
byte tmp = data[left + i];
|
||||
data[left + i] = data[right + i];
|
||||
data[right + i] = tmp;
|
||||
}
|
||||
left += stride;
|
||||
right -= stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,16 @@ public final class GeometryUtils {
|
||||
return inside;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsigned area of polygon.
|
||||
*
|
||||
* @param n number of points
|
||||
*/
|
||||
public static float area(float[] points, int n) {
|
||||
float area = isClockwise(points, n);
|
||||
return area < 0 ? -area : area;
|
||||
}
|
||||
|
||||
public static float area(float ax, float ay, float bx, float by, float cx, float cy) {
|
||||
|
||||
float area = ((ax - cx) * (by - cy)
|
||||
@ -107,6 +117,33 @@ public final class GeometryUtils {
|
||||
return bisection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the center of a set of points.
|
||||
*
|
||||
* @param points the points array
|
||||
* @param pointPos the start position of points
|
||||
* @param n the number of points
|
||||
* @param out the center output
|
||||
* @return the center of points
|
||||
*/
|
||||
public static float[] center(float[] points, int pointPos, int n, float[] out) {
|
||||
if (out == null)
|
||||
out = new float[2];
|
||||
|
||||
// Calculate center
|
||||
for (int i = 0; i < n; i += 2, pointPos += 2) {
|
||||
float x = points[pointPos];
|
||||
float y = points[pointPos + 1];
|
||||
|
||||
out[0] += x;
|
||||
out[1] += y;
|
||||
}
|
||||
out[0] = out[0] * 2 / n;
|
||||
out[1] = out[1] * 2 / n;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param a first vector
|
||||
* @param b second vector
|
||||
@ -273,11 +310,34 @@ public final class GeometryUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a positive value, if pA-pB-pC makes a counter-clockwise turn,
|
||||
* negative for clockwise turn, and zero if the points are collinear.
|
||||
* Is polygon clockwise.
|
||||
*
|
||||
* @param points the points array
|
||||
* @param n the number of points
|
||||
* @return the signed area of the polygon
|
||||
* positive: clockwise
|
||||
* negative: counter-clockwise
|
||||
* 0: collinear
|
||||
*/
|
||||
public static float isClockwise(float[] points, int n) {
|
||||
float area = 0f;
|
||||
for (int i = 0; i < n - 2; i += 2) {
|
||||
area += (points[i] * points[i + 3]) - (points[i + 1] * points[i + 2]);
|
||||
}
|
||||
area += (points[n - 2] * points[1]) - (points[n - 1] * points[0]);
|
||||
|
||||
return 0.5f * area;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the turn of tris pA-pB-pC.
|
||||
*
|
||||
* @return positive: clockwise
|
||||
* negative: counter-clockwise
|
||||
* 0: collinear
|
||||
*/
|
||||
public static float isTrisClockwise(float[] pA, float[] pB, float[] pC) {
|
||||
return (pB[0] - pA[0]) * (pC[1] - pA[1]) - (pB[1] - pA[1]) * (pC[0] - pA[0]);
|
||||
return (pB[1] - pA[1]) * (pC[0] - pA[0]) - (pB[0] - pA[0]) * (pC[1] - pA[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user