О немО себе[code]/maps/Мои СоседиМой ЗимаШопМоя СтройкаЗверь Дверь

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  =4000;
    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)));
    }/* */
    
            var lines = [];
        var limSin = 100, fSin = 0.1 / limSin;
        var limRad = 100, fRad = Math.PI / limRad;
        for (var i = 0; i < limSin; i++) {
            polydata.push(new GLatLng(37.4419+i * fSin,-122.1419 + 0.1*Math.sin(i / 50)));
        }
        for (var i = 0; i < limRad; i++) {
            var R = (130 + ((i > limRad / 2) ? (Math.sin(i / 4)) : 0) * 5)/1000;
            polydata.push(new GLatLng(37.4419 + Math.cos(fRad * i) * R,-122.1419 + Math.sin(fRad * i) * R));
        }
    
    
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);
            len*=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 online
Just 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

How to reduce polygon complexy and be happy

Кащей не в шутку захворал,
Пять дней уж с сундука не сходит...