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