I plan to recreate the Earth through the ages using Flash.
I know how to use actionscript to draw lines and polygons procedurally, but I'm not sure how to calculate the X-Y position a point at a given longitude and latitude on the surface.
To compound things, I then wish to allow the user to rotate the globe on two axis, but I'll start with the first question.
I can create the oceans seas by using a psuedo light-sourced "sphere" (a circle with a highlight imported from Fireworks). The rest of the detail will be drawn on top.
That screams to use an engine like papervision.
Check out this example e.g.:
http://blog.728media.com/2008/11/04/papervision-and-geocoding/ (http://blog.728media.com/2008/11/04/papervision-and-geocoding/)
Or directly run it:
http://www.adobe.com/newsletters/edge/june2008/articles/article2/download/GeoGlobe.html (http://www.adobe.com/newsletters/edge/june2008/articles/article2/download/GeoGlobe.html)
Type in a city, like "Hamburg", "London" or whatever.
Just google around for papervision, flash, geo coding, gis and keywords like
this.
Good luck!
Just found another one with country highlighting:
http://www.shinobishoecorp.com/b/assets/globe/
Impressive, but these are completed projects with no tutorials.
I'm trying to build my own system, into which a time set millions of years ago can be input, and the effects of tectonic plate movement observed.
I have access to some data which will give me the longitude/latitude coordinates, but I'm trying to learn how to calculate the X/Y positions on the stage.
To begin, I have a circle with a diameter of 200 pixels.
On further thought, my knowledge of trigonometry should come in handy, and will give me some X/Y/Z coordinates.
So all I need to know is how to translate the X/Y/Z coordinates into X/Y coordinates.
As I said - there are numerous topics in the internet. For example
the one link of my first post links to the following site:
Learn how to geocode with Papervision3D and Adobe Flex (http://www.adobe.com/newsletters/edge/june2008/articles/article2/index.html?trackingid=DEKYF.)
Ok this is Papervision3D. Also PV3D but with a nice tutorial and also
some words about putting a marker in 2D (which might be interesting
for your first steps - can be found here:
http://blog.zupko.info/?p=221 (http://blog.zupko.info/?p=221)
A running version can be found here:
http://lab.zupko.info/geolocate/ (http://lab.zupko.info/geolocate/)
In the end - the good old wikipedia delivers some general information
as usual:
http://en.wikipedia.org/wiki/Geographic_coordinate_system (http://en.wikipedia.org/wiki/Geographic_coordinate_system)
Good luck - and keep us informed with your progress!
I like this a lot - and would love to see your applilcation.
Excellent - that's almost all the maths I need.
The last piece of the puzzle is translating the resulting X-Y-Z coordinates into X-Y coordinates for the screen.
This excerpt from Clanky's Yabasic cube should provide the principles I need to get this off the ground. All I have to do is translate it into ActionScript. Just give me a few hours.
for a = 1 to points
x1 = x(a)
y1 = y(a)
z1 = z(a)
rem Rotation and Movement
xx = x1
yy = y1 * cs(xr) + z1 * sn(xr) + wip
zz = z1 * cs(xr) - y1 * sn(xr) + wip
y1 = yy
x1 = xx * cs(yr) - zz * sn(yr) + wip
z1 = xx * sn(yr) + zz * cs(yr) + wip
zz = z1
xx = x1 * cs(zr) - y1 * sn(zr) + wip
yy = x1 * sn(zr) + y1 * cs(zr) + wip
rem Perspective
dv = (zz / 40) + 1
xx = size * (xx / dv) + 320
yy = size * (yy / dv) + 256
tx(a) = xx
ty(a) = yy
tz(a) = zz
next a
xr = xr + 3
yr = yr + 2
zr = zr + 5
if xr > 720 xr = xr - 720
if yr > 720 yr = yr - 720
if zr > 720 zr = zr - 720
I'm stuck again :(
The following zip file contains the .fla and a .swf. It is trying to create 6 triangles each 60 degrees apart along the equator.
Only 2 of the triangles are being shown at the front of the globe, and the rest are being squashed in behind it.
Can you spot any obvious mistakes in the following code?
Frame 1
_global.p180=Math.PI/180;
_global.masses=6;
_global.landmasses=new Array(_global.masses);
_global.landmasses[0]=3;
_global.landmasses[1]=3;
_global.landmasses[2]=3;
_global.landmasses[3]=3;
_global.landmasses[4]=3;
_global.landmasses[5]=3;
_global.longs=new Array(_global.masses);
_global.lats=new Array(_global.masses);
_global.longs[0]=new Array(0,5,-5);
_global.longs[1]=new Array(0,5,-5);
_global.longs[2]=new Array(0,5,-5);
_global.longs[3]=new Array(0,5,-5);
_global.longs[4]=new Array(0,5,-5);
_global.longs[5]=new Array(0,5,-5);
_global.lats[0]=new Array(0,5,5);
_global.lats[1]=new Array(60,65,65);
_global.lats[2]=new Array(120,125,125);
_global.lats[3]=new Array(180,185,185);
_global.lats[4]=new Array(240,245,245);
_global.lats[5]=new Array(300,305,305);
_global.radius=100;
_global.poleRot=0;
_global.ewRot=0;
_global.pointX=new Array();
_global.pointY=new Array();
_global.pointZ=new Array();
_global.xOff=100;
_global.yOff=100;
_global.zOff=0;
_global.zMult=0.5;
_global.Size=0.8;
function dotty(){
for(i=0;i<_global.landmasses[_global.landmass];i++){
ph=(90-_global.lats[_global.landmass][i])*_global.p180;
th=(_global.longs[_global.landmass][i]+180)*_global.p180;
x1=_global.radius*Math.sin(ph)*Math.cos(th);
y1=_global.radius*Math.sin(ph)*Math.sin(th);
z1=_global.radius*Math.cos(ph);
xx=x1;
yy=y1*Math.cos(_global.ewRot)+z1*Math.sin(_global.ewRot);
zz=z1*Math.cos(_global.ewRot)-y1*Math.sin(_global.ewRot);
y1=yy;
x1=xx*Math.cos(_global.poleRot)-zz*Math.sin(_global.poleRot);
z1=xx*Math.sin(_global.poleRot)+zz*Math.cos(_global.poleRot);
zz=z1*_global.zMult+_global.zOff;
xx=x1;
yy=y1;
dv=(zz/80)+1;
xx=_global.Size*(xx/dv)+_global.xOff;
yy=_global.Size*(yy/dv)+_global.yOff;
_global.pointX[i]=xx;
_global.pointY[i]=yy;
_global.pointZ[i]=zz;
}
}
function drawPoints(){
test.width=200;
test.height=200;
test._x=25;
test._y=25;
test.lineStyle(1,0x00ff00,100);
test.beginFill(0x00ff00,100);
test.moveTo(_global.pointX[0],_global.pointY[0]);
test.lineTo(_global.pointX[1],_global.pointY[1]);
test.lineTo(_global.pointX[2],_global.pointY[2]);
test.endFill();
}
Frame 2
_global.poleRot+=0.01;
if(_global.poleRot>Math.PI){
_global.poleRot-=Math.PI*2;
}
_root.createEmptyMovieClip("test",0);
for(_global.landmass=0;_global.landmass<_global.masses;_global.landmass++){
dotty();
fnd=false;
for(jj=0;jj<_global.landmasses[_global.landmass];jj++){
if(_global.pointZ[jj]<=-30){
fnd=true;
}
}
fnd=true;
if(fnd){
drawPoints();
}
}
Debug.text=_global.pointZ[0]+"\n"+_global.pointZ[1]+"\n"+_global.pointZ[2];
Frame 3
gotoAndPlay(2);
Just was able to watch the SWF file - it looks great.
Congrats. Everything looks realistically and fine.
If two points(triangles) are close next to each other
you might think about adding a depth parameter to
them as well.
Great ... what do you plan to do with your project ?
Depth as in mountins?
It's a possibility, but first I'd like to iron out the problem which is causing only 120 degrees to be displayed in front of the equator and 240 degrees behind it. It should be 180 degrees on both sides, but I don't know what is causing the distortion.
It turns out that the distortion was caused by low Z-values. I have increased the Z offset, which made it smaller. Then by applying multipliers to the X and Y values, I have re-enlarged it, ironing out the fish-eye perspective.
See the wireframe example in the zip file below.
@ck0:
That's awesome. Very cool progress you made. Congratz.
With depths value I meant the depth attribute on movie
clips.
Keep the updates coming ;-)
Thanks Benny.
I hope to have an update this afternoon with some of the Eurasian plate on it. Expect India, Arabia and Africa to follow shortly.
I see what you mean about the depth attribute, but I'm drawing all the features into a single movie clip. This could change as the program evolves though.
Here it is again with the Eurasian plate features. Some of the test triangles are still there too.
I have spotted a slight problem with the way it is drawn if some corners are behind the world - I'll work on this. There's also a rotation problem, which I also plan to figure out.
I have changed it so it reads the coordinates from a text file.
This will make it easier to add data and split the large land-masses into less buggy small polygons.
The polar rotation is now fixed.
That's pretty neat. Seperating the geo-data from
the code is a good idea IMHO. Very well done!
Here is the latest text file. It contains most of Western Europe, and already it is much bigger than before.
The appearance has improved greatly though.
This latest version features an almost complete Europe and a speed control slider.
The first 2 debug values relate to the rotation and attitude of the globe, and the third value is the number of polygons on the whole model.
It's cool to see that a thread evolves so good. Latest version
looks very solid already. I like it a lot and have some K++ for
doing it totally on your own without using libraries like PV3D !
Very impressive CK! It's suffering from a distinct lack of Australia though :P
Jim
Don't worry - Australia will be an equitorial country in about 50,000,000 AD or so.
I've got to complete the present day first though.