//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Determines whether or not the interior of the arc intersects * the interior of the specified rectangle. * * @param x The X coordinate of the rectangle's upper-left corner. * @param y The Y coordinate of the rectangle's upper-left corner. * @param w The width of the rectangle. * @param h The height of the rectangle. * * @return <CODE>true</CODE> if the arc intersects the rectangle, * <CODE>false</CODE> if the arc doesn't intersect the rectangle. */ public override bool Intersects(int x, int y, int w, int h) { double aw = GetWidth(); double ah = GetHeight(); if (w <= 0 || h <= 0 || aw <= 0 || ah <= 0) { return false; } double ext = GetAngleExtent(); if (ext == 0) { return false; } double ax = GetX(); double ay = GetY(); double axw = ax + aw; double ayh = ay + ah; double xw = x + w; double yh = y + h; // check bbox if (x >= axw || y >= ayh || xw <= ax || yh <= ay) { return false; } // extract necessary data double axc = GetCenterX(); double ayc = GetCenterY(); Point sp = GetStartPoint(); Point ep = GetEndPoint(); double sx = sp.GetX(); double sy = sp.GetY(); double ex = ep.GetX(); double ey = ep.GetY(); /* * Try to catch rectangles that intersect arc in areas * outside of rectagle with left top corner coordinates * (Min(center x, start point x, end point x), * Min(center y, start point y, end point y)) * and rigth bottom corner coordinates * (Max(center x, start point x, end point x), * Max(center y, start point y, end point y)). * So we'll check axis segments outside of rectangle above. */ if (ayc >= y && ayc <= yh) { // 0 and 180 if ((sx < xw && ex < xw && axc < xw && axw > x && ContainsAngle(0)) || (sx > x && ex > x && axc > x && ax < xw && ContainsAngle(180))) { return true; } } if (axc >= x && axc <= xw) { // 90 and 270 if ((sy > y && ey > y && ayc > y && ay < yh && ContainsAngle(90)) || (sy < yh && ey < yh && ayc < yh && ayh > y && ContainsAngle(270))) { return true; } } /* * For PIE we should check intersection with pie slices; * also we should do the same for arcs with extent is greater * than 180, because we should cover case of rectangle, which * situated between center of arc and chord, but does not * intersect the chord. */ Rectangle rect = new Rectangle((int)(x + .5), (int)(y + .5), (int)(w + .5), (int)(h + .5)); if (_type == PIE || MathEx.Abs(ext) > 180) { // for PIE: try to find intersections with pie slices if (rect.IntersectsLine((int)(axc + .5), (int)(ayc + .5), (int)(sx + .5), (int)(sy + .5)) || rect.IntersectsLine((int)(axc + .5), (int)(ayc + .5), (int)(ex + .5), (int)(ey + .5))) { return true; } } else { // for CHORD and OPEN: try to find intersections with chord if (rect.IntersectsLine((int)(sx + .5), (int)(sy + .5), (int)(ex + .5), (int)(ey + .5))) { return true; } } // finally check the rectangle corners inside the arc if (Contains(x, y) || Contains(x + w, y) || Contains(x, y + h) || Contains(x + w, y + h)) { return true; } return false; }