Skip to content

Commit

Permalink
fix interpolation and normalize inserted polygons (this operation was…
Browse files Browse the repository at this point in the history
… removed from a point of time?)
  • Loading branch information
nicolas-f committed Oct 11, 2024
1 parent aa22a02 commit d0cc5d8
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -850,11 +850,12 @@ public PropagationPath computeHEdgeDiffraction(ProfileBuilder.CutProfile cutProf
pt.bodyBarrier = bodyBarrier;
if(pt.buildingId != -1) {
pt.alphaWall = data.profileBuilder.getBuilding(pt.buildingId).getAlphas();
pt.setBuildingHeight(data.profileBuilder.getBuilding(pt.buildingId).getHeight());
pt.setObstacleAltitude(data.profileBuilder.getBuilding(pt.buildingId).getZ());
}
else if(pt.wallId != -1) {
pt.alphaWall = data.profileBuilder.getWall(pt.wallId).getAlphas();
pt.setBuildingHeight(data.profileBuilder.getWall(pt.wallId).getHeight());
ProfileBuilder.Wall wall = data.profileBuilder.getWall(pt.wallId);
pt.setObstacleAltitude(Vertex.interpolateZ(pt.coordinate, wall.p0, wall.p1));
}
}
}
Expand Down Expand Up @@ -1216,6 +1217,21 @@ public static org.apache.commons.math3.geometry.euclidean.threed.Vector3D coordi
return new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(p.x, p.y, p.z);
}

private void updateReflectionPathAttributes(PointPath reflectionPoint, MirrorReceiverResult mirrorReceiverResult) {
reflectionPoint.setType(PointPath.POINT_TYPE.REFL);
if(mirrorReceiverResult.getType().equals(BUILDING)) {
reflectionPoint.setBuildingId(mirrorReceiverResult.getBuildingId());
reflectionPoint.obstacleAltitude = data.profileBuilder.getBuilding(reflectionPoint.getBuildingId()).getZ();
reflectionPoint.setAlphaWall(data.profileBuilder.getBuilding(reflectionPoint.getBuildingId()).getAlphas());
} else {
ProfileBuilder.Wall wall = mirrorReceiverResult.getWall();
reflectionPoint.obstacleAltitude = Vertex.interpolateZ(reflectionPoint.coordinate, wall.p0, wall.p1);
reflectionPoint.setWallId(wall.getProcessedWallIndex());
reflectionPoint.setAlphaWall(wall.getAlphas());
}
reflectionPoint.altitude = data.profileBuilder.getZGround(mirrorReceiverResult.getReceiverPos());
}

