コード例 #1
0
ファイル: Trilat2.cpp プロジェクト: EaTea/NetFunWithCNet
Point __trilaterate(const Circle& c1, const Circle& c2, const Circle& c3)
{
	std::vector<Point> intersections;
	findIntersections(intersections,c1,c2);
	findIntersections(intersections,c1,c3);
	findIntersections(intersections,c2,c3);
	
	return polygonCentroid(intersections);
}
コード例 #2
0
ファイル: TimingFunction.cpp プロジェクト: dstockwell/blink
void CubicBezierTimingFunction::partition(Vector<PartitionRegion>& regions) const
{
    double solution1 = 0.0;
    double solution2 = 0.0;
    double solution3 = 0.0;

    size_t numberOfIntersections = findIntersections(0.5, solution1, solution2, solution3);

    // A valid cubic bezier should only cross the horizontal line
    // 1 or 3 times.
    switch (numberOfIntersections) {
    case 1:
        regions.append(PartitionRegion(TimingFunction::RangeHalf::Lower, 0.0, solution1));
        regions.append(PartitionRegion(TimingFunction::RangeHalf::Upper, solution1, 1.0));
        break;
    case 3:
        regions.append(PartitionRegion(TimingFunction::RangeHalf::Lower, 0.0, solution1));
        regions.append(PartitionRegion(TimingFunction::RangeHalf::Upper, solution1, solution2));
        regions.append(PartitionRegion(TimingFunction::RangeHalf::Lower, solution2, solution3));
        regions.append(PartitionRegion(TimingFunction::RangeHalf::Upper, solution3, 1.0));
        break;
    default:
        ASSERT_NOT_REACHED();
        break;
    }
}
コード例 #3
0
ファイル: BVHSceneTree.cpp プロジェクト: ssell/OcularEngine
        void BVHSceneTree::getIntersections(Math::BoundsOBB const& bounds, std::vector<SceneObject*>& objects) const
        {
            objects.clear();
            objects.reserve(m_AllObjects.size());

            findIntersections(m_Root, bounds, objects);
        }
コード例 #4
0
ファイル: BVHSceneTree.cpp プロジェクト: ssell/OcularEngine
        void BVHSceneTree::getIntersections(Math::Ray const& ray, std::vector<std::pair<SceneObject*, float>>& objects) const
        {
            //------------------------------------------------------------
            // Find intersections and their distances from the origin.

            std::vector<std::pair<SceneObject*, float>> intersections;
            intersections.reserve(m_AllObjects.size());

            findIntersections(m_Root, ray, intersections);

            //------------------------------------------------------------
            // Sort the objects based on distance from origin.
            // This is done such that the object nearest the origin is first.
            
            std::sort(intersections.begin(), intersections.end(), [](std::pair<SceneObject*, float>& first, std::pair<SceneObject*, float>& second)->bool
            {
                return (first.second) < (second.second);
            });

            //------------------------------------------------------------
            // Return the sorted intersections

            objects.clear();
            objects.reserve(intersections.size());

            for(auto pair : intersections)
            {
                objects.emplace_back(pair);
            }
        }
コード例 #5
0
ファイル: BVHSceneTree.cpp プロジェクト: ssell/OcularEngine
 void BVHSceneTree::findIntersections(BVHSceneNode* node, Math::BoundsOBB const& bounds, std::vector<SceneObject*>& objects) const
 {
     if(node)
     {
         if(bounds.intersects(node->bounds))
         {
             if(node->type == SceneNodeType::Leaf)
             {
                 objects.emplace_back(node->object);
             }
             else
             {
                 findIntersections(node->left, bounds, objects);
                 findIntersections(node->right, bounds, objects);
             }
         }
     }
 }
