当前位置: 首页>>代码示例>>C++>>正文


C++ Intersections类代码示例

本文整理汇总了C++中Intersections的典型用法代码示例。如果您正苦于以下问题:C++ Intersections类的具体用法?C++ Intersections怎么用?C++ Intersections使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了Intersections类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: intersect

bool intersect(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
    if (implicit_matches(q1, q2)) {
        // FIXME: compute T values
        // compute the intersections of the ends to find the coincident span
        bool useVertical = fabs(q1[0].x - q1[2].x) < fabs(q1[0].y - q1[2].y);
        double t;
        if ((t = axialIntersect(q1, q2[0], useVertical)) >= 0) {
            i.addCoincident(t, 0);
        }
        if ((t = axialIntersect(q1, q2[2], useVertical)) >= 0) {
            i.addCoincident(t, 1);
        }
        useVertical = fabs(q2[0].x - q2[2].x) < fabs(q2[0].y - q2[2].y);
        if ((t = axialIntersect(q2, q1[0], useVertical)) >= 0) {
            i.addCoincident(0, t);
        }
        if ((t = axialIntersect(q2, q1[2], useVertical)) >= 0) {
            i.addCoincident(1, t);
        }
        assert(i.fCoincidentUsed <= 2);
        return i.fCoincidentUsed > 0;
    }
    QuadraticIntersections q(q1, q2, i);
    bool result = q.intersect();
    // FIXME: partial coincidence detection is currently poor. For now, try
    // to fix up the data after the fact. In the future, revisit the error
    // term to try to avoid this kind of result in the first place.
    if (i.fUsed && i.fCoincidentUsed) {
        hackToFixPartialCoincidence(q1, q2, i);
    }
    return result;
}
开发者ID:Cue,项目名称:skia,代码行数:32,代码来源:QuadraticIntersection.cpp

示例2: build_facet_tree

void Scene::cut_segment_plane()
{
    // Build tree (if build fail, exit)
    build_facet_tree();
    if ( m_facet_tree.empty() ) {
        return;
    }

    Plane plane = frame_plane();

    // Compute intersections
    typedef std::vector<Facet_tree::Object_and_primitive_id> Intersections;
    Intersections intersections;
    m_facet_tree.all_intersections(plane, std::back_inserter(intersections));

    // Fill data structure
    m_cut_segments.clear();
    for ( Intersections::iterator it = intersections.begin(),
            end = intersections.end() ; it != end ; ++it )
    {
        const Segment* inter_seg = CGAL::object_cast<Segment>(&(it->first));

        if ( NULL != inter_seg )
        {
            m_cut_segments.push_back(*inter_seg);
        }
    }

    m_cut_plane = CUT_SEGMENTS;
}
开发者ID:skyopener,项目名称:OSCCAR-dev,代码行数:30,代码来源:Scene.cpp

示例3: pickAtXY

// This method performs intersection testing at the given XY coords, and returns true if
// any intersections were found. It will break after processing the first pickable Window
// it finds.
bool WindowManager::pickAtXY(float x, float y, WidgetList& wl)
{
    Intersections intr;


    osg::Camera* camera = _view->getCamera();
    osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(camera->getGraphicsContext());
    if (gw)
    {
        _view->computeIntersections(camera, osgUtil::Intersector::WINDOW, x, y, intr, _nodeMask);
    }

    if (!intr.empty())
    {
        // Get the first Window at the XY coordinates; if you want a Window to be
        // non-pickable, set the NodeMask to something else.
        Window* activeWin = 0;

        // Iterate over every picked result and create a list of Widgets that belong
        // to that Window.
        for(Intersections::iterator i = intr.begin(); i != intr.end(); i++) {
            Window* win = dynamic_cast<Window*>(i->nodePath.back()->getParent(0));

            // Make sure that our window is valid, and that our pick is within the
            // "visible area" of the Window.
            if(
                !win ||
                (win->getVisibilityMode() == Window::VM_PARTIAL && !win->isPointerXYWithinVisible(x, y))
            ) {
                continue;
            }

            // Set our activeWin, so that we know when we've got all the Widgets
            // that belong to it.
            if(!activeWin) activeWin = win;

            // If we've found a new Widnow, break out!
            else if(activeWin != win) break;

            Widget* widget = dynamic_cast<Widget*>(i->drawable.get());

            if(!widget) continue;

            // We need to return a list of every Widget that was picked, so
            // that the handler can operate on it accordingly.
            else wl.push_back(widget);
        }

        if(wl.size()) {
            // Potentially VERY expensive; only to be used for debugging. :)
            if(_flags & WM_PICK_DEBUG) _updatePickWindow(&wl, x, y);

            return true;
        }
    }

    if(_flags & WM_PICK_DEBUG) _updatePickWindow(0, x, y);

    return false;
}
开发者ID:yueying,项目名称:osg,代码行数:63,代码来源:WindowManager.cpp

