Extend GeometryUtils, ArrayUtils (#662)
This commit is contained in:
parent
777d33a4de
commit
1f0b5509ed
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016 Andrey Novikov
|
* Copyright 2016 Andrey Novikov
|
||||||
* Copyright 2017 Gustl22
|
* Copyright 2017-2019 Gustl22
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@ -18,6 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.core;
|
package org.oscim.core;
|
||||||
|
|
||||||
|
import org.oscim.utils.ArrayUtils;
|
||||||
|
import org.oscim.utils.geom.GeometryUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/* TODO
|
/* TODO
|
||||||
@ -450,22 +453,34 @@ public class GeometryBuffer {
|
|||||||
/**
|
/**
|
||||||
* Calculates geometry area, only polygon outer ring is taken into account.
|
* 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() {
|
public float area() {
|
||||||
|
float area = isClockwise();
|
||||||
|
return area < 0 ? -area : area;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float isClockwise() {
|
||||||
if (isPoint() || isLine() || getNumPoints() < 3)
|
if (isPoint() || isLine() || getNumPoints() < 3)
|
||||||
return 0f;
|
return 0f;
|
||||||
|
|
||||||
float area = 0f;
|
|
||||||
// use only outer ring
|
// 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() {
|
public String toString() {
|
||||||
|
@ -317,6 +317,8 @@ public final class S3DBUtils {
|
|||||||
public static boolean calcPyramidalMesh(GeometryBuffer element, float minHeight, float maxHeight) {
|
public static boolean calcPyramidalMesh(GeometryBuffer element, float minHeight, float maxHeight) {
|
||||||
float[] points = element.points;
|
float[] points = element.points;
|
||||||
int[] index = element.index;
|
int[] index = element.index;
|
||||||
|
float[] topPoint = new float[3];
|
||||||
|
topPoint[2] = maxHeight;
|
||||||
|
|
||||||
for (int i = 0, pointPos = 0; i < index.length; i++) {
|
for (int i = 0, pointPos = 0; i < index.length; i++) {
|
||||||
if (index[i] < 0) {
|
if (index[i] < 0) {
|
||||||
@ -327,27 +329,13 @@ public final class S3DBUtils {
|
|||||||
int numPoints = index[i] / 2;
|
int numPoints = index[i] / 2;
|
||||||
if (numPoints < 0) continue;
|
if (numPoints < 0) continue;
|
||||||
|
|
||||||
float centerX = 0;
|
// Init top of roof (attention with pointPos)
|
||||||
float centerY = 0;
|
GeometryUtils.center(points, pointPos, numPoints << 1, topPoint);
|
||||||
|
|
||||||
List<float[]> point3Fs = new ArrayList<>();
|
List<float[]> point3Fs = new ArrayList<>();
|
||||||
|
// Load points
|
||||||
// Calculate center and load points
|
for (int j = 0; j < (numPoints * 2); j += 2, pointPos += 2)
|
||||||
for (int j = 0; j < (numPoints * 2); j += 2, pointPos += 2) {
|
point3Fs.add(new float[]{points[pointPos], points[pointPos + 1], minHeight});
|
||||||
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};
|
|
||||||
|
|
||||||
// Write index: index gives the first point of triangle mesh (divided 3)
|
// Write index: index gives the first point of triangle mesh (divided 3)
|
||||||
int[] meshIndex = new int[numPoints * 3];
|
int[] meshIndex = new int[numPoints * 3];
|
||||||
@ -717,7 +705,7 @@ public final class S3DBUtils {
|
|||||||
if (Arrays.equals(ridgePoints.get(k), ridgePoints.get(secIndex)))
|
if (Arrays.equals(ridgePoints.get(k), ridgePoints.get(secIndex)))
|
||||||
ridgeSkipFaceIndex.add(k);
|
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
|
// TODO Improve handling of counter clockwise faces and support multiple faces
|
||||||
isTessellateAble = false;
|
isTessellateAble = false;
|
||||||
break;
|
break;
|
||||||
@ -862,7 +850,7 @@ public final class S3DBUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Scale of normal vec
|
// Scale of normal vec
|
||||||
maxDist = Math.signum(GeometryUtils.isTrisClockwise(
|
maxDist = -Math.signum(GeometryUtils.isTrisClockwise(
|
||||||
pL,
|
pL,
|
||||||
GeometryUtils.sumVec(pL, vL),
|
GeometryUtils.sumVec(pL, vL),
|
||||||
splitLinePoint)) * (maxDist / 2);
|
splitLinePoint)) * (maxDist / 2);
|
||||||
@ -878,7 +866,7 @@ public final class S3DBUtils {
|
|||||||
List<float[]> elementPoints2 = new ArrayList<>();
|
List<float[]> elementPoints2 = new ArrayList<>();
|
||||||
float[] secSplitPoint = GeometryUtils.sumVec(splitLinePoint, vL);
|
float[] secSplitPoint = GeometryUtils.sumVec(splitLinePoint, vL);
|
||||||
float sideLastPoint = Math.signum(GeometryUtils.isTrisClockwise(splitLinePoint, secSplitPoint, point3Fs.get(groundSize - 1)));
|
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<>();
|
List<Integer> intersection1 = new ArrayList<>(), intersection2 = new ArrayList<>();
|
||||||
for (int k = 0; k < groundSize; k++) {
|
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
|
// 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++)
|
for (int n = val; n > 0; n = n / 10, i++)
|
||||||
buf[pos + i] = (byte) ('0' + n % 10);
|
buf[pos + i] = (byte) ('0' + n % 10);
|
||||||
|
|
||||||
ArrayUtils.reverse(buf, pos, pos + i);
|
ArrayUtils.reverse(buf, pos, pos + i, 1);
|
||||||
|
|
||||||
return pos + i;
|
return pos + i;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
* Copyright 2019 Gustl22
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* 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) {
|
public static void reverse(short[] data, int left, int right, int stride) {
|
||||||
right -= 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) {
|
while (left < right) {
|
||||||
byte tmp = data[left];
|
for (int i = 0; i < stride; i++) {
|
||||||
data[left] = data[right];
|
float tmp = data[left + i];
|
||||||
data[right] = tmp;
|
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;
|
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) {
|
public static float area(float ax, float ay, float bx, float by, float cx, float cy) {
|
||||||
|
|
||||||
float area = ((ax - cx) * (by - cy)
|
float area = ((ax - cx) * (by - cy)
|
||||||
@ -107,6 +117,33 @@ public final class GeometryUtils {
|
|||||||
return bisection;
|
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 a first vector
|
||||||
* @param b second 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,
|
* Is polygon clockwise.
|
||||||
* negative for clockwise turn, and zero if the points are collinear.
|
*
|
||||||
|
* @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) {
|
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