float
similarityMeasure1(Triangulation::_Internal::_triangle* s, Triangulation::_Internal::_triangle* t)
{
	if(s==0 || t==0) return 0;

	Triangulation::_Internal::_edge* common = commonEdge(s, t);
	if(common == NULL) return 0;
	Triangulation::_Internal::_vertex* sv = oppositeSideVertex(common, s);
	Triangulation::_Internal::_vertex* tv = oppositeSideVertex(common, t);
	CParticleF pnts[4];
	pnts[0] = sv->p;
	pnts[1] = tv->p;
	pnts[2] = common->vertices[0]->p;
	pnts[3] = common->vertices[1]->p;
	CParticleF c;
	for(int i=0; i<4; ++i)
	{
		c.m_X += pnts[i].m_X;
		c.m_Y += pnts[i].m_Y;
	}
	c.m_X /= 4.0;
	c.m_Y /= 4.0;
	float d = Distance2LineSegment(pnts[2], pnts[3], c) / common->Length();
	return 1.0 / (1.0 + d);
}
float
similarityMeasure(Triangulation::_Internal::_triangle* s, Triangulation::_Internal::_triangle* t)
{
	if(s==0 || t==0) return 0;

	Triangulation::_Internal::_edge* common = commonEdge(s, t);
	float slen = Max(s->edges[0]->Length(), Max(s->edges[1]->Length(), s->edges[2]->Length()));
	float tlen = Max(t->edges[0]->Length(), Max(t->edges[1]->Length(), t->edges[2]->Length()));
	return common->Length() / Max(slen, tlen);
}
vector<Treble>
Saliency(Triangulation::Triangulator& trmap)
{
	vector<float> vlen(trmap.edges.size(), 0);
	for(int i=0; i<trmap.edges.size(); ++i)
	{
		vlen[i] = trmap.edges[i]->Length();
	}
	float alpha = 10.0;
	float beta = Rank(vlen, (int)(vlen.size() * 0.05)) * 5.0;
	printf("beta = %f\n", beta);
	vector<Treble> trebles(trmap.edges.size());
	for(int i=0; i<trmap.edges.size(); ++i)
	{
		Triangulation::_Internal::_edge* edge = trmap.edges[i];
		float prod = 1.0-1/(1+exp(-beta*(edge->Length()-beta)/beta)); //exp(-edge->Length()*edge->Length()/(2*sigma*sigma));
		Triangulation::_Internal::_edge* chosen[] = {NULL, NULL};
		float wgts[2] = {0.0f, 0.0f};
		for(int j=0; j<2; ++j)
		{
			Triangulation::_Internal::_vertex* u = edge->vertices[j];
			Triangulation::_Internal::_vertex* v = edge->vertices[j==0 ? 1: 0]; //the other vertex
			float best = 0;
			for(int k=0; k<u->edges.size(); ++k)
			{
				Triangulation::_Internal::_edge* edge2 = u->edges[k];
				Triangulation::_Internal::_vertex* w = edge2->vertices[0]==u ? edge2->vertices[1]: edge2->vertices[0];
				if(edge == edge2) continue;
				float angle = GetVisualAngle(v->p.m_X, v->p.m_Y, w->p.m_X, w->p.m_Y, u->p.m_X, u->p.m_Y);
				float len = edge2->Length();
				float score = (1.0-cos(angle))/2.0f * (1.0-1/(1+exp(-beta*(len-beta)/beta)));
				if(score > best) 
				{
					best = score;
					chosen[j] = edge2;
					wgts[j] = (1.0-cos(angle))/2.0f;
				}
			}
			prod *= best;
		}
		trebles[i].edge = edge;
		trebles[i].left = chosen[0];
		trebles[i].right = chosen[1];
		trebles[i].fitness = prod;
		trebles[i].leftWeight = wgts[0];
		trebles[i].rightWeight = wgts[1];
	}			
	return trebles;
}