galaxies (pt. 2)
Based on some code I found via google (http://www.codemoon.com/galaxy/random.html), I coded a simple applet to generate some spiral galaxies. All went well until I decided to start adapting it to the situation it's needed for in my project -- ie, I need the stars to be spread a lot farther apart than in the example code, and I need the ability to zoom in and out on the galaxy. I therefore wrote a function (called translatePoint) to compute what I thought would be the point I wanted to draw on the screen, based on whatever zoom has been selected.
Here is the code below, I was hoping to get some help on what the appropriate way would be to translate these coordinates:
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.*;
publicclass GalaxyTestextends Appletimplements ActionListener{
publicvoid init(){
setLayout(null);
add(generate =new Button("Generate Galaxy"));
generate.setBounds(420, 30, 100, 20);
generate.addActionListener(this);
add(numStarsField =new TextField("20000"));
numStarsField.setBounds(420, 90, 100, 20);
add(numArmsField =new TextField("5"));
numArmsField.setBounds(420, 150, 100, 20);
add(angularSpreadDivisorField =new TextField("100"));
angularSpreadDivisorField.setBounds(420, 210, 100, 20);
add(radiusField =new TextField("6000"));
radiusField.setBounds(420, 270, 100, 20);
add(zoomField =new TextField("29"));
zoomField.setBounds(420, 330, 100, 20);
generateGalaxy(20000, 5, 100, 6000, 29);
}
publicvoid paint(Graphics g){
g.setColor(Color.black);
g.drawString("Number of Stars", 420, 80);
g.drawString("Number of Arms", 420, 140);
g.drawString("Angular Spread Divisor", 420, 200);
g.drawString("Radius", 420, 260);
g.drawString("Zoom", 420, 320);
//g.translate(200, 225);
g.setColor(Color.black);
g.fillRect(0, 0, 400, 400);
g.setColor(Color.white);
Point loc;
for(int i = 0; i < list.size(); i++){
loc = translatePoint(read(i), center, 400, zoom);
//loc = new Point(read(i).x/zoom, read(i).y/zoom);
centerCircle(g, loc, 30/zoom);
}
}
void generateGalaxy(int numStars,int numArms,int angularSpreadDivisor,int radius,int zoom){
this.numStars = numStars;
this.numArms = numArms;
this.angularSpreadDivisor = angularSpreadDivisor;
this.angularSpread = angularSpreadDivisor/(numArms);
this.radius = radius;
this.zoom = zoom;
armAngle = (360 / numArms)%360;
list =new java.util.Vector();
for(int i = 0; i < numStars; i++){
list.add(makeLocation(i));
}
}
Point read(int i){
return (Point)list.get(i);
}
publicstatic Point translatePoint(Point object, Point center,int size,int zoom){
if(object ==null || center ==null)returnnull;
int dx = center.x / zoom - (int)(0.5 * size);
int dy = center.y / zoom - (int)(0.5 * size);
int x = object.x / zoom - dx;
int y = object.y / zoom - dy;
return(new Point(x, y));
}
publicstatic Point makeLocation(int count){
while(true){
//float r = hatRandom(radius);
//float r = randomFloat(radius);
float r = lineRandom(radius);
//float percentageRadius = r / radius;
//float modifiedSpread = 1-(percentageRadius * angularSpread);
//float q = (float)(hatRandom(angularSpread) * ((random.nextInt(2) == 0) ? 1.0 : -1.0));
//float q = (float)(randomFloat(angularSpread) * ((random.nextInt(2) == 0) ? 1.0 : -1.0));
float q = (float)(lineRandom(angularSpread) * ((random.nextInt(2) == 0) ? 1.0 : -1.0));
//float q = (float)(lineRandom(modifiedSpread) * ((random.nextInt(2) == 0) ? 1.0 : -1.0));
float k = 1.0F;
float a = (random.nextInt() % numArms) * armAngle;
int x = (int)(r * Math.cos(degToRad * (a + r + q)));
int y = (int)(r * Math.sin(degToRad * (a + r + q)));
Point loc =new Point(x, y);
Point wloc;
boolean invalid =false;
int distance;
/*
for(int i = 0; i < count; i++) {
wloc = read(i).loc;
distance = calcDistance(loc, wloc);
if(distance < Galaxy.minDist || distance > Galaxy.maxDist) {
invalid = true;
break;
}
}
*/
if(!invalid)return loc;
}
}
void centerCircle(Graphics g, Point loc,int diameter){
g.fillOval(loc.x - diameter/2, loc.y - diameter/2, diameter, diameter);
}
staticfloat randomFloat(float max){
return max * random.nextFloat();
}
staticfloat hatRandom(float range){
float p = area * random.nextFloat();
return (float)Math.atan(p/4) * range/6.0F;
}
staticfloat lineRandom(float range){
float area = range*range/2;
float p = area * random.nextFloat();
return range-(float)Math.sqrt(range*range - 2*p);
}
publicvoid actionPerformed(ActionEvent actionevent){
if(actionevent.getSource() == generate){
generateGalaxy(Integer.parseInt(numStarsField.getText()), Integer.parseInt(numArmsField.getText()), Integer.parseInt(angularSpreadDivisorField.getText()), Integer.parseInt(radiusField.getText()), Integer.parseInt(zoomField.getText()));
repaint();
}
}
Button generate;
TextField numArmsField;
TextField numStarsField;
TextField angularSpreadDivisorField;
TextField radiusField;
TextField armAngleField;
TextField zoomField;
staticfloat area = (float)(4.0 * Math.atan(6.0));
static Random random =new Random();
java.util.List list =new java.util.Vector();
staticfloat pi = 3.1415927F;
staticfloat degToRad = pi / 180.0F;
staticint radius;
staticint numArms;
staticint armAngle;
staticint angularSpreadDivisor;
staticfloat angularSpread;
staticint numStars;
staticint zoom;
staticint calcDistance(Point from, Point to){
int dx = from.x - to.x;
int dy = from.y - to.y;
//if(dx < 0) dx = - dx;
//if(dy < 0) dy = - dy;
return (int)(Math.sqrt((dx * dx) + (dy * dy)));
}
staticfinal Point center =new Point(200, 200);
}