示例4: intersect

bool intersect(double minT1, double maxT1, double minT2, double maxT2) {
    Cubic sub1, sub2;
    // FIXME: carry last subdivide and reduceOrder result with cubic
    sub_divide(cubic1, minT1, maxT1, sub1);
    sub_divide(cubic2, minT2, maxT2, sub2);
    Intersections i;
    intersect2(sub1, sub2, i);
    if (i.used() == 0) {
        return false;
    }
    double x1, y1, x2, y2;
    t1 = minT1 + i.fT[0][0] * (maxT1 - minT1);
    t2 = minT2 + i.fT[1][0] * (maxT2 - minT2);
    xy_at_t(cubic1, t1, x1, y1);
    xy_at_t(cubic2, t2, x2, y2);
    if (AlmostEqualUlps(x1, x2) && AlmostEqualUlps(y1, y2)) {
        return true;
    }
    double half1 = (minT1 + maxT1) / 2;
    double half2 = (minT2 + maxT2) / 2;
    ++depth;
    bool result;
    if (depth & 1) {
        result = intersect(minT1, half1, minT2, maxT2) || intersect(half1, maxT1, minT2, maxT2)
            || intersect(minT1, maxT1, minT2, half2) || intersect(minT1, maxT1, half2, maxT2);
    } else {
        result = intersect(minT1, maxT1, minT2, half2) || intersect(minT1, maxT1, half2, maxT2)
            || intersect(minT1, half1, minT2, maxT2) || intersect(half1, maxT1, minT2, maxT2);
    }
    --depth;
    return result;
}
开发者ID:Cue,项目名称:skia,代码行数:32,代码来源:CubicIntersection_Test.cpp

示例5: intersect

int intersect(const Cubic& c, Intersections& i) {
    // check to see if x or y end points are the extrema. Are other quick rejects possible?
    if (ends_are_extrema_in_x_or_y(c)) {
        return false;
    }
    (void) intersect3(c, c, i);
    if (i.used() > 0) {
        SkASSERT(i.used() == 1);
        if (i.fT[0][0] > i.fT[1][0]) {
            SkTSwap(i.fT[0][0], i.fT[1][0]);
        }
    }
    return i.used();
}
开发者ID:venkatarajasekhar,项目名称:Qt,代码行数:14,代码来源:CubicIntersection.cpp

示例6: computeIntersections

bool Widget::computeIntersections(osgGA::EventVisitor* ev, osgGA::GUIEventAdapter* event, Intersections& intersections, osg::Node::NodeMask traversalMask) const
{
    osgGA::GUIActionAdapter* aa = ev ? ev->getActionAdapter() : 0;
    osgUtil::LineSegmentIntersector::Intersections source_intersections;
    if (aa && aa->computeIntersections(*event, ev->getNodePath(), source_intersections, traversalMask))
    {
        typedef std::vector<const osgUtil::LineSegmentIntersector::Intersection*> IntersectionPointerList;
        IntersectionPointerList intersectionsToSort;

        // populate the temporay vector of poiners to the original intersection pointers.
        for(osgUtil::LineSegmentIntersector::Intersections::iterator itr = source_intersections.begin();
            itr != source_intersections.end();
            ++itr)
        {
            if (itr->drawable->getName()!="DepthSetPanel")
            {
                intersectionsToSort.push_back(&(*itr));
            }
        }

        // sort the pointer list into order based on child traversal order, to be consistent with osgUI rendering order.
        std::sort(intersectionsToSort.begin(), intersectionsToSort.end(), SortTraversalOrder());

        // copy the pointers to final Intersection container
        for(IntersectionPointerList::iterator itr = intersectionsToSort.begin();
            itr != intersectionsToSort.end();
            ++itr)
        {
            intersections.push_back(*(*itr));
        }
        return true;
    }
    return false;
}
开发者ID:LaurensVoerman,项目名称:OpenSceneGraph,代码行数:34,代码来源:Widget.cpp

