Example #1
0
int FindTrack(StdHepWindow *window, int x, int y)
{
    PhaseParticle *p;
    SpinSegment seg;
    double length;
    int i, minIndex, iok;
    short xs1, ys1, xs2, ys2;	/* window coordinates of a track segment */
    double rp, thetap;		/* pick point translated by xs1, ys1 & polar */
    double rs, thetas;		/* segment translated by xs1, ys1 & polar */
    double segLength;		/* length of segment in window coordinates */
    double xpPrime, ypPrime;	/* pick pt translated and rotated */
    double dist;		/* distance of current segment from pick pt */
    double minDist = FLT_MAX;	/* distance of closest segment so far */
    double l12a, lo1sq, lo2sq, l12, l12sq, dperpsq, dmidsq, xm12, ym12;		
    PhaseWindow *winp = (PhaseWindow *) window;
    SpaceWindow *wins = (SpaceWindow *) window;
    SpaceVertex *vert;
    
    /*
    ** Loop through all of the particles, finding the one which displays
    ** closest to the pick point
    */
    if (window->type == STDHEP_SPACE ) vert = wins->vertices;
    for (i=0, p=window->event.particles; i<window->event.nParticles;
         i++, p++) {
      if (ParticleVisible(window, p->id, p->stable)) {
    	/* get the line segment representing the particle in the spin widget */
	 if (window->type == STDHEP_PHASE ) 
	   iok = ParticleToSegment(winp, p, &seg, &length);
	   else if (window->type == STDHEP_PARA) {
	   iok = 
	     ParticleToParaSegment((ParaWindow *) wins, p, &seg, &length);
	   } else {
	   iok = TrackToSegment(wins, p, vert, &seg, &length);
	  }  
    	if (iok) {
    	    /* translate it to window coordinates */
    	    SpinTransformPoint(window->spin, seg.x1,seg.y1,seg.z1 ,&xs1, &ys1);
    	    SpinTransformPoint(window->spin, seg.x2,seg.y2,seg.z2, &xs2, &ys2);
    	    /*
    	    ** The criteria for mindistance depends on the type of plots..
    	    ** For Phase Display, work in Polar coordinates, ( Mark Edel),
    	    */
    	    if (window->type == STDHEP_PHASE) {
    	    
    	    /* translate the pick point and the line segment into a new
    	       coordinate system centered on xs1, ys1 and rotated so the
    	       line segment lies along the x axis		     	  */
    	    CartToPolar((double)(x - xs1), (double)(y - ys1), &thetap, &rp);
    	    CartToPolar((double)(xs2 - xs1), (double)(ys2 - ys1), &thetas, &rs);
    	    segLength = rs;
    	    PolarToCart(thetap - thetas, rp, &xpPrime, &ypPrime);
    	    
    	    /* distance can now be figured as distance between point and
    	       the x axis (if the point is within the bounds of the segment),
    	       or the distance from the closer endpoint (if it is not within
    	       the bounds of the segment) */
    	    if (xpPrime < 0)
    	    	dist = sqrt(SQR(xpPrime) + SQR(ypPrime));
    	    else if (xpPrime > segLength)
    	    	dist = sqrt(SQR(xpPrime - segLength) + SQR(ypPrime));
    	    else
    	    	dist = fabs(ypPrime);
    	    } else {
    	    /* 
    	    ** Compute the distance at midpoint. Divide by five to 
    	    ** increase Pick probability..
    	    */
    	    xm12 = (xs1 + xs2)/2.; ym12 = (ys1 + ys2)/2.;
    	    dist = 0.2 *sqrt((x - xm12) * (x - xm12) + (y -ym12) * (y -ym12));
    	    }	
    	    /* remember the particle of minimum distance from the pick point */
    	    if (dist < minDist) {
    	    	minDist = dist;
    	    	minIndex = i;
    	    }
    	}
      }
      if (window->type == STDHEP_SPACE ) vert++;
    }
    /* 
    ** One now has to convert the Segment index to the track Index, 
    ** which depends on the current visibility of the choosen particle.
    */
    if (minDist > MIN_PICK_DIST) return NO_TRACK;
    else  return minIndex;
}
bool RoundedConnectivity (double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, Arcview_File *arcview_file ) {

	XYZ_Point point;

	// calculate the deltas for all simple line segments
	double dxA = x2 - x1;
	double dyA = y2 - y1;
	double drA, alphaA;
	CartToPolar (dxA,dyA,&drA,&alphaA);
	double dxB = x3 - x2;
	double dyB = y3 - y2;
	double drB, alphaB;
	CartToPolar (dxB,dyB,&drB,&alphaB);
	double dxC = x4 - x3;
	double dyC = y4 - y3;
	double drC, alphaC;
	CartToPolar (dxC,dyC,&drC,&alphaC);

	// calculate the intersection point of the incoming and outgoing segments
	double xM, yM;
	IntSecPtOfLines (x1, y1, x2, y2, x3, y3, x4, y4, &xM, &yM);
	double drM2 = Distance (x2, y2, xM, yM);
	double drM3 = Distance (x3, y3, xM, yM);

	// check whether these intersect already (when the intersection is too tight)
	bool ProcessConnection = true;
	if ( PtIsOnLineSegment (x1, y1, x2, y2, xM, yM) ) {
		ProcessConnection = false;
	}
	if ( PtIsOnLineSegment (x3, y3, x4, y4, xM, yM) ) {
		ProcessConnection = false;
	}

	// calculate the intersection point of perpendicular lines at points 2 and 3
	double pi = 4.0 * atan(1.0);
	double dx3N, dy3N, x3N, y3N;
	PolarToCart(drC, alphaC + pi/2.0, &dx3N, &dy3N);
	x3N = x3 + dx3N;
	y3N = y3 + dy3N;
	double dx2N, dy2N, x2N, y2N;
	PolarToCart(drA, alphaA + pi/2.0, &dx2N, &dy2N);
	x2N = x2 + dx2N;
	y2N = y2 + dy2N;
	double xP, yP;
	IntSecPtOfLines (x2, y2, x2N, y2N, x3, y3, x3N, y3N, &xP, &yP);
	double drP2 = Distance (x2, y2, xP, yP);
	double drP3 = Distance (x3, y3, xP, yP);

	// the ratio of the lengths of the two legs to the center of the arc
	double ratio = drP2/drP3;
	if ( drP3/drP2 < ratio ) ratio = drP3/drP2;

	double alphaAB = NormalizeAngleCenter(alphaB - alphaA);
	double alphaBC = NormalizeAngleCenter(alphaC - alphaA);
	double angle_ratio = alphaAB/alphaBC;
	if ( alphaBC/alphaAB < angle_ratio ) angle_ratio = alphaBC/alphaAB;

	if ( ProcessConnection && angle_ratio > 0.2 && angle_ratio < 0.8 && ratio > 0.25 && drM2 < drB*2.0 && drM3 < drB*2.0 && drP2 < 250.0 && drP3 < 250.0 ) {
		double betaP2,betaP3,x,y;
		CartToPolar (xP-x2, yP-y2, &drP2, &betaP2);
		CartToPolar (xP-x3, yP-y3, &drP3, &betaP3);

		double delta = NormalizeAngleCenter(betaP3 - betaP2);

		double beta = betaP2;
		double radius = drP2;
	//	double beta = betaP3;
	//	double radius = drP3;
		int num_pt = 15;
		double exp = 1.0;
		for ( int j=0 ; j<=num_pt ; j++ ) {
			double factor = ( 1.0 + cos(pi*double(j)/num_pt) ) / 2.0;
			beta = betaP2 + delta * j / num_pt;
			radius = drP2 * factor + drP3 * (1.0 - factor);
	//		beta = betaP3 - delta * j / num_pt;
	//		radius = drP3 * factor + drP2 * (1.0 - factor);
			PolarToCart(radius, beta, &x, &y);
			point.x = xP - x;
			point.y = yP - y;
			if (!arcview_file->points.Add (&point)) goto mem_error;
		}
	} else {

		// this is the default behavior as used before rounded connectivity
		point.x = x2;
		point.y = y2;
		if (!arcview_file->points.Add (&point)) goto mem_error;
		point.x = x3;
		point.y = y3;
		if (!arcview_file->points.Add (&point)) goto mem_error;
	}
	return true;

mem_error:
	return (false);
}