void drawCollisionIntersection(PixelShape& pixelShape1, PixelShape& pixelShape2, sf::RenderTarget& target) { sf::Sprite shape1 = pixelShape1.getSprite(); sf::Sprite shape2 = pixelShape2.getSprite(); sf::FloatRect shapeRect1(shape1.getPosition().x, shape1.getPosition().y, shape1.getTexture()->getSize().x, shape1.getTexture()->getSize().y); sf::FloatRect shapeRect2(shape2.getPosition().x, shape2.getPosition().y, shape2.getTexture()->getSize().x, shape2.getTexture()->getSize().y); if (shapeRect1.intersects(shapeRect2)) { float interLeft = std::max(shapeRect1.left, shapeRect2.left); float interTop = std::max(shapeRect1.top, shapeRect2.top); float interRight = std::min(shapeRect1.left + shapeRect1.width, shapeRect2.left + shapeRect2.width); float interBottom = std::min(shapeRect1.top + shapeRect1.height, shapeRect2.top + shapeRect2.height); /* //Uncomment to view intersection relative to (0, 0) which is used for pixel checking the image interLeft -= shape2.getPosition().x; interRight -= shape2.getPosition().x; interTop -= shape2.getPosition().y; interBottom -= shape2.getPosition().y; */ sf::RectangleShape rs; rs.setPosition(sf::Vector2f(interLeft, interTop)); rs.setSize(sf::Vector2f(interRight - interLeft, interBottom - interTop)); rs.setOutlineThickness(1); rs.setFillColor(sf::Color(255, 0, 255, 100)); target.draw(rs); } }
int main(void) { Avoid::Router *router = new Avoid::Router(Avoid::OrthogonalRouting); // Create the ShapeRef: Avoid::Rectangle shapeRect1(Avoid::Point(0, 0), Avoid::Point(10, 10)); Avoid::ShapeRef *shapeRef1 = new Avoid::ShapeRef(router, shapeRect1); const unsigned int CENTRE = 1; new Avoid::ShapeConnectionPin(shapeRef1, CENTRE, Avoid::ATTACH_POS_CENTRE, Avoid::ATTACH_POS_CENTRE, true, 0.0, Avoid::ConnDirNone); Avoid::Rectangle shapeRect2(Avoid::Point(0, 0), Avoid::Point(10, 10)); Avoid::ShapeRef *shapeRef2 = new Avoid::ShapeRef(router, shapeRect1); Avoid::ConnEnd dstPt(shapeRef1, CENTRE); Avoid::Point srcPt(1.5, 4); Avoid::ConnRef *connRef = new Avoid::ConnRef(router, srcPt, dstPt); // Force inital callback: router->processTransaction(); router->outputDiagram("output/connendmove-1"); Avoid::Point dstPt2(20, 20); connRef->setDestEndpoint(dstPt2); router->moveShape(shapeRef1, 0.5, 0); router->processTransaction(); router->outputDiagram("output/connendmove-2"); srcPt.x += 0.5; connRef->setSourceEndpoint(srcPt); router->moveShape(shapeRef1, 0.5, 0); router->moveShape(shapeRef2, 0, 0.5); srcPt.x += 0.5; connRef->setSourceEndpoint(srcPt); router->moveShape(shapeRef1, 0.5, 0); router->moveShape(shapeRef2, 0, 0.5); srcPt.x += 0.5; connRef->setSourceEndpoint(srcPt); router->moveShape(shapeRef1, 0.5, 0); router->moveShape(shapeRef2, 0, 0.5); srcPt.x += 0.5; connRef->setSourceEndpoint(srcPt); router->moveShape(shapeRef1, 0.5, 0); router->moveShape(shapeRef2, 0, 0.5); router->processTransaction(); router->outputDiagram("output/connendmove-3"); delete router; return 0; }
bool checkCollision(PixelShape& pixelShape1, PixelShape& pixelShape2) { sf::Sprite shape1 = pixelShape1.getSprite(); sf::Sprite shape2 = pixelShape2.getSprite(); sf::FloatRect shapeRect1(shape1.getPosition().x, shape1.getPosition().y, shape1.getTexture()->getSize().x, shape1.getTexture()->getSize().y); sf::FloatRect shapeRect2(shape2.getPosition().x, shape2.getPosition().y, shape2.getTexture()->getSize().x, shape2.getTexture()->getSize().y); if (shapeRect1.intersects(shapeRect2)) { float interLeft = std::max(shapeRect1.left, shapeRect2.left); float interTop = std::max(shapeRect1.top, shapeRect2.top); float interRight = std::min(shapeRect1.left + shapeRect1.width, shapeRect2.left + shapeRect2.width); float interBottom = std::min(shapeRect1.top + shapeRect1.height, shapeRect2.top + shapeRect2.height); sf::FloatRect intersectRelativeRect1(interLeft - shape1.getPosition().x, interTop - shape1.getPosition().y, interRight - interLeft, interBottom - interTop); sf::FloatRect intersectRelativeRect2(interLeft - shape2.getPosition().x, interTop - shape2.getPosition().y, interRight - interLeft, interBottom - interTop); const sf::Image pixelImage1 = pixelShape1.getImage(); const sf::Image pixelImage2 = pixelShape2.getImage(); //width and height are the same for both intersections bool bitmask1[int(intersectRelativeRect1.height)+1][int(intersectRelativeRect1.width)+1]; bool bitmask2[int(intersectRelativeRect1.height)+1][int(intersectRelativeRect1.width)+1]; for (unsigned int y = 0; y < int(intersectRelativeRect1.height)+1; ++y) { for (unsigned int x = 0; x < int(intersectRelativeRect1.width)+1; ++x) { bitmask1[y][x] = false; bitmask2[y][x] = false; } } for (unsigned int x = intersectRelativeRect1.left; x < intersectRelativeRect1.left + intersectRelativeRect1.width; ++x) { for (unsigned int y = intersectRelativeRect1.top; y < intersectRelativeRect1.top + intersectRelativeRect1.height; ++y) { if (pixelImage1.getPixel(x, y).a > 0) { //std::cout << int(y - intersectRelativeRect1.top) << ", " << int(x - intersectRelativeRect1.left) << "\n"; //std::cout << int(intersectRelativeRect1.height)+1 << ", " << int(intersectRelativeRect1.width)+1 << "\n\n"; bitmask1[int(y - intersectRelativeRect1.top)][int(x - intersectRelativeRect1.left)] = true; } } } for (unsigned int x = intersectRelativeRect2.left; x < intersectRelativeRect2.left + intersectRelativeRect2.width; ++x) { for (unsigned int y = intersectRelativeRect2.top; y < intersectRelativeRect2.top + intersectRelativeRect2.height; ++y) { if (pixelImage2.getPixel(x, y).a > 0) { //std::cout << int(y - intersectRelativeRect2.top) << ", " << int(x - intersectRelativeRect2.left) << "\n"; //std::cout << int(intersectRelativeRect2.height)+1 << ", " << int(intersectRelativeRect2.width)+1 << "\n\n"; bitmask2[int(y - intersectRelativeRect2.top)][int(x - intersectRelativeRect2.left)] = true; } } } for (int y = 0; y < int(intersectRelativeRect2.height)+1; ++y) { for (int x = 0; x < int(intersectRelativeRect2.width)+1; ++x) { if (bitmask1[y][x] && bitmask2[y][x]) { return true; } } } } return false; }
int main(void) { Avoid::Router *router = new Avoid::Router(Avoid::OrthogonalRouting); router->setRoutingPenalty((Avoid::PenaltyType)0, 50); Avoid::Rectangle shapeRect1(Avoid::Point(0, 0), Avoid::Point(30, 20)); Avoid::ShapeRef *shapeRef1 = new Avoid::ShapeRef(router, shapeRect1); Avoid::Rectangle shapeRect2(Avoid::Point(70, 7), Avoid::Point(100, 27)); new Avoid::ShapeRef(router, shapeRect2); Avoid::Rectangle shapeRect3(Avoid::Point(50, 60), Avoid::Point(80, 155)); new Avoid::ShapeRef(router, shapeRect3); Avoid::Rectangle shapeRect4(Avoid::Point(125, 60), Avoid::Point(155, 80)); new Avoid::ShapeRef(router, shapeRect4); Avoid::Rectangle shapeRect5(Avoid::Point(15, 150), Avoid::Point(45, 170)); Avoid::ShapeRef *shapeRef5 = new Avoid::ShapeRef(router, shapeRect5); Avoid::Rectangle shapeRect6(Avoid::Point(130, 130), Avoid::Point(160, 150)); Avoid::ShapeRef *shapeRef6 = new Avoid::ShapeRef(router, shapeRect6); // Add a centre connection pin for the three shapes we'll be using. new Avoid::ShapeConnectionPin(shapeRef1, Avoid::CONNECTIONPIN_CENTRE, Avoid::ATTACH_POS_CENTRE, Avoid::ATTACH_POS_CENTRE, true, 0.0, Avoid::ConnDirNone); new Avoid::ShapeConnectionPin(shapeRef5, Avoid::CONNECTIONPIN_CENTRE, Avoid::ATTACH_POS_CENTRE, Avoid::ATTACH_POS_CENTRE, true, 0.0, Avoid::ConnDirNone); new Avoid::ShapeConnectionPin(shapeRef6, Avoid::CONNECTIONPIN_CENTRE, Avoid::ATTACH_POS_CENTRE, Avoid::ATTACH_POS_CENTRE, true, 0.0, Avoid::ConnDirNone); Avoid::ConnEnd srcEnd(shapeRef1, Avoid::CONNECTIONPIN_CENTRE); Avoid::ConnEnd dstEnd(shapeRef6, Avoid::CONNECTIONPIN_CENTRE); Avoid::ConnRef *conn1= new Avoid::ConnRef(router, srcEnd, dstEnd); router->processTransaction(); router->outputInstanceToSVG("output/junction04-1"); // Split the connector on its second segment and add a junction point. std::pair<Avoid::JunctionRef *, Avoid::ConnRef *> newObjs = conn1->splitAtSegment(2); router->processTransaction(); router->outputInstanceToSVG("output/junction04-2"); // Create a connector from the centre of shape 5 that connects to // the junction. Avoid::ConnEnd srcEnd3(shapeRef5, Avoid::CONNECTIONPIN_CENTRE); Avoid::ConnEnd dstEnd3(newObjs.first); new Avoid::ConnRef(router, srcEnd3, dstEnd3); router->processTransaction(); router->outputInstanceToSVG("output/junction04-3"); // Delete one half of the original connector, up to the junction. router->deleteConnector(conn1); conn1 = NULL; router->processTransaction(); router->outputInstanceToSVG("output/junction04-4"); // The junction just has two connector now, so merge these into one. newObjs.first->removeJunctionAndMergeConnectors(); router->processTransaction(); router->outputInstanceToSVG("output/junction04-5"); router->processTransaction(); delete router; return 0; }