示例7: QDEBUG

void QTessellatorPrivate::addIntersections()
{
    if (scanline.size) {
        QDEBUG() << "INTERSECTIONS";
        // check marked edges for intersections
#ifdef DEBUG
        for (int i = 0; i < scanline.size; ++i) {
            Edge *e = scanline.edges[i];
            QDEBUG() << "    " << i << e->edge << "isect=(" << e->intersect_left << e->intersect_right
                     << ')';
        }
#endif

        for (int i = 0; i < scanline.size - 1; ++i) {
            Edge *e1 = scanline.edges[i];
            Edge *e2 = scanline.edges[i + 1];
            // check for intersection
            if (e1->intersect_right || e2->intersect_left)
                addIntersection(e1, e2);
        }
    }
#if 0
    if (intersections.constBegin().key().y == y) {
        QDEBUG() << "----------------> intersection on same line";
        scanline.clearMarks();
        scanline.processIntersections(y, &intersections);
        goto redo;
    }
#endif
}
开发者ID:KDE,项目名称:android-qt,代码行数:30,代码来源:qtessellator.cpp

示例8: closeEnd

static bool closeEnd(const Cubic& cubic, int cubicIndex, Intersections& i, _Point& pt) {
    int last = i.used() - 1;
    if (i.fT[cubicIndex][last] != 1 || i.fT[cubicIndex][last - 1] < 1 - CLOSE_ENOUGH) {
        return false;
    }
    pt = xy_at_t(cubic, (i.fT[cubicIndex][last] + i.fT[cubicIndex][last - 1]) / 2);
    return true;
}
开发者ID:venkatarajasekhar,项目名称:Qt,代码行数:8,代码来源:CubicIntersection.cpp

示例9: intersect2

// FIXME: add intersection of convex null on cubics' ends with the opposite cubic. The hull line
// segments can be constructed to be only as long as the calculated precision suggests. If the hull
// line segments intersect the cubic, then use the intersections to construct a subdivision for
// quadratic curve fitting.
bool intersect2(const Cubic& c1, const Cubic& c2, Intersections& i) {
#if SK_DEBUG
    debugDepth = 0;
#endif
    bool result = intersect2(c1, 0, 1, c2, 0, 1, 1, i);
    // FIXME: pass in cached bounds from caller
    _Rect c1Bounds, c2Bounds;
    c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ?
    c2Bounds.setBounds(c2);
    result |= intersectEnd(c1, false, c2, c2Bounds, i);
    result |= intersectEnd(c1, true, c2, c2Bounds, i);
    i.swap();
    result |= intersectEnd(c2, false, c1, c1Bounds, i);
    result |= intersectEnd(c2, true, c1, c1Bounds, i);
    i.swap();
    return result;
}
开发者ID:Cue,项目名称:skia,代码行数:21,代码来源:CubicIntersection.cpp

示例10: intersect3

bool intersect3(const Cubic& c1, const Cubic& c2, Intersections& i) {
    bool result = intersect3(c1, 0, 1, c2, 0, 1, 1, i);
    // FIXME: pass in cached bounds from caller
    _Rect c1Bounds, c2Bounds;
    c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ?
    c2Bounds.setBounds(c2);
    result |= intersectEnd(c1, false, c2, c2Bounds, i);
    result |= intersectEnd(c1, true, c2, c2Bounds, i);
    bool selfIntersect = c1 == c2;
    if (!selfIntersect) {
        i.swap();
        result |= intersectEnd(c2, false, c1, c1Bounds, i);
        result |= intersectEnd(c2, true, c1, c1Bounds, i);
        i.swap();
    }
    // If an end point and a second point very close to the end is returned, the second
    // point may have been detected because the approximate quads
    // intersected at the end and close to it. Verify that the second point is valid.
    if (i.used() <= 1 || i.coincidentUsed()) {
        return result;
    }
    _Point pt[2];
    if (closeStart(c1, 0, i, pt[0]) && closeStart(c2, 1, i, pt[1])
            && pt[0].approximatelyEqual(pt[1])) {
        i.removeOne(1);
    }
    if (closeEnd(c1, 0, i, pt[0]) && closeEnd(c2, 1, i, pt[1])
            && pt[0].approximatelyEqual(pt[1])) {
        i.removeOne(i.used() - 2);
    }
    return result;
}
开发者ID:venkatarajasekhar,项目名称:Qt,代码行数:32,代码来源:CubicIntersection.cpp

示例11: CubicIntersection_Test

void CubicIntersection_Test() {
    for (size_t index = firstCubicIntersectionTest; index < tests_count; ++index) {
        const Cubic& cubic1 = tests[index][0];
        const Cubic& cubic2 = tests[index][1];
        Cubic reduce1, reduce2;
        int order1 = reduceOrder(cubic1, reduce1, kReduceOrder_NoQuadraticsAllowed);
        int order2 = reduceOrder(cubic2, reduce2, kReduceOrder_NoQuadraticsAllowed);
        if (order1 < 4) {
            printf("%s [%d] cubic1 order=%d\n", __FUNCTION__, (int) index, order1);
            continue;
        }
        if (order2 < 4) {
            printf("%s [%d] cubic2 order=%d\n", __FUNCTION__, (int) index, order2);
            continue;
        }
        if (implicit_matches(reduce1, reduce2)) {
            printf("%s [%d] coincident\n", __FUNCTION__, (int) index);
            continue;
        }
        Intersections tIntersections;
        intersect(reduce1, reduce2, tIntersections);
        if (!tIntersections.intersected()) {
            printf("%s [%d] no intersection\n", __FUNCTION__, (int) index);
            continue;
        }
        for (int pt = 0; pt < tIntersections.used(); ++pt) {
            double tt1 = tIntersections.fT[0][pt];
            double tx1, ty1;
            xy_at_t(cubic1, tt1, tx1, ty1);
            double tt2 = tIntersections.fT[1][pt];
            double tx2, ty2;
            xy_at_t(cubic2, tt2, tx2, ty2);
            if (!AlmostEqualUlps(tx1, tx2)) {
                printf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                    __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2);
            }
            if (!AlmostEqualUlps(ty1, ty2)) {
                printf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                    __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2);
            }
        }
    }
}
开发者ID:Cue,项目名称:skia,代码行数:43,代码来源:CubicIntersection_Test.cpp

示例12: intersect

bool intersect(const Cubic& cubic, Intersections& i) {
    SkTDArray<double> ts;
    double precision = calcPrecision(cubic);
    cubic_to_quadratics(cubic, precision, ts);
    int tsCount = ts.count();
    if (tsCount == 1) {
        return false;
    }
    double t1Start = 0;
    Cubic part;
    for (int idx = 0; idx < tsCount; ++idx) {
        double t1 = ts[idx];
        Quadratic q1;
        sub_divide(cubic, t1Start, t1, part);
        demote_cubic_to_quad(part, q1);
        double t2Start = t1;
        for (int i2 = idx + 1; i2 <= tsCount; ++i2) {
            const double t2 = i2 < tsCount ? ts[i2] : 1;
            Quadratic q2;
            sub_divide(cubic, t2Start, t2, part);
            demote_cubic_to_quad(part, q2);
            Intersections locals;
            intersect2(q1, q2, locals);
            for (int tIdx = 0; tIdx < locals.used(); ++tIdx) {
            // discard intersections at cusp? (maximum curvature)
                double t1sect = locals.fT[0][tIdx];
                double t2sect = locals.fT[1][tIdx];
                if (idx + 1 == i2 && t1sect == 1 && t2sect == 0) {
                    continue;
                }
                double to1 = t1Start + (t1 - t1Start) * t1sect;
                double to2 = t2Start + (t2 - t2Start) * t2sect;
                i.insert(to1, to2);
            }
            t2Start = t2;
        }
        t1Start = t1;
    }
    return i.intersected();
}
开发者ID:Cue,项目名称:skia,代码行数:40,代码来源:CubicIntersection.cpp

示例13: standardTestCases

static void standardTestCases() {
    for (size_t index = firstQuadIntersectionTest; index < quadraticTests_count; ++index) {
        const Quadratic& quad1 = quadraticTests[index][0];
        const Quadratic& quad2 = quadraticTests[index][1];
        Quadratic reduce1, reduce2;
        int order1 = reduceOrder(quad1, reduce1, kReduceOrder_TreatAsFill);
        int order2 = reduceOrder(quad2, reduce2, kReduceOrder_TreatAsFill);
        if (order1 < 3) {
            printf("[%d] quad1 order=%d\n", (int) index, order1);
        }
        if (order2 < 3) {
            printf("[%d] quad2 order=%d\n", (int) index, order2);
        }
        if (order1 == 3 && order2 == 3) {
            Intersections intersections;
            intersect2(reduce1, reduce2, intersections);
            if (intersections.intersected()) {
                for (int pt = 0; pt < intersections.used(); ++pt) {
                    double tt1 = intersections.fT[0][pt];
                    double tx1, ty1;
                    xy_at_t(quad1, tt1, tx1, ty1);
                    double tt2 = intersections.fT[1][pt];
                    double tx2, ty2;
                    xy_at_t(quad2, tt2, tx2, ty2);
                    if (!approximately_equal(tx1, tx2)) {
                        printf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                            __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2);
                    }
                    if (!approximately_equal(ty1, ty2)) {
                        printf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                            __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2);
                    }
                }
            }
        }
    }
}
开发者ID:venkatarajasekhar,项目名称:Qt,代码行数:37,代码来源:QuadraticIntersection_Test.cpp

示例14: addValidRoots

static void addValidRoots(const double roots[4], const int count, const int side, Intersections& i) {
    int index;
    for (index = 0; index < count; ++index) {
        if (!approximately_zero_or_more(roots[index]) || !approximately_one_or_less(roots[index])) {
            continue;
        }
        double t = 1 - roots[index];
        if (approximately_less_than_zero(t)) {
            t = 0;
        } else if (approximately_greater_than_one(t)) {
            t = 1;
        }
        i.insertOne(t, side);
    }
}
开发者ID:mohamedkhairyhassan,项目名称:OsmAnd-external-skia,代码行数:15,代码来源:QuadraticImplicit.cpp

示例15: hackToFixPartialCoincidence

