/*- * 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 . */ 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.datastructure.Vertex; public class CDPolygonNs extends PolygonNs { private List> innerHalfEdges = new ArrayList<>(); public static CDPolygonNs of(Polygon p, Map pointMap) { List> loopCoordinates = new ArrayList<>(); List edgeExtRing = createCoordinatesFromRing(pointMap, p.getExteriorRing().getVertices()); loopCoordinates.add(edgeExtRing); for (LinearRing innerRing : p.getInnerRings()) { List edgeInnerRing = createCoordinatesFromRing(pointMap, innerRing.getVertices()); loopCoordinates.add(edgeInnerRing); } List> halfEdges = new ArrayList<>(); for (List ringCoordinates : loopCoordinates) { List currHeList = createHalfEdgesFromCoordinates(ringCoordinates); halfEdges.add(currHeList); } return new CDPolygonNs(halfEdges, p); } private static List createHalfEdgesFromCoordinates(List ringCoordinates) { List 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 createCoordinatesFromRing(Map pointMap, List vertices) { List edgeRing = new ArrayList<>(); for (int i = 0; i < vertices.size() - 1; i++) { Vertex 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> halfEdges, Polygon original) { super(halfEdges.get(0), original); for (int i = 1; i < halfEdges.size(); i++) { List loopEdges = halfEdges.get(i); for (HalfEdge e : loopEdges) { addChild(e); } innerHalfEdges.add(loopEdges); } } public List> getInnerHalfEdges() { return innerHalfEdges; } }