mirror of
https://github.com/csharpee/Map-Projections.git
synced 2025-12-16 00:00:06 -05:00
Revert "Angles vs factors"
This reverts commit ed297dbd079f3cc1ce93cd3aeb2cd98a60be7351.
This commit is contained in:
parent
ed297dbd07
commit
00a3f2a25e
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 46 KiB |
@ -24,7 +24,8 @@
|
||||
package apps;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.DoubleFunction;
|
||||
import java.util.function.DoubleUnaryOperator;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import dialogs.ProgressBarDialog;
|
||||
@ -145,14 +146,14 @@ public class MapAnalyzer extends MapApplication {
|
||||
|
||||
|
||||
private Region buildTextDisplay() {
|
||||
this.avgSizeDistort = new Text(". . .");
|
||||
this.avgShapeDistort = new Text(". . .");
|
||||
this.avgSizeDistort = new Text("...");
|
||||
this.avgShapeDistort = new Text("...");
|
||||
final Text txt = new Text("Blue areas are dilated, red areas are compressed, and black areas are stretched.");
|
||||
txt.setWrappingWidth(GUI_WIDTH);
|
||||
|
||||
VBox box = new VBox(3,
|
||||
new HBox(new Label("Average area distortion: "), avgSizeDistort),
|
||||
new HBox(new Label("Average angle distortion: "), avgShapeDistort),
|
||||
new HBox(new Label("Average size distortion: "),avgSizeDistort),
|
||||
new HBox(new Label("Average shape distortion: "),avgShapeDistort),
|
||||
txt);
|
||||
box.setAlignment(Pos.CENTER_LEFT);
|
||||
return box;
|
||||
@ -172,7 +173,7 @@ public class MapAnalyzer extends MapApplication {
|
||||
this.shapeChart = new BarChart<String, Number>(new CategoryAxis(), new NumberAxis());
|
||||
this.shapeChart.setPrefWidth(CHART_WIDTH);
|
||||
this.shapeChart.setPrefHeight(IMG_WIDTH/2);
|
||||
this.shapeChart.getXAxis().setLabel("Angle displacement");
|
||||
this.shapeChart.getXAxis().setLabel("Stretch factor");
|
||||
this.shapeChart.setBarGap(0);
|
||||
this.shapeChart.setCategoryGap(0);
|
||||
this.shapeChart.setAnimated(false);
|
||||
@ -189,8 +190,8 @@ public class MapAnalyzer extends MapApplication {
|
||||
sizeChart.getData().clear();
|
||||
shapeChart.getData().clear();
|
||||
|
||||
avgSizeDistort.setText("\u2026");
|
||||
avgShapeDistort.setText("\u2026");
|
||||
avgSizeDistort.setText("...");
|
||||
avgShapeDistort.setText("...");
|
||||
});
|
||||
|
||||
loadParameters();
|
||||
@ -204,13 +205,13 @@ public class MapAnalyzer extends MapApplication {
|
||||
final double[][][] distortionG = proj.calculateDistortion(Projection.globe(GLOBE_RES));
|
||||
|
||||
Platform.runLater(() -> {
|
||||
sizeChart.getData().add(histogram(distortionG[0], -LN_10, LN_10, 20,
|
||||
(x) -> Double.toString(Math.round(100*Math.exp(x))/100.)));
|
||||
shapeChart.getData().add(histogram(distortionG[1], 0.0, Math.PI/2, 18,
|
||||
(x) -> Integer.toString((int) Math.toDegrees(x))+"\u00B0"));
|
||||
sizeChart.getData().add(histogram(distortionG[0],
|
||||
-LN_10, LN_10, 20, Math::exp));
|
||||
shapeChart.getData().add(histogram(distortionG[1],
|
||||
0.0, LN_10, 20, Math::exp));
|
||||
|
||||
avgSizeDistort.setText(format(Math2.toDecibels(Math2.stdDev(distortionG[0])))+"dB");
|
||||
avgShapeDistort.setText(format(Math.toDegrees(Math2.mean(distortionG[1])))+"\u00B0");
|
||||
avgSizeDistort.setText(format(Math2.stdDev(distortionG[0])/LN_10*10));
|
||||
avgShapeDistort.setText(format(Math2.mean(distortionG[1])/LN_10*10));
|
||||
|
||||
enable(ButtonType.UPDATE_MAP, ButtonType.SAVE_GRAPH);
|
||||
});
|
||||
@ -270,7 +271,7 @@ public class MapAnalyzer extends MapApplication {
|
||||
for (int x = 0; x < distortion[0][y].length; x ++) {
|
||||
final double sizeDistort = distortion[0][y][x], shapeDistort = distortion[1][y][x];
|
||||
final double sizeContour = Math.round(sizeDistort/(LN_10/10))*LN_10/10; //contour the size by decibels
|
||||
final double shapeContour = Math.round(shapeDistort/(Math.PI/36))*Math.PI/36; //contour the size by semidecibels
|
||||
final double shapeContour = Math.round(shapeDistort/(LN_10/20))*LN_10/20; //contour the size by semidecibels
|
||||
if (Double.isNaN(sizeDistort) || Double.isNaN(shapeDistort)) {
|
||||
writer.setArgb(x, y, 0);
|
||||
continue;
|
||||
@ -278,14 +279,14 @@ public class MapAnalyzer extends MapApplication {
|
||||
|
||||
final int r, g, b;
|
||||
if (sizeDistort < 0) { //if compressing
|
||||
r = (int)(255.9*(1-shapeContour/(Math.PI/2)));
|
||||
g = (int)(255.9*(1-shapeContour/(Math.PI/2))*Math.exp(sizeContour*.6));
|
||||
r = (int)(255.9*Math.exp(-shapeContour*.6));
|
||||
g = (int)(255.9*Math.exp(-shapeContour*.6)*Math.exp(sizeContour*.6));
|
||||
b = g;
|
||||
}
|
||||
else { //if dilating
|
||||
r = (int)(255.9*(1-shapeContour/(Math.PI/2))*Math.exp(-sizeContour*.6));
|
||||
r = (int)(255.9*Math.exp(-shapeContour*.6)*Math.exp(-sizeContour*.6));
|
||||
g = r; //I find .6 to be a rather visually pleasing sensitivity
|
||||
b = (int)(255.9*(1-shapeContour/(Math.PI/2)));
|
||||
b = (int)(255.9*Math.exp(-shapeContour*.6));
|
||||
}
|
||||
|
||||
final int argb = ((((((0xFF)<<8)+r)<<8)+g)<<8)+b;
|
||||
@ -297,7 +298,7 @@ public class MapAnalyzer extends MapApplication {
|
||||
|
||||
|
||||
private static final Series<String, Number> histogram(double[][] values,
|
||||
double min, double max, int num, DoubleFunction<String> converter) {
|
||||
double min, double max, int num, DoubleUnaryOperator converter) {
|
||||
int[] hist = new int[num+1]; //this array is the histogram values for min, min+dx, ..., max-dx, max
|
||||
int tot = 0;
|
||||
for (double[] row: values) {
|
||||
@ -312,8 +313,9 @@ public class MapAnalyzer extends MapApplication {
|
||||
}
|
||||
Series<String, Number> output = new Series<String, Number>();
|
||||
for (int i = 0; i <= num; i ++) {
|
||||
double x = converter.applyAsDouble(i*(max-min)/num+min);
|
||||
output.getData().add(new Data<String, Number>(
|
||||
converter.apply(i*(max-min)/num+min),
|
||||
Double.toString(Math.round(100*x)/100.),
|
||||
(double)hist[i]/tot*100));
|
||||
}
|
||||
return output;
|
||||
|
||||
@ -42,6 +42,7 @@ import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
@ -68,7 +69,6 @@ import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
@ -183,7 +183,7 @@ public abstract class MapApplication extends Application {
|
||||
public void start(Stage root) {
|
||||
this.root = root;
|
||||
this.root.setTitle(this.name);
|
||||
this.root.setScene(new Scene(new StackPane(makeWidgets()), Color.ANTIQUEWHITE)); //Why can't I set this color?
|
||||
this.root.setScene(new Scene(new StackPane(makeWidgets())));
|
||||
this.root.show();
|
||||
|
||||
this.suppressListeners.set();
|
||||
@ -192,7 +192,7 @@ public abstract class MapApplication extends Application {
|
||||
}
|
||||
|
||||
|
||||
protected abstract Region makeWidgets();
|
||||
protected abstract Node makeWidgets();
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -47,18 +47,19 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.Stage;
|
||||
import maps.Arbitrary;
|
||||
import maps.Azimuthal;
|
||||
import maps.CahillKeyes;
|
||||
import maps.Cylindrical;
|
||||
import maps.Lenticular;
|
||||
import maps.Misc;
|
||||
import maps.Polyhedral;
|
||||
import maps.MyProjections;
|
||||
import maps.Projection;
|
||||
import maps.Pseudocylindrical;
|
||||
import maps.Arbitrary;
|
||||
import maps.Polyhedral;
|
||||
import maps.Tobler;
|
||||
import maps.Waterman;
|
||||
import maps.WinkelTripel;
|
||||
import utils.Math2;
|
||||
|
||||
/**
|
||||
* A simple script that creates an annotated ScatterPlot of map projections
|
||||
@ -66,6 +67,8 @@ import utils.Math2;
|
||||
* @author jkunimune
|
||||
*/
|
||||
public class MapPlotter extends Application {
|
||||
|
||||
private static final double DECIBEL = Math.log(10)/10;
|
||||
|
||||
private static final double GLOBE_RES = .005;
|
||||
|
||||
@ -98,7 +101,7 @@ public class MapPlotter extends Application {
|
||||
final ScatterChart<Number, Number> plot =
|
||||
new ScatterChart<Number, Number>(
|
||||
new NumberAxis("Size distortion", 0, 4, .5),
|
||||
new NumberAxis("Shape distortion", 0, 20, 5));
|
||||
new NumberAxis("Shape distortion", 0, 3, .5));
|
||||
plot.setLegendSide(Side.RIGHT);
|
||||
final AnchorPane overlay = new AnchorPane();
|
||||
stack = new StackPane(plot, overlay);
|
||||
@ -149,7 +152,7 @@ public class MapPlotter extends Application {
|
||||
final double[] params = projection.getDefaultParameters();
|
||||
final double distortion[] = projection.avgDistortion(points, params);
|
||||
final Data<Number, Number> datum = new Data<Number, Number>(
|
||||
Math2.toDecibels(distortion[0]), Math.toDegrees(distortion[1]));
|
||||
distortion[0]/DECIBEL, distortion[1]/DECIBEL);
|
||||
series.getData().add(datum);
|
||||
final Label lbl = new Label(projection.getName());
|
||||
overlay.getChildren().add(lbl);
|
||||
|
||||
@ -90,7 +90,7 @@ public class Azimuthal {
|
||||
4, 4, 0b0111, Type.AZIMUTHAL, Property.GNOMONIC, 2) {
|
||||
|
||||
public double[] project(double lat, double lon) {
|
||||
if (lat < 0.01) lat = 0.01;
|
||||
if (lat < 0.2) lat = 0.2;
|
||||
final double r = Math.tan(Math.PI/2 - lat);
|
||||
return new double[] { r*Math.sin(lon), -r*Math.cos(lon)};
|
||||
}
|
||||
|
||||
@ -367,9 +367,8 @@ public abstract class Projection {
|
||||
|
||||
final double s1ps2 = Math.hypot((pE[0]-pC[0])+(pN[1]-pC[1]), (pE[1]-pC[1])-(pN[0]-pC[0]));
|
||||
final double s1ms2 = Math.hypot((pE[0]-pC[0])-(pN[1]-pC[1]), (pE[1]-pC[1])+(pN[0]-pC[0]));
|
||||
final double sig = Math.abs((s1ps2+s1ms2)/(s1ps2-s1ms2));
|
||||
output[1] = Math.atan((sig - 1)/Math.sqrt(sig)/2); //the first output is the shape (angle) distortion
|
||||
if (sig > 1e10)
|
||||
output[1] = Math.abs(Math.log(Math.abs((s1ps2-s1ms2)/(s1ps2+s1ms2)))); //the first output is the shape (angle) distortion
|
||||
if (Math.abs(output[1]) > 25)
|
||||
output[1] = Double.NaN; //discard outliers
|
||||
|
||||
return output;
|
||||
|
||||
@ -171,11 +171,6 @@ public class Math2 {
|
||||
}
|
||||
|
||||
|
||||
public static double toDecibels(double ratio) {
|
||||
return ratio/Math.log(10)*10;
|
||||
}
|
||||
|
||||
|
||||
public static double sind(double angdeg) {
|
||||
return Math.sin(Math.toRadians(angdeg));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user