static void hackToFixPartialCoincidence(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
    // look to see if non-coincident data basically has unsortable tangents

    // look to see if a point between non-coincident data is on the curve
    int cIndex;
    for (int uIndex = 0; uIndex < i.fUsed; ) {
        double bestDist1 = 1;
        double bestDist2 = 1;
        int closest1 = -1;
        int closest2 = -1;
        for (cIndex = 0; cIndex < i.fCoincidentUsed; ++cIndex) {
            double dist = fabs(i.fT[0][uIndex] - i.fCoincidentT[0][cIndex]);
            if (bestDist1 > dist) {
                bestDist1 = dist;
                closest1 = cIndex;
            }
            dist = fabs(i.fT[1][uIndex] - i.fCoincidentT[1][cIndex]);
            if (bestDist2 > dist) {
                bestDist2 = dist;
                closest2 = cIndex;
            }
        }
        _Line ends;
        _Point mid;
        double t1 = i.fT[0][uIndex];
        xy_at_t(q1, t1, ends[0].x, ends[0].y);
        xy_at_t(q1, i.fCoincidentT[0][closest1], ends[1].x, ends[1].y);
        double midT = (t1 + i.fCoincidentT[0][closest1]) / 2;
        xy_at_t(q1, midT, mid.x, mid.y);
        LineParameters params;
        params.lineEndPoints(ends);
        double midDist = params.pointDistance(mid);
        // Note that we prefer to always measure t error, which does not scale,
        // instead of point error, which is scale dependent. FIXME
        if (!approximately_zero(midDist)) {
            ++uIndex;
            continue;
        }
        double t2 = i.fT[1][uIndex];
        xy_at_t(q2, t2, ends[0].x, ends[0].y);
        xy_at_t(q2, i.fCoincidentT[1][closest2], ends[1].x, ends[1].y);
        midT = (t2 + i.fCoincidentT[1][closest2]) / 2;
        xy_at_t(q2, midT, mid.x, mid.y);
        params.lineEndPoints(ends);
        midDist = params.pointDistance(mid);
        if (!approximately_zero(midDist)) {
            ++uIndex;
            continue;
        }
        // if both midpoints are close to the line, lengthen coincident span
        int cEnd = closest1 ^ 1; // assume coincidence always travels in pairs
        if (!between(i.fCoincidentT[0][cEnd], t1, i.fCoincidentT[0][closest1])) {
            i.fCoincidentT[0][closest1] = t1;
        }
        cEnd = closest2 ^ 1;
        if (!between(i.fCoincidentT[0][cEnd], t2, i.fCoincidentT[0][closest2])) {
            i.fCoincidentT[0][closest2] = t2;
        }
        int remaining = --i.fUsed - uIndex;
        if (remaining > 0) {
            memmove(&i.fT[0][uIndex], &i.fT[0][uIndex + 1], sizeof(i.fT[0][0]) * remaining);
            memmove(&i.fT[1][uIndex], &i.fT[1][uIndex + 1], sizeof(i.fT[1][0]) * remaining);
        }
    }
    // if coincident data is subjectively a tiny span, replace it with a single point
    for (cIndex = 0; cIndex < i.fCoincidentUsed; ) {
        double start1 = i.fCoincidentT[0][cIndex];
        double end1 = i.fCoincidentT[0][cIndex + 1];
        _Line ends1;
        xy_at_t(q1, start1, ends1[0].x, ends1[0].y);
        xy_at_t(q1, end1, ends1[1].x, ends1[1].y);
        if (!AlmostEqualUlps(ends1[0].x, ends1[1].x) || AlmostEqualUlps(ends1[0].y, ends1[1].y)) {
            cIndex += 2;
            continue;
        }
        double start2 = i.fCoincidentT[1][cIndex];
        double end2 = i.fCoincidentT[1][cIndex + 1];
        _Line ends2;
        xy_at_t(q2, start2, ends2[0].x, ends2[0].y);
        xy_at_t(q2, end2, ends2[1].x, ends2[1].y);
        // again, approximately should be used with T values, not points FIXME
        if (!AlmostEqualUlps(ends2[0].x, ends2[1].x) || AlmostEqualUlps(ends2[0].y, ends2[1].y)) {
            cIndex += 2;
            continue;
        }
        if (approximately_less_than_zero(start1) || approximately_less_than_zero(end1)) {
            start1 = 0;
        } else if (approximately_greater_than_one(start1) || approximately_greater_than_one(end1)) {
            start1 = 1;
        } else {
            start1 = (start1 + end1) / 2;
        }
        if (approximately_less_than_zero(start2) || approximately_less_than_zero(end2)) {
            start2 = 0;
        } else if (approximately_greater_than_one(start2) || approximately_greater_than_one(end2)) {
            start2 = 1;
        } else {
            start2 = (start2 + end2) / 2;
        }
        i.insert(start1, start2);
//.........这里部分代码省略.........
开发者ID:Cue,项目名称:skia,代码行数:101,代码来源:QuadraticIntersection.cpp


注:本文中的Intersections类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。