Skip to content

Instantly share code, notes, and snippets.

@zyuiop
Created August 23, 2017 23:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zyuiop/248304e6dcd1af7b695116b5b9afb8aa to your computer and use it in GitHub Desktop.
Save zyuiop/248304e6dcd1af7b695116b5b9afb8aa to your computer and use it in GitHub Desktop.
package ch.epfl.alpano.gui;
import ch.epfl.alpano.Math2;
import ch.epfl.alpano.PanoramaComputer;
import ch.epfl.alpano.PanoramaParameters;
import ch.epfl.alpano.dem.ContinuousElevationModel;
import ch.epfl.alpano.dem.ElevationProfile;
import ch.epfl.alpano.summit.Summit;
import javafx.scene.Node;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import javafx.scene.transform.Rotate;
import java.util.*;
import java.util.function.DoubleUnaryOperator;
import java.util.stream.Collectors;
/**
* A labelizer, responsible of placing labels on the summits.
*/
final class Labelizer {
private final ContinuousElevationModel cem;
private final List<Summit> summits;
Labelizer(ContinuousElevationModel cem, List<Summit> summits) {
this.cem = Objects.requireNonNull(cem);
this.summits = Collections.unmodifiableList(summits);
}
/*
* ...
*/
private List<SummitWrapper> getVisibleSummits(PanoramaParameters parameters) {
return this.summits.stream()
.map(s -> new Object() {
// Small tip to keep some variables across loops
private final Summit summit = s;
private final double azimuth = parameters.observerPosition().azimuthTo(summit.position());
private final double distance = parameters.observerPosition().distanceTo(summit.position());
})
.filter(summit -> {
// First check
return summit.azimuth >= (parameters.centerAzimuth() - parameters.horizontalFieldOfView() / 2D) &&
summit.azimuth <= (parameters.centerAzimuth() + parameters.horizontalFieldOfView() / 2D) &&
summit.distance <= parameters.maxDistance();
})
.map(summit -> {
ElevationProfile profile = new ElevationProfile(cem, parameters.observerPosition(), summit.azimuth, summit.distance);
DoubleUnaryOperator f = PanoramaComputer.rayToGroundDistance(profile, parameters.observerElevation(), 0);
double rayToGround = -f.applyAsDouble(summit.distance);
double angle = Math.atan2(rayToGround, summit.distance);
return new SummitWrapper(summit.summit, summit.distance, rayToGround, angle, summit.azimuth) {
ElevationProfile profile() {
return profile;
}
};
})
.filter(summit -> {
if (Math.abs(summit.verticalAngle()) > parameters.verticalFieldOfView() / 2D)
return false;
DoubleUnaryOperator f = PanoramaComputer.rayToGroundDistance(summit.profile(), parameters.observerElevation(), summit.rayToGround() / summit.distance()); // (dY / distance)
double first = Math2.firstIntervalContainingRoot(f, 0, summit.distance(), 64);
return first >= summit.distance() - 200;
})
.sorted((s1, s2) -> {
int comp = Double.compare(parameters.yForAltitude(s1.verticalAngle()), parameters.yForAltitude(s2.verticalAngle()));
return comp == 0 ? Integer.compare(s2.summit().elevation(), s1.summit().elevation()) : comp;
})
.collect(Collectors.toList());
}
private static class SummitWrapper {
private final Summit summit;
private final double distance;
private final double rayToGround;
private final double verticalAngle;
private final double azimuth;
private SummitWrapper(Summit summit, double distance, double rayToGround, double verticalAngle, double azimuth) {
this.summit = summit;
this.distance = distance;
this.rayToGround = rayToGround;
this.verticalAngle = verticalAngle;
this.azimuth = azimuth;
}
public Summit summit() {
return summit;
}
public double distance() {
return distance;
}
public double rayToGround() {
return rayToGround;
}
public double verticalAngle() {
return verticalAngle;
}
public double azimuth() {
return azimuth;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment