// LAB 1 SOLUTION, Part I // IsPointInside, IntersectingRectangle #include "SWindows.h" #include "Graphics.h" #include "Mouse.h" #include "Delay.h" #include "Text.h" //On a PC, uncomment these includes and comment out those above //#include "ct_windows.h" //#include "ct_graphics.h" //#include "ct_mouse.h" //#include "ct_delay.h" //#include "ct_text.h" #include "IOTools.h" #include "MathUtil.h" #include "Random.h" // for RandomLong(..) #include #include // for random numbers seed // myDot is represented as a circle struct myDot { // x and y are the co-ordinates of the center of the dot int x_center; int y_center; int radius; myDot() { x_center = 0; y_center = 0; } myDot(int, int, int); void Draw(); }; // Constructor for myDot - takes in as input parameters // the x-coordinate and y-coordinate of the center of the dot // along with the radius myDot::myDot(int x, int y, int rad) { x_center = x; y_center = y; radius = rad; } // Draws the point on the screen void myDot::Draw() { PaintCircle(x_center, y_center, radius); } // Define a rectangle struct struct myRect { int left; // coordinates of the upper-left corner int top; int right; // coordinates of the lower-right corner int bottom; // Constructor which sets all values = 0 myRect() { left = 0; top = 0; right = 0; bottom = 0;} myRect(int,int,int,int); bool IsPointInside( const myDot& ); void DrawSolid(); void DrawFrame(); }; // Constructor for myRect. max and min are used to ensure // that even a wrong order of args results is a properly // formed rectangles, i.e. that left <= right and top <= bottom . myRect::myRect(int x1, int y1, int x2, int y2) { left = min(x1,x2); top = min(y1,y2); right = max(x1,x2); bottom = max(y1,y2); } // Draws the rectangle on the screen as a solid rectangle of current color void myRect::DrawSolid() { PaintRect(left, top, right, bottom); } // Draws the rectangle on the screen as a frame rectangle of current color void myRect::DrawFrame() { FrameRect(left, top, right, bottom); } bool myRect::IsPointInside( const myDot& d ){ return ( left <= d.x_center && right >= d.x_center && top <= d.y_center && bottom >= d.y_center ); } // prototypes myRect BoundingRectangle( const myRect&, const myRect& ); myRect IntersectingRectangle( const myRect&, const myRect& ); // definitions void main() { // open text and drawing windows, set random seed BigSquarePair(); SetRandomSeed(); // testing points myRect r0( 100, 100, 300, 300 ); for( int i=0; i < 10; i++ ){ Point p; // Mac standard point GetClickPoint( p ); // await click, fill p with the click position myDot d0( p.h, p.v, 5 ); // p.h and p.v are x and y coords of p // choose color based on where the point d0 lies w.r.t. r0 if( r0.IsPointInside( d0 ) ) SetForeColor( 255, 0, 0 ); // red else SetForeColor( 0, 0, 255 ); // blue d0.Draw(); // the dot is drawn in the color just chosen } // testing rectangles for( int j=0; j < 10; j++ ){ myRect rect1 ( RandomLong(0,400), RandomLong(0,400), RandomLong(0,400), RandomLong(0,400) ); myRect rect2 ( RandomLong(0,400), RandomLong(0,400), RandomLong(0,400), RandomLong(0,400) ); SetForeColor(255, 0, 0); // red rect1.DrawFrame(); SetForeColor(0, 255, 0); // green rect2.DrawFrame(); PressReturn("Press Enter to get the bounding rectangle"); (BoundingRectangle(rect2, rect1)).DrawFrame(); PressReturn("Press Enter to get the intersecting rectangle"); IntersectingRectangle(rect2, rect1).DrawSolid(); PressReturn(); ClearDrawing(); } PressReturn("Done"); } myRect BoundingRectangle( const myRect& R1, const myRect& R2 ){ SetForeColor(0,0,255); // blue myRect r; // Find the min and max x-coordinates of both rectangles r.left = min( R1.left, R2.left ); r.right = max( R1.right, R2.right ); // Find the min and max y-coordinates of both rectangles r.top = min( R1.top, R2.top ); r.bottom = max( R1.bottom, R2.bottom ); return r; } myRect IntersectingRectangle( const myRect& R1, const myRect& R2 ){ // first rule out the case of no intersection myRect res; // zero rectangle created SetForeColor( 0, 0, 0 ); // black // is R1 completely to the right of R2 or vice versa? if( R1.right < R2.left || R2.right < R1.left ) return res; // is R1 completely above R2 or vice versa? if( R1.bottom < R2.top || R2.bottom < R1.top ) return res; // Provided that the rectangles do intersect, // each dimension of the result is either the corresponding // dimension of R1 or of R2. For example, res.left is either // R1.left or R2.left. We only need to choose one of the two. if( R1.left <= R2.left && R2.left <= R1.right ) res.left = R2.left; else res.left = R1.left; if( R1.left <= R2.right && R2.right <= R1.right ) res.right = R2.right; else res.right = R1.right; if( R1.top <= R2.top && R2.top <= R1.bottom ) res.top = R2.top; else res.top = R1.top; if( R1.top <= R2.bottom && R2.bottom <= R1.bottom ) res.bottom = R2.bottom; else res.bottom = R1.bottom; return res; }