コード例 #6
0
ファイル: BVHSceneTree.cpp プロジェクト: ssell/OcularEngine
        void BVHSceneTree::findIntersections(BVHSceneNode* node, Math::BoundsSphere const& bounds, std::vector<SceneObject*>& objects) const
        {
            if(node)
            {
                if(bounds.intersects(node->bounds))
                {
                    if((node->type == SceneNodeType::Leaf) && (node->object))
                    {
                        objects.emplace_back(node->object);
                    }
                    else
                    {
                        findIntersections(node->left, bounds, objects);
                        findIntersections(node->right, bounds, objects);
                    }
                }

                // Do nothing if there is no intersection.
            }
        }
コード例 #7
0
ファイル: BVHSceneTree.cpp プロジェクト: ssell/OcularEngine
        void BVHSceneTree::findIntersections(BVHSceneNode* node, Math::Ray const& ray, std::vector<std::pair<SceneObject*, float>>& objects) const
        {
            if(node)
            {
                Math::Vector3f point;
                float distance;

                if(ray.intersects(node->bounds, point, distance))
                {
                    if((node->type == SceneNodeType::Leaf) && (node->object))
                    {
                        objects.emplace_back(std::make_pair(node->object, distance));
                    }
                    else
                    {
                        findIntersections(node->left, ray, objects);
                        findIntersections(node->right, ray, objects);
                    }
                }
            }
        }
コード例 #8
0
ファイル: tregion.cpp プロジェクト: AmEv7Fam/opentoonz
void TRegion::Imp::computeScanlineIntersections(double y, vector<double> &intersections) const
{
	TRectD bbox = getBBox();
	if (y <= bbox.y0 || y >= bbox.y1)
		return;

	assert(intersections.empty());

	UINT i, firstSide = 0;
	vector<int> sides;

	for (i = 0; i < m_edge.size(); i++) {
		TEdge *e = m_edge[i];

		TStroke *s = e->m_s;
		if (s->getBBox().y0 > y || s->getBBox().y1 < y)
			continue;
		int chunkIndex0, chunkIndex1;
		double t0, t1;
		s->getChunkAndT(e->m_w0, chunkIndex0, t0);
		s->getChunkAndT(e->m_w1, chunkIndex1, t1);

		if (chunkIndex0 > chunkIndex1) {
			findIntersections(y, *s->getChunk(chunkIndex0), t0, 0, intersections, sides);
			for (int j = chunkIndex0 - 1; j > chunkIndex1; j--)
				findIntersections(y, *s->getChunk(j), 1, 0, intersections, sides);
			findIntersections(y, *s->getChunk(chunkIndex1), 1, t1, intersections, sides);
		} else if (chunkIndex0 < chunkIndex1) {
			findIntersections(y, *s->getChunk(chunkIndex0), t0, 1, intersections, sides);
			for (int j = chunkIndex0 + 1; j < chunkIndex1; j++)
				findIntersections(y, *s->getChunk(j), 0, 1, intersections, sides);
			findIntersections(y, *s->getChunk(chunkIndex1), 0, t1, intersections, sides);
		} else {
			findIntersections(y, *s->getChunk(chunkIndex0), t0, t1, intersections, sides);
		}
	}

	if (intersections.size() > 0 && intersections.front() == intersections.back()) {
		intersections.pop_back();
		if (!sides.empty() && sides.front() == sides.back() && intersections.size() > 0)
			intersections.erase(intersections.begin());
	}

	std::sort(intersections.begin(), intersections.end());
	assert(intersections.size() % 2 == 0);
}
コード例 #9
0
 /**
  * Calculate the Y and E values for the given possible overlap
  * @param inputWS :: A pointer to the inputWS
  * @param newPoly :: A reference to a polygon to test for overlap
  * @returns A pair of Y and E values
  */
 std::pair<double,double> 
 SofQW2::calculateYE(API::MatrixWorkspace_const_sptr inputWS,
                     const ConvexPolygon & newPoly) const
 {
   // Build a list intersection locations in terms of workspace indices
   // along with corresponding weights from that location
   std::vector<BinWithWeight> overlaps = findIntersections(inputWS, newPoly);
   std::pair<double,double> binValues(0,0);
   if( inputWS->isDistribution() )
   {
     const double newWidth = newPoly[3].X() - newPoly[0].X(); // For distribution
     binValues = calculateDistYE(inputWS, overlaps, newWidth);
   }
   else
   {
     binValues = calculateYE(inputWS, overlaps);
   }
   return binValues;
 }
コード例 #10
0
MainWindow::MainWindow(QWidget *parent)
	: QMainWindow(parent)
	, m_update_pending(false), m_animating(false)
	, m_fgColor(255, 255, 255), m_bgColor(0, 0, 0)
{
	m_oglviewer = new OGLViewer;

	ui.setupUi(this);
	ui.ogl_layout->addWidget(m_oglviewer);
	//setWindowTitle(tr("OpenGL Qt Template"));

	m_oglviewer->setFocusPolicy(Qt::StrongFocus);
	connect(ui.clear_button, SIGNAL(clicked()), m_oglviewer, SLOT(clearVertex()));
	connect(ui.curve_type, SIGNAL(currentIndexChanged(int)), m_oglviewer, SLOT(changeCurveType(int)));
	connect(ui.degree_val, SIGNAL(valueChanged(int)), m_oglviewer, SLOT(setDegree(int)));
	connect(ui.seg_val, SIGNAL(valueChanged(int)), m_oglviewer, SLOT(setSegment(int)));

	connect(ui.actionOpen, SIGNAL(triggered()), this, SLOT(readPoints()));
	connect(ui.actionSave, SIGNAL(triggered()), this, SLOT(savePoints()));
	connect(ui.actionExport, SIGNAL(triggered()), this, SLOT(exportSVG()));

	signalMapper = new QSignalMapper(this);
	connect(signalMapper, SIGNAL(mapped(int)), m_oglviewer, SLOT(changeOperation(int)));
	signalMapper->setMapping(ui.actionInsert, 0);
	signalMapper->setMapping(ui.actionMove, 1);
	connect(ui.actionInsert, SIGNAL(triggered()), signalMapper, SLOT(map()));
	connect(ui.actionMove, SIGNAL(triggered()), signalMapper, SLOT(map()));

	connect(ui.intersection_button, SIGNAL(clicked()), m_oglviewer, SLOT(findIntersections()));

	connect(ui.disp_ctrl_pts, SIGNAL(toggled(bool)), m_oglviewer, SLOT(setDispCtrlPts(bool)));
	connect(ui.disp_curves, SIGNAL(toggled(bool)), m_oglviewer, SLOT(setDispCurves(bool)));
	connect(ui.disp_intersections, SIGNAL(toggled(bool)), m_oglviewer, SLOT(setDispIntersections(bool)));

	ui.foreground_color->setStyleSheet("QPushButton { background-color : #FFFFFF;}");
	ui.background_color->setStyleSheet("QPushButton { background-color : #000000;}");
	connect(ui.foreground_color, SIGNAL(clicked()), this, SLOT(pickColor()));
	
}
コード例 #11
0
ファイル: octree.cpp プロジェクト: ervanalb/ao
/*
 *  Vertex positioning is based on [Kobbelt et al, 2001]
 */
float Octree::findVertex(Evaluator* e)
{
    findIntersections(e);

    // Find the center of intersection positions
    glm::vec3 center = std::accumulate(
            intersections.begin(), intersections.end(), glm::vec3(),
            [](const glm::vec3& a, const Intersection& b)
                { return a + b.pos; }) / float(intersections.size());

    /*  The A matrix is of the form
     *  [n1x, n1y, n1z]
     *  [n2x, n2y, n2z]
     *  [n3x, n3y, n3z]
     *  ...
     *  (with one row for each Hermite intersection)
     */
    Eigen::MatrixX3f A(intersections.size(), 3);
    for (unsigned i=0; i < intersections.size(); ++i)
    {
        auto d = intersections[i].norm;
        A.row(i) << Eigen::Vector3f(d.x, d.y, d.z).transpose();
    }

    /*  The B matrix is of the form
     *  [p1 . n1]
     *  [p2 . n2]
     *  [p3 . n3]
     *  ...
     *  (with one row for each Hermite intersection)
     *
     *  Positions are pre-emtively shifted so that the center of the contoru
     *  is at 0, 0, 0 (since the least-squares fix minimizes distance to the
     *  origin); we'll unshift afterwards.
     */
    Eigen::VectorXf B(intersections.size(), 1);
    for (unsigned i=0; i < intersections.size(); ++i)
    {
        B.row(i) << glm::dot(intersections[i].norm,
                             intersections[i].pos - center);
    }

    // Use singular value decomposition to solve the least-squares fit.
    Eigen::JacobiSVD<Eigen::MatrixX3f> svd(A, Eigen::ComputeFullU |
                                              Eigen::ComputeFullV);

    // Truncate singular values below 0.1
    auto singular = svd.singularValues();
    svd.setThreshold(0.1 / singular.maxCoeff());
    rank = svd.rank();

    // Solve the equation and convert back to cell coordinates
    Eigen::Vector3f solution = svd.solve(B);
    vert = glm::vec3(solution.x(), solution.y(), solution.z()) + center;

    // Clamp vertex to be within the bounding box
    vert.x = std::min(X.upper(), std::max(vert.x, X.lower()));
    vert.y = std::min(Y.upper(), std::max(vert.y, Y.lower()));
    vert.z = std::min(Z.upper(), std::max(vert.z, Z.lower()));

    // Find and return QEF residual
    auto m = A * solution - B;
    return m.transpose() * m;
}
コード例 #12
0
ファイル: clipping.c プロジェクト: Tarrasch/easyVision
// Perform clipping of the polygon clip with nc points against
// a subject with ns points. Returns a set of nl polygons with specified lengths
// in an array of coordinates polys.
int clip(double *clipx, double *clipy, int nc,
            double *subjectx, double *subjecty, int ns,
                double **polysx, double **polysy, int **origin, int **lengths, int *nl, int *nlp, int *inside, int op)
{
    struct vertex *lclip, *lsubject;
    struct vertex *polygons = NULL, *polygons2 = NULL, *auxpoly = NULL;
    int cIntExt=0, sIntExt=0;
    int nvertex, nvertex2, npolys, npolys2;

    // create data structures
    createList(1,clipx, clipy, nc, &lclip);
    createList(2,subjectx, subjecty, ns, &lsubject);

    //printf("created lists\n");

    // phase one of the algorithm
    findIntersections(lclip, lsubject);

    //printf("found intersections\n");

    switch(op) {
        case POLYGON_UNION:
            cIntExt = sIntExt = POLYGON_INTERIOR;
            break;
        case POLYGON_INTERSECTION:
            cIntExt = sIntExt = POLYGON_EXTERIOR;
            break;
        case POLYGON_DIFF_AB:
            cIntExt = POLYGON_EXTERIOR;
            sIntExt = POLYGON_INTERIOR;
            break;
        case POLYGON_XOREXT:
            cIntExt = POLYGON_EXTERIOR;
            sIntExt = POLYGON_INTERIOR;
            break;
        case POLYGON_DIFF_BA:
            cIntExt = POLYGON_INTERIOR;
            sIntExt = POLYGON_EXTERIOR;
            break;
        }

    markEntries(lclip, lsubject, sIntExt);
    markEntries(lsubject, lclip, cIntExt);

    //printf("marked entries\n");

    // phase three of the algorithm
    npolys = createClippedPolygon(lclip, lsubject, &polygons, &nvertex);

    if(op==POLYGON_XOREXT && npolys > 0) {
        cIntExt = POLYGON_INTERIOR;
        sIntExt = POLYGON_EXTERIOR;

        markEntries(lclip, lsubject, sIntExt);
        markEntries(lsubject, lclip, cIntExt);

        npolys2 = createClippedPolygon(lclip, lsubject, &polygons2, &nvertex2);

        // number of "positive" polygons:
        *nlp = npolys;

        npolys += npolys2;
        nvertex += nvertex2;

        auxpoly = polygons;
        while(auxpoly->nextPoly)
            auxpoly = auxpoly->nextPoly;
        auxpoly->nextPoly = polygons2;

    } else {
        // only xorext operation uses nlp:
        *nlp = 0;
    }

    //printf("clip polygon\n");

    
    // copy polygons into polys array
    copy(polygons, npolys, nvertex, polysx, polysy, origin, lengths);
    *nl = npolys;

    //printf("copied\n");

    *inside = 0;
    if (isInside(lclip,lsubject)) *inside = 1;
    if (isInside(lsubject,lclip)) *inside = 2;

    // free memory
    deleteList(lclip);
    deleteList(lsubject);
    deletePolygons(polygons);

    return 0;
}
コード例 #13
0
   ///   The main clipping function
