-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTerrain.java
133 lines (114 loc) · 3.54 KB
/
Terrain.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import java.io.File;
import java.awt.image.*;
import java.awt.Color;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
/** Creates a terrain object which loads in the textfile contents into a single dimensional array, creates a greyscale bufferedimage object. */
public class Terrain {
float [][] height; // regular grid of height values
int dimx, dimy; // data dimensions
BufferedImage img; // greyscale image for displaying the terrain top-down
ArrayList<Integer> permute; // permuted list of integers in range [0, dimx*dimy)
// overall number of elements in the height grid
int dim(){
return dimx*dimy;
}
// get x-dimensions (number of columns)
int getDimX(){
return dimx;
}
// get y-dimensions (number of rows)
int getDimY(){
return dimy;
}
// get greyscale image
public BufferedImage getImage() {
return img;
}
// convert linear position into 2D location in grid
synchronized void locate(int pos, int [] ind)
{
ind[0] = (int) pos / dimy; // x
ind[1] = pos % dimy; // y
}
// to paint on mouseclick or any other event.
void changeImage(int x, int y){
Color blue = Color.BLUE;
img.setRGB(x,y, blue.getRGB());
}
// convert height values to greyscale colour and populate an image
void deriveImage()
{
img = new BufferedImage(dimy, dimx, BufferedImage.TYPE_INT_ARGB);
float maxh = -10000.0f, minh = 10000.0f;
// determine range of heights
for(int x=0; x < dimx; x++)
for(int y=0; y < dimy; y++) {
float h = height[x][y];
if(h > maxh)
maxh = h;
if(h < minh)
minh = h;
}
for(int x=0; x < dimx; x++)
for(int y=0; y < dimy; y++) {
// find normalized height value in range
float val = (height[x][y] - minh) / (maxh - minh);
//System.out.println("val = " + val);
Color col = new Color(val, val, val, 1.0f);
img.setRGB(x, y, col.getRGB());
}
}
// generate a permuted list of linear index positions to allow a random
// traversal over the terrain
void genPermute() {
permute = new ArrayList<Integer>();
for(int idx = 0; idx < dim(); idx++)
permute.add(idx);
java.util.Collections.shuffle(permute);
}
// find permuted 2D location from a linear index in the
// range [0, dimx*dimy)
synchronized void getPermute(int i, int [] loc) {
locate(permute.get(i), loc);
}
// read in terrain from file
void readData(String fileName){
try{
Scanner sc = new Scanner(new File(fileName));
// read grid dimensions
// x and y correpond to columns and rows, respectively.
// Using image coordinate system where top left is (0, 0).
dimy = sc.nextInt();
dimx = sc.nextInt();
// populate height grid
height = new float[dimx][dimy];
for(int y = 0; y < dimy; y++){
for(int x = 0; x < dimx; x++)
height[x][y] = sc.nextFloat();
}
sc.close();
// create randomly permuted list of indices for traversal
genPermute();
// generate greyscale heightfield image
deriveImage();
}
catch (IOException e){
System.out.println("Unable to open input file "+fileName);
e.printStackTrace();
}
catch (java.util.InputMismatchException e){
System.out.println("Malformed input file "+fileName);
e.printStackTrace();
}
}
/** return the height of the terrain in a given x and y position, when looping through the heights to determine water surface at each point.
* @param x is the x position in question.
* @param y is the y position of the grid in question.
* @return height at the inputted position.
*/
public float getHeight(int x, int y){
return height[x][y];
}
}