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); }