## Friday, 13 January 2017

### Chapter 18 Exercise 37, Introduction to Java Programming, Tenth Edition Y. Daniel LiangY.

18.37 (Hilbert curve)
The Hilbert curve, first described by German mathematician David Hilbert in 1891,
is a space-filling curve that visits every point in a square grid with a
size of 22, 44, 88, 1616, or any other power of 2.
Write a program that displays a Hilbert curve for the specified order

import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Polyline;
import javafx.stage.Stage;

public class Exercise_37 extends Application {

@Override
public void start(Stage primaryStage) throws Exception {

HilbertCurvePane pane = new HilbertCurvePane();
primaryStage.setScene(new Scene(pane));
primaryStage.show();
}

class HilbertCurvePane extends BorderPane {

private final int UP = 0;
private final int RIGHT = 1;
private final int DOWN = 2;
private final int LEFT = 3;

Label lblOrder = new Label("Enter Order:");
TextField tfOrder = new TextField("0");
Polyline polyline = new Polyline();
Pane pane = new Pane(polyline);

private double x1;
private double y1;
double length = 10;

int order;

HilbertCurvePane() {
setMinSize(400, 400);

HBox hBox = new HBox(10, lblOrder, tfOrder);
hBox.setAlignment(Pos.BASELINE_CENTER);

tfOrder.setPrefColumnCount(4);
tfOrder.setAlignment(Pos.BASELINE_RIGHT);
tfOrder.setOnKeyPressed(e-> {

if (e.getCode() == KeyCode.ENTER) {
try {
order = Integer.parseInt(tfOrder.getText());
} catch (NumberFormatException ex) {
order = 0;
tfOrder.setText("0");
}
draw();
} else if (e.getCode() == KeyCode.UP) {
order = Integer.parseInt(tfOrder.getText()) + 1;
tfOrder.setText(order + "");
draw();
}else if (e.getCode() == KeyCode.DOWN) {
order = Math.max(Integer.parseInt(tfOrder.getText()) - 1, 0);
tfOrder.setText(order + "");
draw();
}
});
setBottom(hBox);

setCenter(pane);
}

private void draw() {
if (order == 0) return;

polyline.getPoints().clear();
length = 50 / order;
x1 = Math.min(getWidth(), getHeight()) - 50;
y1 = x1;
draw(order, DOWN);
}

private void draw(int order, int direction) {

if (order == 1) {
switch (direction) {
case UP:
move(DOWN);
move(RIGHT);
move(UP);
break;
case RIGHT:
move(LEFT);
move(UP);
move(RIGHT);
break;
case DOWN:
move(UP);
move(LEFT);
move(DOWN);
break;
case LEFT:
move(RIGHT);
move(DOWN);
move(LEFT);
break;
}

} else if (order > 1){
switch (direction) {
case UP:
draw(order - 1, LEFT);
move(DOWN);
draw(order - 1, UP);
move(RIGHT);
draw(order - 1, UP);
move(UP);
draw(order - 1, RIGHT);
break;
case RIGHT:
draw(order - 1, DOWN);
move(LEFT);
draw(order - 1, RIGHT);
move(UP);
draw(order - 1, RIGHT);
move(RIGHT);
draw(order - 1, UP);
break;
case DOWN:
draw(order - 1, RIGHT);
move(UP);
draw(order - 1, DOWN);
move(LEFT);
draw(order - 1, DOWN);
move(DOWN);
draw(order - 1, LEFT);
break;
case LEFT:
draw(order - 1, UP);
move(RIGHT);
draw(order - 1, LEFT);
move(DOWN);
draw(order - 1, LEFT);
move(LEFT);
draw(order - 1, DOWN);
break;
}
}
}

private void move(int direction) {
ObservableList<Double> list = polyline.getPoints();
switch (direction) {
case UP:
list.addAll(x1, y1 -= length);
break;
case RIGHT:
list.addAll(x1 += length, y1);
break;
case DOWN:
list.addAll(x1, y1 += length);
break;
case LEFT:
list.addAll(x1 -= length, y1);
break;
}

}
}

public static void main(String[] args) {
Application.launch(args);
}
}