Mission: create polygon of 1000 verticles and display it w\o lags
Goal: control LOD in real time
Step1. Create Polygon
lets create circle
//lests create circle
var polydata=[];
var Nverts =1000;
var step =Math.PI*2/Nverts;
var radius =0.03;
var i;
for(i=0;i<Nverts;i++){
polydata.push(new GLatLng(37.4419 +radius*Math.cos(i*step),
-122.1419+radius*Math.sin(i*step)));
}
next add it to map
return new smartPolygon(createCircle(),map,new CoordinatesMapper(map));
setup redraw on zoom change
GEvent.addListener(map, "zoomend", function(){
_this.render();
});
and change complexity on zoom change
//convert data to screen space
var set=this.mapper.toScreenSpace(this.data);
var inL=set.length;
//reduce
set=this.performReduce(set);
var outL=set.length;
/** log **/
document.getElementById("message").innerHTML='polygon reduced from '+inL+' to '+outL;
//convert back to map space and return
return this.mapper.toMapSpace(set);
But how to change it?
having points 1,2,3 and 4 we need to remove point 2 but keep point 3.
Lets create vector from 1 to 3, and from 1 to 4. We need to caclucate perpendicular P from 3 to L
If it is greater that some delta - so we have visible shift. And we store point 1 and 3 in result set.
var resultset=[];
var L=dataset.length;
resultset.push(dataset[0]);
dataset.push(dataset[L-1]);
var cur=0;
var j=0;
for(j=1;j<L;j++)
{
var x1=dataset[cur].x;
var y1=dataset[cur].y;
var x2=dataset[j ].x;
var y2=dataset[j ].y;
var x3=dataset[j+1].x;
var y3=dataset[j+1].y;
//first points must be different in screen space
if(!(((Math.round(x1)==Math.round(x2)) && (Math.round(y1)==Math.round(y2))) ||
((Math.round(x2)==Math.round(x3)) && (Math.round(y2)==Math.round(y3)))))
{
/*
goal - create two vectors -
from current to test point
and from current to next point
we need to drop a perpendicular from test point to cur-last vector
just simple mathematics
*/
var vx1=x2-x1;
var vy1=y2-y1;
var len=Math.sqrt(vy1*vy1+vx1*vx1);
var v1=this._norm(vx1,vy1,len);
var vx2=x3-x1;
var vy2=y3-y1;
var v2=this._norm(vx2,vy2);
var dot=this._dot(v1,v2);
var sa=Math.sin(Math.acos(dot));
var perp=sa*len;
//so if perpendicular is bigger than delta, and length of vector is bigger than delta
//add point to result set
if(Math.abs(perp)>=delta && len>=delta)
{
cur=j;
resultset.push(dataset[j]);
}
}
}
Next iteration will begin from point 3. In any case - it works!
and, all of this you can see onlineJust zoomin and out, and set different deltas(end press enter) to see how it works!
Homework: inherit smartPolygon from GOverlay to produce more transparent solution
All of sections, i list here, is allready done by me. I need just to wrap code into article, and, yap, english article :)
If you want to know more - ask
If you want to know more - ask
No comments:
Post a Comment