View unanswered posts | View active topics It is currently Thu Mar 28, 2024 4:34 pm



Reply to topic  [ 1 post ] 
spring chart fix 
Author Message
New pChart user
New pChart user

Joined: Fri Apr 20, 2012 6:33 am
Posts: 1
Post spring chart fix
I'm looking at the spring chart code because I'm trying to model a graph containing a few hundred nodes. In this process, I've noticed that 2 nodes kept sticking to the left edge.

I've found out this is because these nodes were positioned on exactly the same location. On each iteration, the distance calculated would be 0, resulting in a high force, but the angle calculated would be 0. Since the code adds 180 to this number (to reverse the direction), this results in the two nodes moving to the left at quite a high speed (since the force is high). Problem is, that they arrive on exactly the same spot, repeating the process every iteration, and tearing appart the graph.

The fix for this is quite easy:

In the function doPass(), in the Repulstion vector calculation block, after the distance calculation, we can do a check if the calculated distance is 0, when this is the case, instead of calculating the angle, just do $Angle = rand(0,360). This will make sure that the two nodes can arrive in different locations. After some iterations, the positions will be corrected.

Code:
...
            /* Repulsion vectors */
            foreach($this->Data as $Key2 => $Settings2) {
                if ( $Key != $Key2 ) {
                    $X2 = $this->Data[$Key2]["X"];
                    $Y2 = $this->Data[$Key2]["Y"];
                    $FreeZone = $this->Data[$Key2]["FreeZone"];

                    $Distance = $this->getDistance($X1,$Y1,$X2,$Y2);

                    /* Nodes too close, repulsion occurs */
                    if ( $Distance < $FreeZone ) {
                        $Force = log(pow(2,$FreeZone-$Distance));

                        if ($Distance == 0) {
                            $Angle = rand(0,360);
                        } else {
                            $Angle = $this->getAngle($X1,$Y1,$X2,$Y2) + 180;
                        }

                        if ( $Force > 1 ) {
                            $this->Data[$Key]["Vectors"][] = array("Type"=>"R","Angle"=>$Angle % 360,"Force"=>$Force);
                        }
                    }
                }
            }
...
 


Fri Apr 20, 2012 6:42 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 1 post ] 

Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron