/** * Returns the intersecting area of @c rectangleA and @c rectangleB. * * Edges that touch (but don't overlap) are not considered to be overlapping. * * If the rectangles do not intersect, returns rectangle @c {{0,0},{0,0}}. */ VuoRectangle VuoPoint2d_rectangleIntersection(VuoRectangle rectangleA, VuoRectangle rectangleB) { float rectangleALeft = rectangleA.center.x - rectangleA.size.x/2.; float rectangleARight = rectangleA.center.x + rectangleA.size.x/2.; float rectangleABottom = rectangleA.center.y - rectangleA.size.y/2.; float rectangleATop = rectangleA.center.y + rectangleA.size.y/2.; float rectangleBLeft = rectangleB.center.x - rectangleB.size.x/2.; float rectangleBRight = rectangleB.center.x + rectangleB.size.x/2.; float rectangleBBottom = rectangleB.center.y - rectangleB.size.y/2.; float rectangleBTop = rectangleB.center.y + rectangleB.size.y/2.; float tolerance = 0.00001; if ( rectangleARight < rectangleBLeft + tolerance || rectangleBRight < rectangleALeft + tolerance || rectangleATop < rectangleBBottom + tolerance || rectangleBTop < rectangleABottom + tolerance) return VuoRectangle_make(0,0,0,0); else { float intersectionLeft = MAX(rectangleALeft, rectangleBLeft); float intersectionRight = MIN(rectangleARight, rectangleBRight); float intersectionBottom = MAX(rectangleABottom, rectangleBBottom); float intersectionTop = MIN(rectangleATop, rectangleBTop); return VuoRectangle_make( (intersectionLeft + intersectionRight)/2., (intersectionBottom + intersectionTop)/2., intersectionRight - intersectionLeft, intersectionTop - intersectionBottom); } }
/** * Transforms @c rectangle using @c matrix (a column-major matrix of 16 values), and returns the new rectangle. * * If the matrix specifies a rotation, this function returns an axis-aligned rectangle fully enclosing the source rectangle. * * @see VuoTransform_getMatrix */ VuoRectangle VuoTransform_transformRectangle(const float *matrix, VuoRectangle rectangle) { VuoReal left = rectangle.center.x - rectangle.size.x/2.; VuoReal right = rectangle.center.x + rectangle.size.x/2.; VuoReal bottom = rectangle.center.y - rectangle.size.y/2.; VuoReal top = rectangle.center.y + rectangle.size.y/2.; VuoPoint3d topLeft = VuoTransform_transformPoint(matrix, VuoPoint3d_make(left, top, 0.)); VuoPoint3d topRight = VuoTransform_transformPoint(matrix, VuoPoint3d_make(right, top, 0.)); VuoPoint3d bottomLeft = VuoTransform_transformPoint(matrix, VuoPoint3d_make(left, bottom, 0.)); VuoPoint3d bottomRight = VuoTransform_transformPoint(matrix, VuoPoint3d_make(right, bottom, 0.)); VuoReal transformedLeft = MIN(MIN(MIN(topLeft.x, topRight.x), bottomLeft.x), bottomRight.x); VuoReal transformedRight = MAX(MAX(MAX(topLeft.x, topRight.x), bottomLeft.x), bottomRight.x); VuoReal transformedBottom = MIN(MIN(MIN(topLeft.y, topRight.y), bottomLeft.y), bottomRight.y); VuoReal transformedTop = MAX(MAX(MAX(topLeft.y, topRight.y), bottomLeft.y), bottomRight.y); VuoRectangle transformedRectangle = VuoRectangle_make( (transformedLeft + transformedRight)/2., (transformedBottom + transformedTop)/2., transformedRight - transformedLeft, transformedTop - transformedBottom); return transformedRectangle; }
/** * Returns the union area of @c rectangleA and @c rectangleB. */ VuoRectangle VuoPoint2d_rectangleUnion(VuoRectangle rectangleA, VuoRectangle rectangleB) { VuoReal left = MIN(rectangleA.center.x - rectangleA.size.x/2., rectangleB.center.x - rectangleB.size.x/2.); VuoReal right = MAX(rectangleA.center.x + rectangleA.size.x/2., rectangleB.center.x + rectangleB.size.x/2.); VuoReal bottom = MIN(rectangleA.center.y - rectangleA.size.y/2., rectangleB.center.y - rectangleB.size.y/2.); VuoReal top = MAX(rectangleA.center.y + rectangleA.size.y/2., rectangleB.center.y + rectangleB.size.y/2.); return VuoRectangle_make( (left + right)/2., (bottom + top)/2., right - left, top - bottom); }