std::vector<UPolygon*> clip(UPolygon* p0, UPolygon* p1)
{
//Step one is to identify all of the intersection points between the two UPolygon;
findIntersections(p1,p0);

std::vector<UPolygon*> polygons;// = new std::vector<UPolygon*>();
      NAME names[2] = {p0->name, p1->name};

        // get next entering intersection
        PointNode* entering = findEnteringIntersection(p1->pointList, p1->name);

         while (entering != NULL) {

            UPolygon* newPoly = new UPolygon(CLIP);

            PointNode* current = entering;
            int currentPoly = 1;
            while (false == current->visited) {

                newPoly->addPoint(current->x, current->y);

                current->visited = true;


                if (current->isIntersection(names[currentPoly]) && current != entering)
                    currentPoly = (currentPoly + 1) % 2;


                current = current->next[names[currentPoly]];
                if (current == NULL) {
                    // time to wrap
                    if (currentPoly == 0)
                        current = p0->pointList;
                    else
                        current = p1->pointList;
              }
            }

            polygons.push_back(newPoly);
              entering = findEnteringIntersection(current->next[p1->name], p1->name);
      }



        if (polygons.size() == 0) {
            /*
            # we  found no polygons - possibly one is contained in the other
            # first check to see if our clipping region contains the other one
            # theoretically, any point will do, except that all of the end
            # points might intersect the boundary of the shape - and thus fail
            # the containment test. So, we pick a point that is halfway along
            # the first edge and one unit vector in the direction opposite the
            # perp vector
          */
            PointNode* A = p1->pointList;
            PointNode* B = p1->pointList->next[p1->name];
            Vector b = *B - *A;
            Vector b_perp = b.perp();
            b_perp.normalize();
            int x = .5 * (A->x + B->x) - b_perp.x;
            int y = .5 * (A->y + B->y) - b_perp.y;

            if (p0->contains(x,y)) {
                // make a copy of poly0
                UPolygon* newPoly = new UPolygon(SUBJECT);
                PointNode* pt = p0->pointList;
                while(pt != NULL) {
                    newPoly->addPoint(pt->x,pt->y);
                    pt = pt->next[p0->name];
                }
                polygons.push_back(newPoly);
            }
           // now check to see if the clipping region is enclosed by the other
            else {
                PointNode* A = p0->pointList;
                PointNode* B = p0->pointList->next[p0->name];
                Vector b = *B - *A;
                Vector b_perp = b.perp();
                b_perp.normalize();
                x = .5 * (A->x + B->x) - b_perp.x;
                y = .5 * (A->y + B->y) - b_perp.y;

                if (p1->contains(x,y)) {
                   // make a copy of poly0
                    UPolygon* newPoly = new UPolygon(SUBJECT);
                    PointNode* pt = p1->pointList;
                    while(pt != NULL) {
                        newPoly->addPoint(pt->x,pt->y);
                        pt = pt->next[p1->name];
                    }
                    polygons.push_back(newPoly);
                }
                else //return two base polygons
                {
                    polygons.push_back(p0);
                    polygons.push_back(p1);
                }


            }

        }
return polygons;
}
コード例 #14
0
ファイル: polygon.cpp プロジェクト: mivihe/luola2
void ConvexPolygon::booleanDifference(const ConvexPolygon &hole, std::vector<ConvexPolygon> &list) const
{
    // Special case: this polygon is entirely swallowed by the hole
    if(hole.envelopes(*this))
        return;

    // Special case: the hole is entirely inside this polygon
    if(envelopes(hole)) {
        Points p1, p2;
        splitPolygon(*this, hole, p1, p2);
        ConvexPolygon::make(p1, list);
        ConvexPolygon::make(p2, list);
        return;
    }

    // Common case: hole intersects with this polygon.
    std::vector<bool> visited(vertexCount());
    std::queue<unsigned int> queue;
    queue.push(0);

    // Perform intersection
    unsigned int oldsize = list.size();
    Points poly;
    while(!queue.empty()) {
        int i = queue.front();
        while(i < vertexCount()) {
            // Stop if we've already been here
            if(visited[i])
                break;
            visited[i] = true;

            // Include point if it is not inside the hole
            bool inhole = hole.hasPoint(vertex(i));
            if(!inhole)
                poly.push_back(vertex(i));

            // Check for intersections
            Point isect[2];
            int isectv[2];
            findIntersections(*this, i, i+1, hole, isect, isectv);

            if(isectv[0] >= 0) {
                // Intersection found: this is the start of a hole,
                // except when this edge started inside the hole.
                poly.push_back(isect[0]);
                if(!inhole) {
                    // Start tracing the hole
                    int j = isectv[0];
                    do {
                        // Check for intersections
                        // The first hole edge may intersect with another edges
                        Point hisect[2];
                        int hisectv[2];
                        findIntersections(hole, j+1, j, *this, hisect, hisectv);

                        // There is always one intersection (the one that got us here)
                        if((j == isectv[0] && hisectv[1] >= 0) || (j != isectv[0] && hisectv[0] >= 0)) {
                            // Pick the intersection that is not the one we came in on
                            Point ip;
                            int iv;
                            if(hisectv[1] < 0 || glm::distance2(hisect[0],isect[0]) > glm::distance(hisect[1],isect[0])) {
                                ip = hisect[0];
                                iv = hisectv[0];
                            } else {
                                ip = hisect[1];
                                iv = hisectv[1];
                            }

                            queue.push(i+1);

                            // Avoid adding duplicate point of origin
                            if(glm::distance2(poly.front(), ip) > 0.0001)
                                poly.push_back(ip);
                            i = iv;
                            break;
                        } else {
                            // No intersections? Just add the hole vertex then
                            poly.push_back(hole.vertex(j));
                        }
 
                        if(--j < 0)
                            j = hole.vertexCount() - 1;
                    } while(j != isectv[0]);
                }
            }
            ++i;
        }

        // Partition the generated polygon into convex polygons
        // and add them to the list.
        if(poly.size() >= 3) {
            try {
                ConvexPolygon::make(poly, list);
            } catch(const algorithm::GeometryException &e) {
                // Bad polygons generated... The algorithm works well
                // enough most of the time, let's just roll back the error.
                int changes = list.size() - oldsize;
#ifndef NDEBUG
                cerr << "booleanDifference error: " << e.what() << " (" << changes << " change(s) rolled back)\n";
#endif
                while(changes-->0)
                    list.pop_back();
                list.push_back(*this);
                return;
            }
        }
        poly.clear();
        queue.pop();
    }
}