/* StarCoord.m  CopyRight 1992 Steve Ludtke  All Rights Reserved 	    */
/* This object distributes the branches in all directions around a starting */
/* point in 3d. Has a tendency (intentional) to move up and down more than  */
/* left and right.							    */

#import "StarCoord.h"
#import <stdio.h>
#import <math.h>
#import <libc.h>

@implementation StarCoord

/* get useful pointers */
- start: (Root *) Ptop: Pobject:(char *)path
{
    object = Pobject;
    return self;
}

/* set coordinates of branch */
- setCoord:(Branch *) branch
{
    unsigned char      *adr;
    float               c, t, m;

    c = atan2(1.0, 2.0);
/* network address + port are split into 3, 2 byte words and used as */
/* x,y,z coordinates for the Root Branch 			     */
    if (branch->prev == NULL) {
	adr = (unsigned char *)&branch->root->addr;
	branch->x = adr[0] * 256 + adr[3];
	branch->y = adr[1] * 256 + ((branch->root->port >> 8) & 255);
	branch->z = adr[2] * 256 + (branch->root->port & 255);
	return self;
    }

/* if we are looking at a web link, point towards the destination in the */
/* x-y plane (reduces crossed wires).					 */
    if (branch->link == NULL)
	c = frand(0, M_PI * 2.0);
    else
	c = atan2(branch->link->y - branch->prev->y, branch->link->x - branch->prev->x);

/* for the first branch, go in a random direction. After that only go in */
/* the up or down half sphere.						 */
    if (branch->level == 1)
	t = frand(-M_PI / 2.0, M_PI / 2.0);
    else if (branch->z - branch->root->branch.z > 0.0)
	t = frand(0.0, M_PI / 2.0);
    else
	t = frand(-M_PI / 2.0, 0.0);

/* c==chi=azimuth  t==theta=altitude in spherical coords */
    m = 1.5 / (float)branch->level;

    branch->x = branch->prev->x + cos(c) * cos(t) * m;
    branch->y = branch->prev->y + sin(c) * cos(t) * m;
    branch->z = branch->prev->z + sin(t) * m;

    return self;
}

/* no prefs yet */
- preferences:sender
{
    return self;
}

/* be helpful */
- (char *)help:window :browser
{
    return ("StarCoord - Steve Ludtke  May 1992\n\nThis is another simple example of a Coord object. This one splits the 6 bytes of address/port# into 2 16 bit words and uses the results as x,y,z coordinates for the center of the object. Branches spread both up and down from the center in a rather haphazard fashion. This is hardly an ideal distribution method, but it is a good, simple example.\n");
}

@end
