예제 #1
0
// "dual" edge-drop problems
// cylinder: zero diam edge/ellipse, r-radius cylinder, find r-offset == cl  (ITO surface XY-slice is a circle)
// sphere: zero diam cylinder. ellipse around edge, find offset == cl (ITO surface slice is ellipse) (?)
// toroid: radius2 diam edge, radius1 cylinder, find radius1-offset-ellipse=cl (ITO surf slice is offset ellipse) (this is the offset-ellipse problem)
// cone: ??? (how is this an ellipse??)
bool MillingCutter::singleEdgeDrop(CLPoint& cl, const Point& p1, const Point& p2, double d) const {    
    Point v = p2 - p1; // vector along edge, from p1 -> p2
    Point vxy( v.x, v.y, 0.0);
    vxy.xyNormalize(); // normalized XY edge vector
    // figure out u-coordinates of p1 and p2 (i.e. x-coord in the rotated system)
    Point sc = cl.xyClosestPoint( p1, p2 );   
    assert( ( (cl-sc).xyNorm() - d ) < 1E-6 );
    // edge endpoints in the new coordinate system, in these coordinates, CL is at origo
    Point up1( (p1-sc).dot(vxy) , d, p1.z); // d, distance to line, is the y-coord in the rotated system
    Point up2( (p2-sc).dot(vxy) , d, p2.z);
    CC_CLZ_Pair contact = this->singleEdgeDropCanonical( up1, up2 ); // the subclass handles this
    CCPoint cc_tmp( sc + contact.first * vxy, EDGE); // translate back into original coord-system
    cc_tmp.z_projectOntoEdge(p1,p2);
    return cl.liftZ_if_InsidePoints( contact.second , cc_tmp , p1, p2);
}
예제 #2
0
/*
For smart monster movement, build a proximity ripple from the player's
position, out to a 'distance' of 20.  For example:

W 5 4 4 W W X    Player is at position marked 1
W 5 W 3 3 W W    W is a wall.  Monsters will attempt
W 6 W 2 W 4 W    to move to a location with a smaller
W 7 W 1 W 5 W    value than their current position.
W 8 W W W 6 W    Note that a monster at location X
W 9 9 8 7 7 7    will not move at all.
W W W 8 W W W
*/
static void build_proximity_ripple(void)
{
	int xl, yl, xh, yh ;
	int k, m, z, tmpx, tmpy;
	int curx, cury, curdist;

	xl=tmp3-2; yl=tmp1-2; xh=tmp4+2;  yh=tmp2+2;
	vxy(&xl,&yl);  vxy(&xh,&yh);
	for (k=yl; k<=yh; k++)
		for (m=xl; m<=xh; m++)
		{
			switch(item[m][k])
			{
			case OWALL:
			case OPIT:
			case OTRAPARROW:
			case ODARTRAP:
			case OCLOSEDDOOR:
			case OTRAPDOOR:
			case OTELEPORTER:
				screen[m][k]=127;
				break;
			case OENTRANCE:
				if (level==1)
					screen[m][k] = 127;
				else
					screen[m][k] = 0;
				break;
			default:
				screen[m][k] = 0;
				break;
			};
		}
		screen[playerx][playery]=1;

		/* now perform proximity ripple from playerx,playery to monster */
		xl=tmp3-1; yl=tmp1-1; xh=tmp4+1;  yh=tmp2+1;
		vxy(&xl,&yl);  vxy(&xh,&yh);

		PUTQUEUE( playerx, playery, 1 );
		do
		{
			GETQUEUE( curx, cury, curdist );

			/* test all spots around the current one being looked at.
			*/
			if ( ( curx >= xl && curx <= xh ) &&
				( cury >= yl && cury <= yh ) )
			{
				for (z=1; z<9; z++)
				{
					tmpx = curx + diroffx[z] ;
					tmpy = cury + diroffy[z] ;
					vxy( &tmpx, &tmpy );
					if (screen[tmpx][tmpy] == 0 )
					{
						screen[tmpx][tmpy] = curdist + 1;
						PUTQUEUE( tmpx, tmpy, curdist + 1 );
					}
				}
			}
		}
		while (!QUEUEEMPTY());
}