internal void SeekHarmony(IEnumerable<Tag> valueCollection, double SIZE) { double maxOccurance = OccuredCount + 0.1d; // how we scale the whole cloud, 4 would be exactly the size of the area // 3 would be slightlight larger and 5 would be smaller const double ATTRACTION_SCALE = Math.PI; // how much tags that have not cooccurred repel each other // ϕ (golden ratio) gives us a nice aesthic const double REPEL_RATIO = 1.618d; // how much tags that cooccurred attract each other // it must be greater than the repel rate or everything // will fly away from each other const double ATTRACT_RATIO = Math.E; // assume we don't need to be moved Point offset = new Point(0, 0); // work out where the best place in 2d space to be // would be given where all the other tags are foreach (Tag otherTag in valueCollection) { // ignore ourself if (otherTag == this) continue; // work out vector bewteen us and the other tag Polar vector = Trigonometry.CartesianToPolar(this.Point, otherTag.Point); // how far apart? double distance = vector.Magnitude; // how much they repel by default double desiredDistance = maxOccurance * REPEL_RATIO; // did we co-occur with the other tag? int cooccurred = this[otherTag]; if (cooccurred != 0) // we want to closer to the other tag based on frequency desiredDistance /= (cooccurred * (ATTRACTION_SCALE / ATTRACT_RATIO)); // scale the distance based on the play area and how important // the other tag is compared to all the tags we co-occurred with distance = SIZE * (desiredDistance / (ATTRACTION_SCALE * maxOccurance)); distance = (vector.Magnitude - distance); // towards not away // work out what vector needs to be applied to our // current position to move us closer Polar desiredVector = new Polar(vector.Direction, distance); Point offsetPoint = Trigonometry.PolarToCartesian(desiredVector); // accumlate all the proposed changes offset.X += offsetPoint.X; offset.Y -= offsetPoint.Y; } // update our new position, (scaled to fit within play area) // and also scaled to allow gradual movement double rateOfChange = SIZE / ATTRACTION_SCALE; point.X += offset.X / rateOfChange; point.Y += offset.Y / rateOfChange; }hopefully I will post all the code and zip file tomorrow..
Thursday, June 25, 2009
Tag cloud seeking harmony
I'm about to release the code for the tag cloud - here's a teaser of the code that each tag runs to seek harmony:
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment