Esempio n. 1
0
/*
 ** Function : inDiamond()
 ** Purpose  : test whether a point is in, on or outside diamond
 ** Arguments: diamond, point
 ** Returns  : -1 if outside, 0 if on, +1 if in diamond
 ** Notes    :
 */
int
inDiamond (struct diamond testDiamond,
		   struct point testPoint)
{
	int retval = 0;
	int retval2 = 0;
	
	retval = PointLine(&testDiamond.eastmost, &testDiamond.top, &testPoint);
	if (retval >= 0)
	{
		retval2 = PointLine(&testDiamond.top, &testDiamond.westmost, &testPoint);
		if (retval2 == 0)
		{
			retval = 0;
		}
		else if (retval2 < 0)
		{
			return retval2;
		}
		
		retval2 = PointLine(&testDiamond.westmost, &testDiamond.bottom, &testPoint);
		if (retval2 == 0)
		{
			retval = 0;
		}
		else if (retval2 < 0)
		{
			return retval2;
		}

		retval2 = PointLine(&testDiamond.bottom, &testDiamond.eastmost, &testPoint);
		if (retval2 == 0)
		{
			retval = 0;
		}
		else if (retval2 < 0)
		{
			return retval2;
		}
		
	}
	return retval;
}
Esempio n. 2
0
BOOL CTyDirection::PointInObj(float x, float y, float errRange)
{
	ASSERT(errRange>=0);
	if (m_bDelete) return FALSE; 
	if ((x<max(0,__min(m_x0,m_x1)-errRange))&&
			(y<max(0,__min(m_y0,m_y1)-errRange))&&
			(x>__max(m_x0,m_x1)+errRange)&&
			(y>__max(m_y0,m_y1)+errRange)) return FALSE;


  float dist=PointLine(x,y,m_x0,m_y0,m_x1,m_y1);
  if (dist>errRange) return FALSE;
  else return TRUE; 
}
Esempio n. 3
0
/*
 ** Function : ringNesting()
 ** Purpose  : 
 ** Arguments: counter of number of rings, pointer to ring circle
 ** Returns  : pointer to array of nesting information
 ** Notes    : 
 */
int *
ringNesting(int ringCnt, struct ring *rings)
{
	int *nesting = (int *)NULL;
//	struct ring *ringPointers = (struct ring *)NULL;
//    struct ring *tempPointer = (struct ring *)NULL;
	int inner;
	int outer;
	struct ring *innerRing;
	struct ring *outerRing;
	struct point thisPoint;
    struct point firstPoint;
    struct point lineStart;
    struct point lineEnd;
    struct points *aPoints;
    struct points *firstLine;
    struct points *aLine;
    int isfirstP = 0;
    int isfirstL = 0;
    int touching = 0;
	int i, j; /* work variables */
	
	/*
	 ** This is where we consider the nesting of the various rings.
	 ** We do this by setting up a matrix - ringisin - which takes two
	 ** subscripts. The values in this matrix are:
	 **   -2    ring subscript_1 is NOT in ring subscript_2
	 **   -1    ring subscript_1 is NOT in ring subscript_2, but touches it
	 **    0    nesting not decided
	 **   +1    ring subscript_1 is in ring subscript_2, and touches it
	 **   +2    ring subscript_1 is in ring subscript_2
	 **
	 ** The nesting of N rings requires us (initially) to make N*(N-1) 
	 ** ring-in-ring tests. This is not the most efficient it could be, 
	 ** but given the number of rings that (in reality) we are likely 
	 ** to encounter simultaneously, it's probably not too bad.
	 **     N     1    2    3    4    5    6    7    8    9 ...
	 **     Tests 0    2    6   12   20   30   42   56   72 ...
	 **
	 ** Each test tries to determine as quickly as possible the gross
	 ** inclusion and exclusions. If we are looking at rings A and B,
	 ** and asking whether ring A is in ring B then we proceed as follows:
	 **   1) this algorithm works *only* if ring B is convex
	 **   2) for each point on ring A:
	 **      i)  is this point outside box B?
	 **          yes - A is outside B
	 **          touching - A touches B - test more points
	 **          no - test more points
	 **      ii) is this point inside diamond B?
	 **          yes or touching - test more points
	 **          no - test this point of A against each line in B
	 ** So we have to test a point of A against every line of B only if it
	 ** is both inside B's box and outside B's diamond.
	 */
	
    /* DEBUG PRINT: */
    if (tprint != 0)
    {
        fprintf(stderr,"\nRing Nesting:\n");
    }
    /* END DEBUG PRINT */
    
	/* Get enough memory for the array: */
	nesting = malloc(ringCnt*(ringCnt/*-1*/)*sizeof(int));
	/* 
	 * If we could not get enough memory, return the NULL pointer
	 */
	if (nesting == (int *)NULL)
	{
		fprintf(stderr, "ERROR: Could not evaluate ring nesting - no memory\n");
		return nesting;
	}
	
	/*
	 *  Initialise array to all zeros - indicating not yet calculated
	 */
	for (i=0; i<ringCnt; i++)
		for (j=0; j<ringCnt; j++)
			*((nesting)+(ringCnt*i+j)) = 0;
    
    /* 
     *  Now we loop round every ring ("inner") and ask is this in ring "outer",
     *  where "outer" also loops round every ring.
     *  Begin by pointing to the first inner ring:
     */
    innerRing = rings; 
	for (inner=1; inner<=ringCnt; inner++)
	{		
        /*
         *  Point to first outer ring:
         */
        outerRing = rings;
		for (outer=1; outer<=ringCnt; outer++)
		{
            /*
             *  This loop asks (and answers!) the question:
             *    is "inner" inside "outer"?
             */
			
			/* Go round each point on ring "inner" 
			* Logic: 
			*   0) default mark inner as inside outer
			*   1) get the first point of inner
			*   2) test point against box
			*      if outside box then inner is outside outer; exit (go to 6)
			*   3) test point against diamond
			*      if inside diamond then still inside - go to 5)
			*   4) test point against each line of outer
			*      if outside any line, then mark as outside and exit (go to 6)
			*   5) get next point of inner
			*      if this is the first point again, then exit (go to 6)
			*      otherwise go back to 2)
			*   6) end of calculation - exit point
			 */
			
			/* 0) Default mark inner as inside outer: */
			*((nesting)+(ringCnt*inner+outer)) = 2;
            /*    ...and also that they are NOT touching: */
            touching = 0;
			
            /*
             *  If the two rings are the same (i.e. inner == outer) then
             *  clearly they nest - and no further tests are needed:
             */
            if (inner == outer)
            {
                goto foundnest;
            }
            
			/* 1) Get first point of inner ring */
			thisPoint = innerRing->pts->pt;
            firstPoint = thisPoint;
            isfirstP = 0;
            aPoints = innerRing->pts;
			
            while (isfirstP == 0)
            {
			/* 2) Test point against box */
			/* If it is outside the box, then it is outside the ring */
			if (   (thisPoint.x > outerRing->ringbox.max.x)
				|| (thisPoint.x < outerRing->ringbox.min.x)
				|| (thisPoint.y > outerRing->ringbox.max.y)
				|| (thisPoint.y < outerRing->ringbox.min.y))
			{
				*((nesting)+(ringCnt*inner+outer)) = -2;
				goto foundnest;
			}
			
			/* 3) Test point against diamond */
			/* If it is inside the diamond, then it is inside the ring */
			if ( inDiamond(outerRing->ringdiamond, thisPoint) >=0 )
			{
				*((nesting)+(ringCnt*inner+outer)) = 2;
				goto foundnest;
			}

			/* 4) test point against each line of ring */
			/* 
			 * So we know that this point is inside the box and outside
			 * the diamond - thus we have to test this point against
			 * every line of the (nominally outer) ring. Tedium.
			 * We go into a loop, testing each line separately.
			 * If we are ever outside the line, then we are also outside
			 * the ring. If we are ever touching the line, then we are
			 * touching the ring.
			 * FOR THE MOMENT we are not checking all of the touching
			 * situations - so we only have "inside" and "outside" (20120416)
			 */
                firstLine = outerRing->pts;
                aLine = firstLine;
                isfirstL = 0;
                while (isfirstL == 0)
                {
                    lineStart = aLine->pt;
                    lineEnd = aLine->next->pt;
                    i = PointLine(&lineStart, &lineEnd, &thisPoint);
                    if (i < 0)
                    {
                        *((nesting)+(ringCnt*inner+outer)) = -2;
                        goto foundnest;
                    }
                    else if (i == 0)
                    {
                        /*
                         *  >>>> INSERT MORE CODE HERE >>>>
                         *  This is the "touching" case - that is, we know that
                         *  the point is on the line (or a projection of that
                         *  line).
                         *  ?? do we have to determine whether the point is on
                         *  a projection of the line?? I think we do - because
                         *  only when the point is ON the line do we have the
                         *  case of "touching".
                         */
                    }
                    /*
                     *  Get the next line in the sequence, and check whether we
                     *  are back to the beginning of the outer ring:
                     */
                    aLine = aLine->next;
                    if (aLine == firstLine)
                    {
                        isfirstL = 1;
                    }
                }
                /* 5) get next point of inner */
                aPoints = aPoints->next;
                thisPoint = aPoints->pt;
                if ((thisPoint.x == firstPoint.x) && 
                    (thisPoint.y == firstPoint.y))
                {
                    isfirstP = 1;
                }
            }
			/* 6) end of calculation for *this* inner ring: */
		foundnest:
            /*
             *  If we have the "touching" case, then divide the indicator
             *  by two, to record that fact:
             */
            if (touching != 0)
            {
                *((nesting)+(ringCnt*inner+outer)) = 
                *((nesting)+(ringCnt*inner+outer)) / 2;
            }
            /*
             *  Now point to the next outer ring, and go back to try it
             */
            outerRing = outerRing->next; //NEW
		}
        /*
         *  Now point to the next inner ring, and go back to try it
         */
        innerRing = innerRing->next; 
	}
    
    /* DEBUG PRINT: */
    if (tprint != 0)
    {
        for (inner=1; (inner<=ringCnt); inner++)
        {
            for (outer=1; (outer<=ringCnt); outer++)
            {
                fprintf(stderr,"Nesting: in=%d out=%d nest=%d\n",inner,outer,
                        *((nesting)+(ringCnt*inner+outer)));
            }
        }
    }
    /* END DEBUG PRINT */
    
	return nesting;
}