import java.util.*;

const int edge = EDGE_0;

module Arrow(Node to) ==> Line(new Vector3f(to-this));
static const int ANZ = 80;
static Sphere[] all;
static Sphere start;
static Sphere act;
static Sphere next = null;


protected void init ()
[
	Axiom ==> 
	for (int i:(0:ANZ))([Sphere(1).(setShader(BLUE))]);
	{
		apply();
		init1();
		start = selectWhereMin((*s:Sphere*),(s.getTranslation().y));
		act = start;
		all = array((* s:Sphere*));
	}
]

private void init1()
[
	{
		Random r = new Random((new Date()).getTime());
		
	}
	s:Sphere, (s.getRadius() == 1) ::> {
		
		s.setTransform((r.nextInt(10000)/100),(r.nextInt(10000)/100),0);
	}
]


public void jarvis () {
	
	if(next==start) return;
	
	next = getNextNode(act);
	conn(next,act);
	next.setShader(WHITE);
	act = next;
	

}

private Sphere getNextNode(Sphere s) {

	Sphere min = 
		selectRandomly((*t:Sphere,(t.getShader()!=WHITE)*),(t.getTranslation().x));
	
	for (int i=0; i< all.length; i++) {
		if((all[i].getShader() == WHITE) || (all[i] == min)){
			continue;
		}

		if(T(s,min,all[i])>0) {
			min = all[i];
		}
	
	}
	return min;
}

private double T(Sphere s1, Sphere s2, Sphere s3) {
	double s1x = s1.getTranslation().x;
	double s1y = s1.getTranslation().y;
	double s2x = s2.getTranslation().x;
	double s2y = s2.getTranslation().y;
	double s3x = s3.getTranslation().x;
	double s3y = s3.getTranslation().y;
	return (((s2x-s1x)*(s3y-s1y))-((s3x-s1x)*(s2y-s1y)));
}

private void conn(Sphere from, Sphere to)
[
	// Kanten von from nach to ziehen
	==>>
	from -edge-> to,
	to -edge-> from,
	// und graphisch darstellen
	from Arrow(to);
]