public List<PropagationPath> computeReflexion(Coordinate rcvCoord, Coordinate srcCoord, boolean favorable,
Orientation orientation, MirrorReceiverResultIndex receiverMirrorIndex) {

Expand All @@ -1238,7 +1254,7 @@ public List<PropagationPath> computeReflexion(Coordinate rcvCoord, Coordinate sr
linters.computeIntersection(seg.p0, seg.p1,
receiverReflection.getReceiverPos(),
destinationPt);
while (linters.hasIntersection() /*&& MirrorReceiverIterator.wallPointTest(seg.getLine(), destinationPt)*/) {
while (linters.hasIntersection()) {
// There are a probable reflection point on the segment
Coordinate reflectionPt = new Coordinate(
linters.getIntersection(0));
Expand Down Expand Up @@ -1328,17 +1344,7 @@ public List<PropagationPath> computeReflexion(Coordinate rcvCoord, Coordinate sr
}
PointPath reflPoint = points.get(points.size() - 1);
reflIdx.add(points.size() - 1);
reflPoint.setType(PointPath.POINT_TYPE.REFL);
if(rayPath.get(0).getType().equals(BUILDING)) {
reflPoint.setBuildingId(rayPath.get(0).getBuildingId());
reflPoint.buildingHeight = data.profileBuilder.getBuilding(reflPoint.getBuildingId()).getHeight();
reflPoint.setAlphaWall(data.profileBuilder.getBuilding(reflPoint.getBuildingId()).getAlphas());
} else {
reflPoint.buildingHeight = rayPath.get(0).getWall().p0.getZ();
reflPoint.setWallId(rayPath.get(0).getWall().getProcessedWallIndex());
reflPoint.setAlphaWall(rayPath.get(0).getWall().getAlphas());
}
reflPoint.altitude = data.profileBuilder.getZGround(rayPath.get(0).getReceiverPos());
updateReflectionPathAttributes(reflPoint, rayPath.get(0));
// Add intermediate reflections
for (int idPt = 0; idPt < rayPath.size() - 1; idPt++) {
MirrorReceiverResult firstPoint = rayPath.get(idPt);
Expand All @@ -1358,17 +1364,7 @@ public List<PropagationPath> computeReflexion(Coordinate rcvCoord, Coordinate sr
p.coordinate.x += points.get(previousPointSize - 1).coordinate.x;
}
PointPath lastReflexionPoint = points.get(points.size() - 1);
lastReflexionPoint.setType(PointPath.POINT_TYPE.REFL);
if(rayPath.get(0).getType().equals(BUILDING)) {
lastReflexionPoint.setBuildingId(secondPoint.getBuildingId());
lastReflexionPoint.buildingHeight = data.profileBuilder.getBuilding(reflPoint.getBuildingId()).getHeight();
lastReflexionPoint.setAlphaWall(data.profileBuilder.getBuilding(reflPoint.getBuildingId()).getAlphas());
} else {
lastReflexionPoint.buildingHeight = secondPoint.getWall().p0.getZ();
lastReflexionPoint.setWallId(secondPoint.getWall().getProcessedWallIndex());
lastReflexionPoint.setAlphaWall(secondPoint.getWall().getAlphas());
}
lastReflexionPoint.altitude = data.profileBuilder.getZGround(secondPoint.getReceiverPos());
updateReflectionPathAttributes(lastReflexionPoint, secondPoint);
}
// Compute direct path between receiver and last reflection point, add profile to the data
int previousPointSize = points.size();
Expand All @@ -1394,7 +1390,7 @@ public List<PropagationPath> computeReflexion(Coordinate rcvCoord, Coordinate sr
// compute Y value (altitude) by interpolating the Y values of the two neighboring points
currentPoint.coordinate = new CoordinateXY(p1.x, (p1.x-p0.x)/(p2.x-p0.x)*(p2.y-p0.y)+p0.y);
//check if new reflection point altitude is higher than the wall
if (currentPoint.coordinate.y > currentPoint.altitude + currentPoint.buildingHeight) {
if (currentPoint.coordinate.y > currentPoint.obstacleAltitude - epsilon) {
// can't reflect higher than the wall
points.clear();
segments.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ public MirrorReceiverResultIndex(List<ProfileBuilder.Wall> buildWalls, Coordinat
// wall is too far from the receiver image, there is no receiver image
continue;
}
// Walls that belong to a building (polygon) does not create image receiver
// from the two sides of the wall
// Exterior polygons are CW we can check if the receiver is on the reflective side of the wall
// (on the exterior side of the wall)
if(wall.getType() == ProfileBuilder.IntersectionType.BUILDING &&
!wallPointTest(wall.getLineSegment(), receiverImage)) {
continue;
}
// create the visibility cone of this receiver image
Polygon imageReceiverVisibilityCone = createWallReflectionVisibilityCone(rcvMirror,
wall.getLineSegment(), maximumPropagationDistance, maximumDistanceFromWall);
Expand All @@ -176,6 +184,18 @@ public MirrorReceiverResultIndex(List<ProfileBuilder.Wall> buildWalls, Coordinat
}
mirrorReceiverTree.build();
}
/**
* Occlusion test between one wall and a viewer.
* Simple Feature Access (ISO 19125-1) say that:
* On polygon exterior ring are CCW, and interior rings are CW.
* @param wall1 Wall segment
* @param pt Observer
* @return True if the wall is oriented to the point, false if the wall Occlusion Culling (transparent)
*/
public static boolean wallPointTest(LineSegment wall1, Coordinate pt) {
return org.locationtech.jts.algorithm.Orientation.isCCW(new Coordinate[]{wall1.getCoordinate(0),
wall1.getCoordinate(1), pt, wall1.getCoordinate(0)});
}

public int getMirrorReceiverCapacity() {
return mirrorReceiverCapacity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public class PointPath {
public double e=0;
public Orientation orientation;

public void setBuildingHeight(double buildingHeight) {
this.buildingHeight = buildingHeight;
public void setObstacleAltitude(double obstacleAltitude) {
this.obstacleAltitude = obstacleAltitude;
}

public double buildingHeight; // only if POINT_TYPE = REFL
public double obstacleAltitude; // only if POINT_TYPE = REFL
public POINT_TYPE type; // type of point
public enum POINT_TYPE {
SRCE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,13 @@ public ProfileBuilder addBuilding(Coordinate[] coords, List<Double> alphas, int
* @param id Database primary key.
*/
public ProfileBuilder addBuilding(Geometry geom, double height, List<Double> alphas, int id) {
if(geom == null && ! (geom instanceof Polygon)) {
if(!(geom instanceof Polygon)) {
LOGGER.error("Building geometry should be Polygon");
return null;
}
Polygon poly = (Polygon)geom;
// Fix clock wise orientation of the polygon and inner holes
poly.normalize();
if(!isFeedingFinished) {
if(envelope == null) {
envelope = geom.getEnvelopeInternal();
Expand Down Expand Up @@ -2349,8 +2351,15 @@ public double updateZTopo(ProfileBuilder profileBuilder) {
return zTopo;
}

/**
* @return Obstacle altitude
*/
public double getZ() {
return zTopo + height;
if(Double.isNaN(zTopo) | Double.isNaN(height)) {
return poly.getCoordinate().z;
} else {
return zTopo + height;
}
}

public void setWalls(List<Wall> walls) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ public void testNReflexion() throws ParseException, IOException, SQLException {
// Keep only mirror receivers potentially visible from the source(and its parents)
List<MirrorReceiverResult> mirrorResults = receiverMirrorIndex.findCloseMirrorReceivers(inputData.
sourceGeometries.get(0).getCoordinate());
assertEquals(18, mirrorResults.size());

try {
try (FileWriter fileWriter = new FileWriter("target/testNReflexion_testVisibilityCone.csv")) {
Expand All @@ -139,6 +138,8 @@ public void testNReflexion() throws ParseException, IOException, SQLException {
//ignore
}

assertEquals(4, mirrorResults.size());

List<PropagationPath> propagationPaths = computeRays.computeReflexion(receiver,
inputData.sourceGeometries.get(0).getCoordinate(), false,
new Orientation(), receiverMirrorIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ public static double[] deltaRetrodif(PropagationPath reflect, PropagationProcess
//Get the reflexion point
PointPath pp = reflect.getPointList().get(idx);
//Get the point on the top of the obstacle
Coordinate o = new Coordinate(pp.coordinate.x, pp.buildingHeight);
Coordinate o = new Coordinate(pp.coordinate.x, pp.obstacleAltitude);
//Compute de distance delta (2.5.36)
double deltaPrime = -(s.distance(o) + o.distance(r) - reflect.getSRSegment().d);
double ch = 1.;
Expand Down

0 comments on commit d0cc5d8

Please sign in to comment.