Commit 81be0b1d authored by Riegel's avatar Riegel
Browse files

Merge branch 'dev_GUI' into 'dev'

Open source release of CityDoctorGUI and other extensions.

See merge request !6
parents 12d96d95 5a4d0a74
Pipeline #10056 passed with stage
in 1 minute and 6 seconds
/CityDoctorParent/.idea/.gitignore
/CityDoctorParent/.idea/compiler.xml
/CityDoctorParent/.idea/encodings.xml
/CityDoctorParent/.idea/jarRepositories.xml
/CityDoctorParent/.idea/misc.xml
/CityDoctorParent/.idea/vcs.xml
......@@ -4,7 +4,7 @@ image: maven:3.8.6-eclipse-temurin-17
build:
script:
- cd CityDoctorParent
- mvn verify
- mvn verify -U
artifacts:
when: always
reports:
......
......@@ -303,3 +303,8 @@ gradle-app.setting
*.hprof
# End of https://www.toptal.com/developers/gitignore/api/gradle
/CityDoctorWebService/CityDoctorWebService.iml
/Extensions/CityDoctorWebService/CityDoctorWebService.iml
/.idea/codeStyles/codeStyleConfig.xml
/GUISettings.properties
/.idea/inspectionProfiles/Project_Default.xml
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId>
......
......@@ -18,8 +18,11 @@
*/
package de.hft.stuttgart.citydoctor2.checkresult.utility;
import java.io.Serial;
public class CheckReportParseException extends Exception {
@Serial
private static final long serialVersionUID = 6043371305010386110L;
public CheckReportParseException() {
......
......@@ -18,8 +18,11 @@
*/
package de.hft.stuttgart.citydoctor2.checkresult.utility;
import java.io.Serial;
public class CheckReportWriteException extends Exception {
@Serial
private static final long serialVersionUID = 1769358555887675233L;
public CheckReportWriteException() {
......
......@@ -34,7 +34,7 @@ public class IndentationXmlStreamWriter implements XMLStreamWriter {
private static final String INDENTATION = " ";
private XMLStreamWriter writer;
private final XMLStreamWriter writer;
private int depth = -1;
boolean sameElement = true;
......
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId>
......
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class BaseEntity {
private List<BaseEntity> parents = new ArrayList<>(2);
private List<BaseEntity> children = new ArrayList<>(2);
public void addChild(BaseEntity e) {
children.add(e);
e.parents.add(this);
}
@SuppressWarnings("unchecked")
public <T> List<T> getParents(Class<T> clazz) {
Set<T> result = new HashSet<>();
for (BaseEntity b : parents) {
if (clazz.isAssignableFrom(b.getClass())) {
result.add((T) b);
}
}
return new ArrayList<>(result);
}
@SuppressWarnings("unchecked")
public <T> List<T> getChildren(Class<T> clazz) {
List<T> result = new ArrayList<>();
for (BaseEntity b : children) {
if (b.getClass() == clazz) {
result.add((T) b);
}
}
return result;
}
public void removeChild(BaseEntity pEntity) {
children.remove(pEntity);
// check for multiple relationships
pEntity.parents.remove(this);
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class BaseEntity {
private final List<BaseEntity> parents = new ArrayList<>(2);
private final List<BaseEntity> children = new ArrayList<>(2);
public void addChild(BaseEntity e) {
children.add(e);
e.parents.add(this);
}
@SuppressWarnings("unchecked")
public <T> List<T> getParents(Class<T> clazz) {
Set<T> result = new HashSet<>();
for (BaseEntity b : parents) {
if (clazz.isAssignableFrom(b.getClass())) {
result.add((T) b);
}
}
return new ArrayList<>(result);
}
@SuppressWarnings("unchecked")
public <T> List<T> getChildren(Class<T> clazz) {
List<T> result = new ArrayList<>();
for (BaseEntity b : children) {
if (b.getClass() == clazz) {
result.add((T) b);
}
}
return result;
}
public void removeChild(BaseEntity pEntity) {
children.remove(pEntity);
// check for multiple relationships
pEntity.parents.remove(this);
}
}
......@@ -20,8 +20,8 @@ package de.hft.stuttgart.citydoctor2.edge;
public class Box2d {
private Point2d mMin;
private Point2d mMax;
private final Point2d mMin;
private final Point2d mMax;
public Box2d(Point2d min, Point2d max) {
mMin = min;
......
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.math.MovedPolygon;
import de.hft.stuttgart.citydoctor2.math.MovedRing;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
public class CDPolygonNs extends PolygonNs {
private List<List<HalfEdge>> innerHalfEdges = new ArrayList<>();
public static CDPolygonNs of(Polygon p, Map<Vector3d, Coordinate3d> pointMap) {
List<List<Coordinate3d>> loopCoordinates = new ArrayList<>();
List<Coordinate3d> edgeExtRing = createCoordinatesFromRing(pointMap, p.getExteriorRing().getVertices());
loopCoordinates.add(edgeExtRing);
for (LinearRing innerRing : p.getInnerRings()) {
List<Coordinate3d> edgeInnerRing = createCoordinatesFromRing(pointMap, innerRing.getVertices());
loopCoordinates.add(edgeInnerRing);
}
List<List<HalfEdge>> halfEdges = new ArrayList<>();
for (List<Coordinate3d> ringCoordinates : loopCoordinates) {
List<HalfEdge> currHeList = createHalfEdgesFromCoordinates(ringCoordinates);
halfEdges.add(currHeList);
}
return new CDPolygonNs(halfEdges, p);
}
public static CDPolygonNs of(MovedPolygon mp, Map<Vector3d, Coordinate3d> pointMap) {
List<List<Coordinate3d>> loopCoordinates = new ArrayList<>();
List<Coordinate3d> edgeExtRing = createCoordinatesFromRing(pointMap, mp.getExteriorRing().getVertices());
loopCoordinates.add(edgeExtRing);
for (MovedRing innerRing : mp.getInnerRings()) {
List<Coordinate3d> edgeInnerRing = createCoordinatesFromRing(pointMap, innerRing.getVertices());
loopCoordinates.add(edgeInnerRing);
}
List<List<HalfEdge>> halfEdges = new ArrayList<>();
for (List<Coordinate3d> ringCoordinates : loopCoordinates) {
List<HalfEdge> currHeList = createHalfEdgesFromCoordinates(ringCoordinates);
halfEdges.add(currHeList);
}
return new CDPolygonNs(halfEdges, mp.getOriginal());
}
private static List<HalfEdge> createHalfEdgesFromCoordinates(List<Coordinate3d> ringCoordinates) {
List<HalfEdge> currHeList = new ArrayList<>();
HalfEdge prevHalfEdge = null;
for (int currCoordIndex = 1; currCoordIndex < ringCoordinates.size(); currCoordIndex++) {
int prevCoordIndex = currCoordIndex - 1;
Coordinate3d currCoord = ringCoordinates.get(currCoordIndex);
Coordinate3d prevCoord = ringCoordinates.get(prevCoordIndex);
HalfEdge e = new HalfEdge(prevCoord, currCoord);
if (prevHalfEdge != null) {
prevHalfEdge.setNext(e);
}
currHeList.add(e);
prevHalfEdge = e;
}
if (prevHalfEdge == null) {
throw new IllegalStateException("No half edges were created");
}
Coordinate3d start = ringCoordinates.get(0);
Coordinate3d end = ringCoordinates.get(ringCoordinates.size() - 1);
HalfEdge e = new HalfEdge(end, start);
prevHalfEdge.setNext(e);
e.setNext(currHeList.get(0));
currHeList.add(e);
return currHeList;
}
private static List<Coordinate3d> createCoordinatesFromRing(Map<Vector3d, Coordinate3d> pointMap,
List<? extends Vector3d> vertices) {
List<Coordinate3d> edgeRing = new ArrayList<>();
for (int i = 0; i < vertices.size() - 1; i++) {
Vector3d v = vertices.get(i);
Coordinate3d c = pointMap.computeIfAbsent(v, key -> new Coordinate3d(key.getX(), key.getY(), key.getZ()));
edgeRing.add(c);
}
return edgeRing;
}
public CDPolygonNs(List<List<HalfEdge>> halfEdges, Polygon original) {
super(halfEdges.get(0), original);
for (int i = 1; i < halfEdges.size(); i++) {
List<HalfEdge> loopEdges = halfEdges.get(i);
for (HalfEdge e : loopEdges) {
addChild(e);
}
innerHalfEdges.add(loopEdges);
}
}
public List<List<HalfEdge>> getInnerHalfEdges() {
return innerHalfEdges;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.math.MovedPolygon;
import de.hft.stuttgart.citydoctor2.math.MovedRing;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
public class CDPolygonNs extends PolygonNs {
private final List<List<HalfEdge>> innerHalfEdges = new ArrayList<>();
public static CDPolygonNs of(Polygon p, Map<Vector3d, Coordinate3d> pointMap) {
List<List<Coordinate3d>> loopCoordinates = new ArrayList<>();
List<Coordinate3d> edgeExtRing = createCoordinatesFromRing(pointMap, p.getExteriorRing().getVertices());
loopCoordinates.add(edgeExtRing);
for (LinearRing innerRing : p.getInnerRings()) {
List<Coordinate3d> edgeInnerRing = createCoordinatesFromRing(pointMap, innerRing.getVertices());
loopCoordinates.add(edgeInnerRing);
}
List<List<HalfEdge>> halfEdges = new ArrayList<>();
for (List<Coordinate3d> ringCoordinates : loopCoordinates) {
List<HalfEdge> currHeList = createHalfEdgesFromCoordinates(ringCoordinates);
halfEdges.add(currHeList);
}
return new CDPolygonNs(halfEdges, p);
}
public static CDPolygonNs of(MovedPolygon mp, Map<Vector3d, Coordinate3d> pointMap) {
List<List<Coordinate3d>> loopCoordinates = new ArrayList<>();
List<Coordinate3d> edgeExtRing = createCoordinatesFromRing(pointMap, mp.getExteriorRing().getVertices());
loopCoordinates.add(edgeExtRing);
for (MovedRing innerRing : mp.getInnerRings()) {
List<Coordinate3d> edgeInnerRing = createCoordinatesFromRing(pointMap, innerRing.getVertices());
loopCoordinates.add(edgeInnerRing);
}
List<List<HalfEdge>> halfEdges = new ArrayList<>();
for (List<Coordinate3d> ringCoordinates : loopCoordinates) {
List<HalfEdge> currHeList = createHalfEdgesFromCoordinates(ringCoordinates);
halfEdges.add(currHeList);
}
return new CDPolygonNs(halfEdges, mp.getOriginal());
}
private static List<HalfEdge> createHalfEdgesFromCoordinates(List<Coordinate3d> ringCoordinates) {
List<HalfEdge> currHeList = new ArrayList<>();
HalfEdge prevHalfEdge = null;
for (int currCoordIndex = 1; currCoordIndex < ringCoordinates.size(); currCoordIndex++) {
int prevCoordIndex = currCoordIndex - 1;
Coordinate3d currCoord = ringCoordinates.get(currCoordIndex);
Coordinate3d prevCoord = ringCoordinates.get(prevCoordIndex);
HalfEdge e = new HalfEdge(prevCoord, currCoord);
if (prevHalfEdge != null) {
prevHalfEdge.setNext(e);
}
currHeList.add(e);
prevHalfEdge = e;
}
if (prevHalfEdge == null) {
throw new IllegalStateException("No half edges were created");
}
Coordinate3d start = ringCoordinates.get(0);
Coordinate3d end = ringCoordinates.get(ringCoordinates.size() - 1);
HalfEdge e = new HalfEdge(end, start);
prevHalfEdge.setNext(e);
e.setNext(currHeList.get(0));
currHeList.add(e);
return currHeList;
}
private static List<Coordinate3d> createCoordinatesFromRing(Map<Vector3d, Coordinate3d> pointMap,
List<? extends Vector3d> vertices) {
List<Coordinate3d> edgeRing = new ArrayList<>();
for (int i = 0; i < vertices.size() - 1; i++) {
Vector3d v = vertices.get(i);
Coordinate3d c = pointMap.computeIfAbsent(v, key -> new Coordinate3d(key.getX(), key.getY(), key.getZ()));
edgeRing.add(c);
}
return edgeRing;
}
public CDPolygonNs(List<List<HalfEdge>> halfEdges, Polygon original) {
super(halfEdges.get(0), original);
for (int i = 1; i < halfEdges.size(); i++) {
List<HalfEdge> loopEdges = halfEdges.get(i);
for (HalfEdge e : loopEdges) {
addChild(e);
}
innerHalfEdges.add(loopEdges);
}
}
public List<List<HalfEdge>> getInnerHalfEdges() {
return innerHalfEdges;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Coordinate3d extends BaseEntity {
private Point3d point;
public Coordinate3d(Point3d point) {
this.point = point;
}
public Coordinate3d(double x, double y, double z) {
this(new Point3d(x, y, z));
}
public Point3d getPoint() {
return point;
}
public List<EdgePolygon> getPolygons() {
List<HalfEdge> halfEdges = getParents(HalfEdge.class);
Set<EdgePolygon> polygons = new HashSet<>();
for (HalfEdge he : halfEdges) {
List<EdgePolygon> localPolygons = he.getParents(EdgePolygon.class);
polygons.addAll(localPolygons);
}
return new ArrayList<>(polygons);
}
@Override
public String toString() {
return "Coordinate3d [point=" + point + "]";
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Coordinate3d extends BaseEntity {
private final Point3d point;
public Coordinate3d(Point3d point) {
this.point = point;
}
public Coordinate3d(double x, double y, double z) {
this(new Point3d(x, y, z));
}
public Point3d getPoint() {
return point;
}
public List<EdgePolygon> getPolygons() {
List<HalfEdge> halfEdges = getParents(HalfEdge.class);
Set<EdgePolygon> polygons = new HashSet<>();
for (HalfEdge he : halfEdges) {
List<EdgePolygon> localPolygons = he.getParents(EdgePolygon.class);
polygons.addAll(localPolygons);
}
return new ArrayList<>(polygons);
}
@Override
public String toString() {
return "Coordinate3d [point=" + point + "]";
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.List;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
public class EdgePolygon extends BaseEntity {
private Polygon original;
private List<HalfEdge> halfEdges;
public EdgePolygon(List<HalfEdge> halfEdges, Polygon original) {
for (HalfEdge he : halfEdges) {
addChild(he);
}
this.halfEdges = halfEdges;
this.original = original;
}
public Polygon getOriginal() {
return original;
}
public GmPlane getPlane() {
Point3d midPoint = getMidPoint();
List<HalfEdge> children = getChildren(HalfEdge.class);
Vector3d averageNormalVector = new Vector3d(0.0, 0.0, 0.0);
for (HalfEdge he : children) {
Point3d start = he.getStart().getPoint();
Point3d end = he.getEnd().getPoint();
Vector3d mid2Start = start.minus(midPoint);
Vector3d mid2End = end.minus(midPoint);
averageNormalVector = averageNormalVector.plus(mid2Start.cross(mid2End));
}
UnitVector3d normalVector = averageNormalVector.toUnitVector();
return new GmPlane(midPoint, normalVector);
}
private Point3d getMidPoint() {
Point3d midPoint = new Point3d(0, 0, 0);
List<HalfEdge> children = getChildren(HalfEdge.class);
for (HalfEdge he : children) {
midPoint = midPoint.plus(he.getStart().getPoint());
}
return (midPoint.div(children.size()));
}
public List<HalfEdge> getHalfEdges() {
return halfEdges;
}
public List<Coordinate3d> getCoordinates() {
List<Coordinate3d> coords = new ArrayList<>();
for (HalfEdge he : halfEdges) {
coords.add(he.getStart());
}
// HalfEdge firstHE = Objects.requireNonNull(getFirstHalfEdge());
// HalfEdge currHE = firstHE;
// do {
// coords.add(currHE.getStart());
// currHE = currHE.getNext();
// } while (currHE != firstHE);
return coords;
}
public HalfEdge getFirstHalfEdge() {
if (!halfEdges.isEmpty()) {
return halfEdges.get(0);
}
return null;
}
/**
* Test whether the given point is lying in- or outside of the non self
* intersecting, planar polygon. It's believed, that point and polygon are lying
* in the same plane. <br>
* <br>
* It's assumed, that the polygon is non self intersecting and planar.
* Additionally it is assumed, that the point and the polygon lying in the same
* plane. The given point is projected on the plane of the polygon. If the point
* is lying on an edge of the polygon it's supposed that the point is inside of
* the polygon
*
* @param rcPoint The point that should be checked
*
* @return true, if the point is inside the polygon, false otherwise
*
*/
public boolean isPointInsidePolygon(Point3d rcPoint, double eps) {
// Project the coordinate of the point on the plane
GmPlane plane = getPlane();
Point2d projectedPoint = plane.project(rcPoint);
Polygon2d pP = plane.projectOn2dPolygon(this);
return pP.isPointInsidePolygon(projectedPoint, eps);
}
public int getNrHalfEdges() {
return halfEdges.size();
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.List;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
public class EdgePolygon extends BaseEntity {
private final Polygon original;
private final List<HalfEdge> halfEdges;
public EdgePolygon(List<HalfEdge> halfEdges, Polygon original) {
for (HalfEdge he : halfEdges) {
addChild(he);
}
this.halfEdges = halfEdges;
this.original = original;
}
public Polygon getOriginal() {
return original;
}
public GmPlane getPlane() {
Point3d midPoint = getMidPoint();
List<HalfEdge> children = getChildren(HalfEdge.class);
Vector3d averageNormalVector = new Vector3d(0.0, 0.0, 0.0);
for (HalfEdge he : children) {
Point3d start = he.getStart().getPoint();
Point3d end = he.getEnd().getPoint();
Vector3d mid2Start = start.minus(midPoint);
Vector3d mid2End = end.minus(midPoint);
averageNormalVector = averageNormalVector.plus(mid2Start.cross(mid2End));
}
UnitVector3d normalVector = averageNormalVector.toUnitVector();
return new GmPlane(midPoint, normalVector);
}
private Point3d getMidPoint() {
Point3d midPoint = new Point3d(0, 0, 0);
List<HalfEdge> children = getChildren(HalfEdge.class);
for (HalfEdge he : children) {
midPoint = midPoint.plus(he.getStart().getPoint());
}
return (midPoint.div(children.size()));
}
public List<HalfEdge> getHalfEdges() {
return halfEdges;
}
public List<Coordinate3d> getCoordinates() {
List<Coordinate3d> coords = new ArrayList<>();
for (HalfEdge he : halfEdges) {
coords.add(he.getStart());
}
return coords;
}
public HalfEdge getFirstHalfEdge() {
if (!halfEdges.isEmpty()) {
return halfEdges.get(0);
}
return null;
}
/**
* Test whether the given point is lying inside the non-self-
* intersecting, planar polygon. It's believed, that point and polygon are lying
* in the same plane. <br>
* <br>
* It's assumed, that the polygon is non-self-intersecting and planar, and that the point is
* lying in the same plane. The given point is projected on the plane of the polygon. If the point is lying on an edge
* of the polygon, it is considered to be inside.
*
* @param rcPoint The point that should be checked
*
* @return true, if the point is inside the polygon, false otherwise
*
*/
public boolean isPointInsidePolygon(Point3d rcPoint, double eps) {
// Project the coordinate of the point on the plane
GmPlane plane = getPlane();
Point2d projectedPoint = plane.project(rcPoint);
Polygon2d pP = plane.projectOn2dPolygon(this);
return pP.isPointInsidePolygon(projectedPoint, eps);
}
public int getNrHalfEdges() {
return halfEdges.size();
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.Comparator;
public class Global {
private static final double DBL_EPSILON = 2.2204460492503131e-16;
private static double mZeroAngleCosinus = 1.0e-9;
private static double mTolVectorsParallel = 1e-9;
private static double mHighAccuracyTol = DBL_EPSILON * 5;
private static double mTolPointsEqual = 1e-3;
private Global() {
}
public static double getTolPointsEquals() {
return mTolPointsEqual;
}
public static double getHighAccuracyTolerance() {
return mHighAccuracyTol;
}
public static Comparator<Double> getDoubleTolCompare(double epsilon) {
return (v1, v2) -> {
double dif = v1 - v2;
if (Math.abs(dif) < epsilon) {
return 0;
}
return Double.compare(v1, v2);
};
}
public static double getZeroAngleCosinus() {
return mZeroAngleCosinus;
}
public static double getTolVectorsParallel() {
return mTolVectorsParallel;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.Comparator;
public class Global {
private static final double DBL_EPSILON = 2.2204460492503131e-16;
private static final double M_ZERO_ANGLE_COSINE = 1.0e-9;
private static final double M_TOL_VECTORS_PARALLEL = 1e-9;
private static final double M_HIGH_ACCURACY_TOL = DBL_EPSILON * 5;
private static final double M_TOL_POINTS_EQUAL = 1e-3;
private Global() {
}
public static double getTolPointsEquals() {
return M_TOL_POINTS_EQUAL;
}
public static double getHighAccuracyTolerance() {
return M_HIGH_ACCURACY_TOL;
}
public static Comparator<Double> getDoubleTolCompare(double epsilon) {
return (v1, v2) -> {
double dif = v1 - v2;
if (Math.abs(dif) < epsilon) {
return 0;
}
return Double.compare(v1, v2);
};
}
public static double getZeroAngleCosine() { return M_ZERO_ANGLE_COSINE; }
public static double getTolVectorsParallel() {
return M_TOL_VECTORS_PARALLEL;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
public class GmBoundedStraight2d extends GmStraight2d {
private double length;
private Point2d target;
public static GmBoundedStraight2d of(Point2d start, Vector2d dir) {
GmBoundedStraight2d straight = new GmBoundedStraight2d(start, dir);
straight.target = straight.getOrigin().plus(dir);
straight.length = dir.getLength();
return straight;
}
public static GmBoundedStraight2d of(Point2d from, Point2d to) {
Vector2d dir = to.minus(from);
GmBoundedStraight2d straight = new GmBoundedStraight2d(from, dir);
straight.target = to;
straight.length = dir.getLength();
return straight;
}
private GmBoundedStraight2d(Point2d start, Vector2d dir) {
super(start, dir);
}
public Point2d getTarget() {
return target;
}
public boolean isWithinBoundaries(double parameter, double eps) {
if (Math.abs(parameter) < eps) {
parameter = 0.0;
}
if (Math.abs(parameter - length) < eps) {
parameter = length;
}
if (0 <= parameter && parameter <= length) {
return true;
}
return false;
}
public double getLength() {
return length;
}
public boolean isWithinBoundaries(double parameter) {
return isWithinBoundaries(parameter, Global.getHighAccuracyTolerance());
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
public class GmBoundedStraight2d extends GmStraight2d {
private double length;
private Point2d target;
public static GmBoundedStraight2d of(Point2d start, Vector2d dir) {
GmBoundedStraight2d straight = new GmBoundedStraight2d(start, dir);
straight.target = straight.getOrigin().plus(dir);
straight.length = dir.getLength();
return straight;
}
public static GmBoundedStraight2d of(Point2d from, Point2d to) {
Vector2d dir = to.minus(from);
GmBoundedStraight2d straight = new GmBoundedStraight2d(from, dir);
straight.target = to;
straight.length = dir.getLength();
return straight;
}
private GmBoundedStraight2d(Point2d start, Vector2d dir) {
super(start, dir);
}
public Point2d getTarget() {
return target;
}
public boolean isWithinBoundaries(double parameter, double eps) {
if (Math.abs(parameter) < eps) {
parameter = 0.0;
}
if (Math.abs(parameter - length) < eps) {
parameter = length;
}
return 0 <= parameter && parameter <= length;
}
public double getLength() {
return length;
}
public boolean isWithinBoundaries(double parameter) {
return isWithinBoundaries(parameter, Global.getHighAccuracyTolerance());
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.List;
public class GmPlane {
private Point3d x0;
private UnitVector3d r1;
private UnitVector3d r2;
private UnitVector3d n;
private double d;
public GmPlane(Point3d point, UnitVector3d normalVector) {
x0 = point;
n = normalVector;
d = new Vector3d(point).dot(n);
r1 = UnitVector3d.of(n.getZ(), n.getX(), n.getY());
r2 = n.cross(r1).toUnitVector();
// r1 ist nicht in allen Faellen rechtwinklig zur Flaechennormalen
// daher nochmal eine neu Berechnung;
// ----------------------------------------------------------------
r1 = n.cross(r2).toUnitVector();
}
public double getDistance() {
return d;
}
public Vector3d getNormal() {
return n;
}
public Point3d evaluate(Point2d point) {
return evaluate(point.getX(), point.getY());
}
private Point3d evaluate(double x, double y) {
Vector3d vectorU = r1.mult(x);
Vector3d vectorV = r2.mult(y);
return new Point3d(x0.plus(vectorU).plus(vectorV));
}
public GmStraight2d projectOn2dStraight(GmStraight crStraight) {
Point2d start = project(crStraight.getOrigin());
Point2d end = project(crStraight.getOrigin().plus(crStraight.getDir()));
return new GmStraight2d(start, end);
}
public GmBoundedStraight2d projectOn2dStraight(GmBoundedStraight crBoundedStraight) {
Point2d start = project(crBoundedStraight.getOrigin());
Point2d end = project(crBoundedStraight.getTarget());
return GmBoundedStraight2d.of(start, end);
}
public Point2d project(Point3d crPoint) {
GmStraight firstAxis = new GmStraight(x0, r1);
GmStraight secondAxis = new GmStraight(x0, r2);
double u = firstAxis.project(crPoint).getParameter();
double v = secondAxis.project(crPoint).getParameter();
return new Point2d(u, v);
}
public GmStraight planeIntersection(GmPlane other) {
// get plane normals and distances
// -------------------------------
Vector3d normal1 = getNormal();
Vector3d normal2 = other.getNormal();
double dist1 = getDistance();
double dist2 = other.getDistance();
// planes (normal vectors) parallel? -> good bye
// ---------------------------------------------
if (Vector3d.areParallel(normal1, normal2) || Vector3d.areAntiParallel(normal1, normal2)) {
return null; // but rSuccess is false
}
// get direction and origin for straight
// -------------------------------------
Vector3d dir = normal1.cross(normal2);
Matrix3d matrix = new Matrix3d();
matrix.set(0, 0, normal1.getX());
matrix.set(0, 1, normal1.getY());
matrix.set(0, 2, normal1.getZ());
matrix.set(1, 0, normal2.getX());
matrix.set(1, 1, normal2.getY());
matrix.set(1, 2, normal2.getZ());
matrix.set(2, 0, dir.getX());
matrix.set(2, 1, dir.getY());
matrix.set(2, 2, dir.getZ());
double[] b = new double[] { dist1, dist2, 0.0 };
double[] org = new double[3];
matrix.gauss(b, org);
return new GmStraight(new Point3d(org), dir);
}
public Polygon2d projectOn2dPolygon(EdgePolygon cpPolygon) {
HalfEdge startHE = cpPolygon.getFirstHalfEdge();
HalfEdge currHE = startHE;
int numHEs = cpPolygon.getNrHalfEdges();
Coordinate2d[] coords = new Coordinate2d[numHEs];
int i = 0;
do {
Coordinate3d coord = currHE.getStart();
Point2d p = project(coord.getPoint());
coords[i++] = new Coordinate2d(p);
currHE = currHE.getNext();
} while (currHE != startHE);
List<HalfEdge2d> halfedges = new ArrayList<>();
for (i = 0; i < numHEs; ++i) {
HalfEdge2d he = new HalfEdge2d(coords[i], coords[(i + 1) % (numHEs)]);
halfedges.add(he);
}
return new Polygon2d(halfedges);
}
public Point3d getPoint() {
return x0;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.List;
public class GmPlane {
private final Point3d x0;
private final UnitVector3d r1;
private final UnitVector3d r2;
private final UnitVector3d n;
private final double d;
public GmPlane(Point3d point, UnitVector3d normalVector) {
x0 = point;
n = normalVector;
d = new Vector3d(point).dot(n);
UnitVector3d r = UnitVector3d.of(n.getZ(), n.getX(), n.getY());
r2 = n.cross(r).toUnitVector();
// r is not always perpendicular to the plane's normal vector,
// recalculate using r2
// ----------------------------------------------------------------
r1 = n.cross(r2).toUnitVector();
}
public double getDistance() {
return d;
}
public Vector3d getNormal() {
return n;
}
public Point3d evaluate(Point2d point) {
return evaluate(point.getX(), point.getY());
}
private Point3d evaluate(double x, double y) {
Vector3d vectorU = r1.mult(x);
Vector3d vectorV = r2.mult(y);
return new Point3d(x0.plus(vectorU).plus(vectorV));
}
public GmStraight2d projectOn2dStraight(GmStraight crStraight) {
Point2d start = project(crStraight.getOrigin());
Point2d end = project(crStraight.getOrigin().plus(crStraight.getDir()));
return new GmStraight2d(start, end);
}
public GmBoundedStraight2d projectOn2dStraight(GmBoundedStraight crBoundedStraight) {
Point2d start = project(crBoundedStraight.getOrigin());
Point2d end = project(crBoundedStraight.getTarget());
return GmBoundedStraight2d.of(start, end);
}
public Point2d project(Point3d crPoint) {
GmStraight firstAxis = new GmStraight(x0, r1);
GmStraight secondAxis = new GmStraight(x0, r2);
double u = firstAxis.project(crPoint).getParameter();
double v = secondAxis.project(crPoint).getParameter();
return new Point2d(u, v);
}
public GmStraight planeIntersection(GmPlane other) {
// get plane normals and distances
// -------------------------------
Vector3d normal1 = getNormal();
Vector3d normal2 = other.getNormal();
double dist1 = getDistance();
double dist2 = other.getDistance();
// planes (normal vectors) parallel? -> good bye
// ---------------------------------------------
if (Vector3d.areParallel(normal1, normal2) || Vector3d.areAntiParallel(normal1, normal2)) {
return null; // but rSuccess is false
}
// get direction and origin for straight
// -------------------------------------
Vector3d dir = normal1.cross(normal2);
Matrix3d matrix = new Matrix3d();
matrix.set(0, 0, normal1.getX());
matrix.set(0, 1, normal1.getY());
matrix.set(0, 2, normal1.getZ());
matrix.set(1, 0, normal2.getX());
matrix.set(1, 1, normal2.getY());
matrix.set(1, 2, normal2.getZ());
matrix.set(2, 0, dir.getX());
matrix.set(2, 1, dir.getY());
matrix.set(2, 2, dir.getZ());
double[] b = new double[] { dist1, dist2, 0.0 };
double[] org = new double[3];
matrix.gauss(b, org);
return new GmStraight(new Point3d(org), dir);
}
public Polygon2d projectOn2dPolygon(EdgePolygon cpPolygon) {
HalfEdge startHE = cpPolygon.getFirstHalfEdge();
HalfEdge currHE = startHE;
int numHEs = cpPolygon.getNrHalfEdges();
Coordinate2d[] coords = new Coordinate2d[numHEs];
int i = 0;
do {
Coordinate3d coord = currHE.getStart();
Point2d p = project(coord.getPoint());
coords[i++] = new Coordinate2d(p);
currHE = currHE.getNext();
} while (currHE != startHE);
List<HalfEdge2d> halfedges = new ArrayList<>();
for (i = 0; i < numHEs; ++i) {
HalfEdge2d he = new HalfEdge2d(coords[i], coords[(i + 1) % (numHEs)]);
halfedges.add(he);
}
return new Polygon2d(halfedges);
}
public Point3d getPoint() {
return x0;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
public class GmStraight {
private Point3d org;
private UnitVector3d dir;
public GmStraight(Point3d org, Vector3d dir) {
this.org = org;
this.dir = dir.toUnitVector();
}
public GmStraight(Point3d org, UnitVector3d dir) {
this.org = org;
this.dir = dir;
}
public ProjectedPoint3d project(Point3d origin) {
Vector3d v2Origin = origin.minus(org);
double length = v2Origin.getLength();
if (length < Global.getTolPointsEquals()) {
return new ProjectedPoint3d(origin, 0.0);
}
double parameter = dir.dot(UnitVector3d.of(v2Origin)) * length;
Point3d foot = evaluate(parameter);
return new ProjectedPoint3d(foot, parameter);
}
public Point3d evaluate(double param) {
return org.plus(dir.mult(param));
}
public UnitVector3d getDir() {
return dir;
}
public boolean isColinear(GmStraight straight2, double angleEpsilon, double epsilon) {
UnitVector3d rDir1 = getDir();
UnitVector3d rDir2 = straight2.getDir();
if ((!Vector3d.areParallel(rDir1, rDir2, angleEpsilon))
&& (!Vector3d.areAntiParallel(rDir1, rDir2, angleEpsilon))) {
return false;
}
Point3d rOrigin1 = getOrigin();
Point3d foot1 = straight2.project(rOrigin1).getPoint();
if ((foot1.minus(rOrigin1)).getLength() > epsilon) {
return false;
}
Point3d rOrigin2 = straight2.getOrigin();
Point3d foot2 = project(rOrigin2).getPoint();
if ((foot2.minus(rOrigin2)).getLength() > epsilon) {
return false;
}
return true;
}
public Point3d getOrigin() {
return org;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
public class GmStraight {
private final Point3d org;
private final UnitVector3d dir;
public GmStraight(Point3d org, Vector3d dir) {
this.org = org;
this.dir = dir.toUnitVector();
}
public GmStraight(Point3d org, UnitVector3d dir) {
this.org = org;
this.dir = dir;
}
public ProjectedPoint3d project(Point3d origin) {
Vector3d v2Origin = origin.minus(org);
double length = v2Origin.getLength();
if (length < Global.getTolPointsEquals()) {
return new ProjectedPoint3d(origin, 0.0);
}
double parameter = dir.dot(UnitVector3d.of(v2Origin)) * length;
Point3d foot = evaluate(parameter);
return new ProjectedPoint3d(foot, parameter);
}
public Point3d evaluate(double param) {
return org.plus(dir.mult(param));
}
public UnitVector3d getDir() {
return dir;
}
public boolean isCollinear(GmStraight straight2, double angleEpsilon, double epsilon) {
UnitVector3d rDir1 = getDir();
UnitVector3d rDir2 = straight2.getDir();
if ((!Vector3d.areParallel(rDir1, rDir2, angleEpsilon))
&& (!Vector3d.areAntiParallel(rDir1, rDir2, angleEpsilon))) {
return false;
}
Point3d rOrigin1 = getOrigin();
Point3d foot1 = straight2.project(rOrigin1).getPoint();
if ((foot1.minus(rOrigin1)).getLength() > epsilon) {
return false;
}
Point3d rOrigin2 = straight2.getOrigin();
Point3d foot2 = project(rOrigin2).getPoint();
return ((foot2.minus(rOrigin2)).getLength() <= epsilon);
}
public Point3d getOrigin() {
return org;
}
}
......@@ -18,10 +18,12 @@
*/
package de.hft.stuttgart.citydoctor2.edge;
public class GmStraight2d {
private Point2d origin;
private UnitVector2d direction;
private final Point2d origin;
private final UnitVector2d direction;
public GmStraight2d(Point2d org, UnitVector2d dir) {
this.direction = dir;
......@@ -39,14 +41,13 @@ public class GmStraight2d {
}
/**
* Just intersects two GmStraights2d.
*
* Intersects this straight with another straight.
* <br>
* <br>
* If the two straights are parallel the method will return false, so the user
* has to determine, if the straight are just parallel or identical
* If the two straights are parallel, areParallel in the returned IntersectionResult will be true.
* This method will not differentiate between parallel and identical straights.
*
* @param other First Straight
* @param other the other straight
*
* @return intersection result
*/
......@@ -60,7 +61,7 @@ public class GmStraight2d {
Vector2d r2Perpendicular = r2.getPerpendicularVector();
double diff = r1.dot(r2Perpendicular);
if (Math.abs(diff) < Global.getZeroAngleCosinus()) {
if (Math.abs(diff) < Global.getZeroAngleCosine()) {
return GmStraight2dIntersectionResult.parallel(this, other);
} else {
double invR1DotPerpR2 = 1.0 / diff;
......
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
public class GmStraight2dIntersectionResult {
private double paramHE;
private double paramInt;
private GmStraight2d straightHE;
private GmStraight2d straightInt;
private boolean areParallel;
public static GmStraight2dIntersectionResult parallel(GmStraight2d s1, GmStraight2d s2) {
return new GmStraight2dIntersectionResult(0, 0, s1, s2, true);
}
public static GmStraight2dIntersectionResult intersecting(double paramHE, double paramInt, GmStraight2d straightHE,
GmStraight2d straightInt) {
return new GmStraight2dIntersectionResult(paramHE, paramInt, straightHE, straightInt, false);
}
private GmStraight2dIntersectionResult(double paramHE, double paramInt, GmStraight2d straightHE,
GmStraight2d straightInt, boolean areParallel) {
this.paramHE = paramHE;
this.paramInt = paramInt;
this.straightHE = straightHE;
this.straightInt = straightInt;
this.areParallel = areParallel;
}
public double getParamHE() {
return paramHE;
}
public double getParamInt() {
return paramInt;
}
public GmStraight2d getStraightHE() {
return straightHE;
}
public GmStraight2d getStraightInt() {
return straightInt;
}
public boolean areParallel() {
return areParallel;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
public record GmStraight2dIntersectionResult(double paramHE, double paramInt, GmStraight2d straightHE,
GmStraight2d straightInt, boolean areParallel) {
public static GmStraight2dIntersectionResult parallel(GmStraight2d s1, GmStraight2d s2) {
return new GmStraight2dIntersectionResult(0, 0, s1, s2, true);
}
public static GmStraight2dIntersectionResult intersecting(double paramHE, double paramInt, GmStraight2d straightHE,
GmStraight2d straightInt) {
return new GmStraight2dIntersectionResult(paramHE, paramInt, straightHE, straightInt, false);
}
}
......@@ -108,7 +108,7 @@ public class HalfEdge extends BaseEntity {
HalfEdge pNextPartner = this.partner;
while (pNextPartner != this) {
if (pNextPartner == partner) {
logger.debug("(HalfEdge " + partner + " already exits in chain");
logger.debug(String.format("(HalfEdge %s already exits in chain", partner));
return;
}
pNextPartner = pNextPartner.partner;
......@@ -141,7 +141,7 @@ public class HalfEdge extends BaseEntity {
pPreviousPartner.partner = this;
this.partner = partner;
} else {
/**
/*
* TODO : das riecht nach einer Ringverzeigerung : 3 Polygonraender treffen auf
* einander
*/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment