float mgnear::quadSplinesHit(int n, const Point2d* knots, bool closed, const Point2d& pt, float tol, Point2d& nearpt, int& segment) { Point2d ptTemp; float dist, distMin = _FLT_MAX; Point2d pts[3 + 4]; const Box2d rect (pt, 2 * tol, 2 * tol); segment = -1; for (int i = 0; i < (closed ? n : n - 2); i++, pts[0] = pts[2]) { if (i == 0) { pts[0] = closed ? (knots[0] + knots[1]) / 2 : knots[0]; } pts[1] = knots[(i+1) % n]; if (closed || i + 3 < n) pts[2] = (knots[(i+1) % n] + knots[(i+2) % n]) / 2; else pts[2] = knots[i+2]; mgcurv::quadBezierToCubic(pts, pts + 3); if (rect.isIntersect(computeCubicBox(pts + 3))) { dist = mgnear::nearestOnBezier(pt, pts + 3, ptTemp); if (dist < distMin) { distMin = dist; nearpt = ptTemp; segment = i; } } } return distMin; }
void NormalFilter::render(const ITextureObject& texture, const ICamera<float>& renderedCamera) { const Box2d<float> box(Vector2d<float>(-1.0, -1.0), Vector2d<float>(1.0, 1.0)); const auto& positions = box.toArray(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); //glDisable(GL_DEPTH_TEST); glUseProgram(shader.getId()); texture.bind(); //glGetUniformLocation( texture.getId() glUniform1i(shader.getUniformLocation("depthTex"), texture.getId()); glUniform1f(shader.getUniformLocation("texelSizeW"), 1.0f / static_cast<float>(texture.getWidth())); glUniform1f(shader.getUniformLocation("texelSizeH"), 1.0f / static_cast<float>(texture.getHeight())); glUniformMatrix4fv(shader.getUniformLocation("projectionMatrix"), 1, GL_FALSE, renderedCamera.getProjectionMatrix().toArray().data()); glVertexAttribPointer(shader.getAttribLocation("positions"), 2, GL_FLOAT, GL_FALSE, 0, positions.data()); glEnableVertexAttribArray(0); glDrawArrays(GL_QUADS, 0, static_cast<GLsizei>( positions.size() / 2) ); glDisableVertexAttribArray(0); glBindFragDataLocation(shader.getId(), 0, "fragColor"); texture.unbind(); glDisable(GL_DEPTH_TEST); glUseProgram(0); }
bool GiGraphics::setClipBox(const RECT_2D& rc) { if (m_impl->drawRefcnt < 1) return false; bool ret = false; Box2d rect; if (!rect.intersectWith(Box2d(rc), Box2d(m_impl->clipBox0)).isEmpty()) { if (rect != Box2d(m_impl->clipBox)) { rect.get(m_impl->clipBox); m_impl->rectDraw.set(Box2d(rc)); m_impl->rectDraw.inflate(GiGraphicsImpl::CLIP_INFLATE); m_impl->rectDrawM = m_impl->rectDraw * xf().displayToModel(); m_impl->rectDrawW = m_impl->rectDrawM * xf().modelToWorld(); SafeCall(m_impl->canvas, clipRect(m_impl->clipBox.left, m_impl->clipBox.top, m_impl->clipBox.width(), m_impl->clipBox.height())); } ret = true; } return ret; }
float mgnear::cubicSplinesHit( int n, const Point2d* knots, const Vector2d* knotvs, bool closed, const Point2d& pt, float tol, Point2d& nearpt, int& segment, bool hermite) { Point2d ptTemp; float dist, distMin = _FLT_MAX; Point2d pts[4]; const Box2d rect (pt, 2 * tol, 2 * tol); int n2 = (closed && n > 1) ? n + 1 : n; segment = -1; for (int i = 0; i + 1 < n2; i++) { mgcurv::cubicSplineToBezier(n, knots, knotvs, i, pts, hermite); if (rect.isIntersect(computeCubicBox(pts))) { dist = mgnear::nearestOnBezier(pt, pts, ptTemp); if (dist < distMin) { distMin = dist; nearpt = ptTemp; segment = i; } } } return distMin; }
bool GiGraphics::setClipWorld(const Box2d& rectWorld) { bool ret = false; if (isDrawing() && !rectWorld.isEmpty()) { Box2d box (rectWorld * xf().worldToDisplay()); box.intersectWith(Box2d(m_impl->clipBox0)); if (!box.isEmpty(Tol(1, 0))) { if (box != Box2d(m_impl->clipBox)) { box.get(m_impl->clipBox); m_impl->rectDraw = box; m_impl->rectDraw.inflate(GiGraphicsImpl::CLIP_INFLATE); m_impl->rectDrawM = m_impl->rectDraw * xf().displayToModel(); m_impl->rectDrawW = m_impl->rectDrawM * xf().modelToWorld(); SafeCall(m_impl->canvas, _clipBoxChanged(m_impl->clipBox)); } ret = true; } } return ret; }
float MgEllipse::_hitTest(const Point2d& pt, float tol, MgHitResult& res) const { if (isCircle()) { Point2d pt1(getCenter()), pt2(pt); crossCircle(pt1, pt2, this); float d1 = pt.distanceTo(pt1); float d2 = pt.distanceTo(pt2); res.nearpt = d1 < d2 ? pt1 : pt2; return mgMin(d1, d2); } float distMin = _FLT_MAX; const Box2d rect (pt, 2 * tol, 2 * tol); Point2d ptTemp; for (int i = 0; i < 4; i++) { if (rect.isIntersect(Box2d(4, _bzpts + 3 * i))) { mgnear::nearestOnBezier(pt, _bzpts + 3 * i, ptTemp); float dist = pt.distanceTo(ptTemp); if (dist <= tol && dist < distMin) { distMin = dist; res.nearpt = ptTemp; res.segment = i; } } } return distMin; }
float MgEllipse::_hitTest(const Point2d& pt, float tol, Point2d& nearpt, int& segment) const { float distMin = _FLT_MAX; const Box2d rect (pt, 2 * tol, 2 * tol); Point2d ptTemp; segment = -1; for (int i = 0; i < 4; i++) { if (rect.isIntersect(Box2d(4, _bzpts + 3 * i))) { mgNearestOnBezier(pt, _bzpts + 3 * i, ptTemp); float dist = pt.distanceTo(ptTemp); if (dist <= tol && dist < distMin) { distMin = dist; nearpt = ptTemp; segment = i; } } } return distMin; }
void OnScreenRenderer::render(const ITextureObject& texture) { const Box2d<float> box(Vector2d<float>(-1.0, -1.0), Vector2d<float>(1.0, 1.0)); const auto& positions = box.toArray(); //glEnable(GL_DEPTH_TEST); glUseProgram(shader.getId()); texture.bind(); glUniform1i(shader.getUniformLocation("texture"), texture.getId()); glVertexAttribPointer(shader.getAttribLocation("positions"), 2, GL_FLOAT, GL_FALSE, 0, positions.data()); glEnableVertexAttribArray(0); glDrawArrays(GL_QUADS, 0, static_cast<GLsizei>( positions.size() / 2) ); glDisableVertexAttribArray(0); glBindFragDataLocation(shader.getId(), 0, "fragColor"); texture.unbind(); //glDisable(GL_DEPTH_TEST); glUseProgram(0); }
inline Pt2dr PQ2(const Box2d<Type> & b,INT c1,INT c2) { return Pt2dr ( b.x(TAB_IND_Q2X[c1][c2]), b.y(TAB_IND_Q2Y[c1][c2]) ); }
bool mglnrel::clipLine(Point2d& pt1, Point2d& pt2, const Box2d& _box) { Box2d box (_box); box.normalize(); unsigned code1, code2; code1 = ClipCode(pt1, box); code2 = ClipCode(pt2, box); for ( ; ; ) { if (!(code1 | code2)) // 完全在矩形内 return true; if (code1 & code2) // 完全在矩形外 return false; float x = 0.f, y = 0.f; unsigned code; if (code1) // 起点不在矩形内 code = code1; else // 终点不在矩形内 code = code2; if (code & 0x1000) // 上 { x = pt1.x + (pt2.x - pt1.x) * (box.ymax - pt1.y) / (pt2.y - pt1.y); y = box.ymax; } else if (code & 0x0100) // 下 { x = pt1.x + (pt2.x - pt1.x) * (box.ymin - pt1.y) / (pt2.y - pt1.y); y = box.ymin; } else if (code & 0x0001) // 左 { y = pt1.y + (pt2.y - pt1.y) * (box.xmin - pt1.x) / (pt2.x - pt1.x); x = box.xmin; } else if (code & 0x0010) // 右 { y = pt1.y + (pt2.y - pt1.y) * (box.xmax - pt1.x) / (pt2.x - pt1.x); x = box.xmax; } if (code == code1) { pt1.x = x; pt1.y = y; code1 = ClipCode(pt1, box); } else { pt2.x = x; pt2.y = y; code2 = ClipCode(pt2, box); } } }
bool GiGraphics::drawRect(const GiContext* ctx, const Box2d& rect, bool modelUnit) { Point2d points[4] = { rect.leftBottom(), rect.rightBottom(), rect.rightTop(), rect.leftTop() }; return drawPolygon(ctx, 4, points, modelUnit); }
void CScrollShapeView::OnZoomed() { CRandomShapeView::OnZoomed(); Box2d rect; // m_rcLimits: 极限范围对应的坐标范围, 像素 rect = m_shapes->getExtent() * m_graph->xf.modelToDisplay(); rect.inflate(1, 1); rect.get(m_rcLimits); // m_rcScrWnd: 当前窗口对应的坐标范围, 像素 rect = Box2d(m_graph->xf.getCenterW(), m_graph->xf.getWidth() / m_graph->xf.getWorldToDisplayX(), m_graph->xf.getHeight() / m_graph->xf.getWorldToDisplayY()); rect *= m_graph->xf.worldToDisplay(); rect.get(m_rcScrWnd); // 以m_rcLimits左上角为原点调整m_rcScrWnd和m_rcLimits ::OffsetRect(&m_rcScrWnd, -m_rcLimits.left, -m_rcLimits.top); ::OffsetRect(&m_rcLimits, -m_rcLimits.left, -m_rcLimits.top); // 避免m_rcScrWnd部分超出m_rcLimits ::UnionRect(&m_rcLimits, &m_rcLimits, &m_rcScrWnd); SCROLLINFO si; si.cbSize = sizeof(si); si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; si.nMin = 0; if (m_rcLimits.right - m_rcLimits.left > m_rcScrWnd.right - m_rcScrWnd.left) { si.nMax = max(1, m_rcLimits.right - m_rcLimits.left); si.nPage = m_rcScrWnd.right - m_rcScrWnd.left; si.nPos = m_rcScrWnd.left; ::EnableScrollBar(m_hWnd, SB_HORZ, ESB_ENABLE_BOTH); ::SetScrollInfo(m_hWnd, SB_HORZ, &si, TRUE); } else { ::EnableScrollBar(m_hWnd, SB_HORZ, ESB_DISABLE_BOTH); } if (m_rcLimits.bottom - m_rcLimits.top > m_rcScrWnd.bottom - m_rcScrWnd.top) { si.nMax = max(1, m_rcLimits.bottom - m_rcLimits.top); si.nPage = m_rcScrWnd.bottom - m_rcScrWnd.top; si.nPos = m_rcScrWnd.top; ::EnableScrollBar(m_hWnd, SB_VERT, ESB_ENABLE_BOTH); ::SetScrollInfo(m_hWnd, SB_VERT, &si, TRUE); } else { ::EnableScrollBar(m_hWnd, SB_VERT, ESB_DISABLE_BOTH); } }
Box2d MgShapeDoc::getExtent() const { Box2d rect; for (unsigned i = 0; i < im->layers.size(); i++) { rect.unionWith(im->layers[i]->getExtent()); } return rect; }
bool GiGraphics::drawRoundRect(const GiContext* ctx, const Box2d& rect, float rx, float ry, bool modelUnit) { if (m_impl->drawRefcnt == 0 || rect.isEmpty()) return false; GiLock lock (&m_impl->drawRefcnt); bool ret = false; if (ry < _MGZERO) ry = rx; if (!DRAW_RECT(m_impl, modelUnit).isIntersect(rect)) // 全部在显示区域外 return false; if (rx < _MGZERO) { Point2d points[4] = { rect.leftBottom(), rect.rightBottom(), rect.rightTop(), rect.leftTop() }; return drawPolygon(ctx, 4, points); } else { Point2d points[16]; mgRoundRectToBeziers(points, rect, rx, ry); S2D(xf(), modelUnit).TransformPoints(16, points); ret = rawBeginPath(); if (ret) { ret = rawMoveTo(points[0].x, points[0].y); ret = rawBezierTo(&points[1], 3); ret = rawLineTo(points[4].x, points[4].y); ret = rawBezierTo(&points[5], 3); ret = rawLineTo(points[8].x, points[8].y); ret = rawBezierTo(&points[9], 3); ret = rawLineTo(points[12].x, points[12].y); ret = rawBezierTo(&points[13], 3); ret = rawClosePath(); ret = rawEndPath(ctx, true); } } return ret; }
void MgCmdManagerImpl::getBoundingBox(Box2d& box, const MgMotion* sender) { MgCommand* cmd = sender->cmds()->getCommand(); Box2d selbox; if (cmd && strcmp(cmd->getName(), MgCmdSelect::Name()) == 0) { MgCmdSelect* sel = (MgCmdSelect*)cmd; selbox = sel->getBoundingBox(sender); } box = selbox.isEmpty() ? Box2d(sender->pointM, 0, 0) : selbox; box *= sender->view->xform()->modelToDisplay(); box.normalize(); }
void mgnear::beziersBox( Box2d& box, int count, const Point2d* points, bool closed) { box.empty(); for (int i = 0; i + 3 < count; i += 3) { box.unionWith(computeCubicBox(points + i)); } if (closed && count > 3) { box.unionWith(computeCubicBox(points[count - 1], points[count - 1] * 2 - points[count - 2].asVector(), points[0] * 2 - points[1].asVector(), points[0])); } }
void MgBaseRect::setRect(const Box2d& rect, float angle) { _points[0] = rect.leftTop(); _points[1] = rect.rightTop(); _points[2] = rect.rightBottom(); _points[3] = rect.leftBottom(); if (!mgIsZero(angle)) { Matrix2d mat(Matrix2d::rotation(angle, rect.center())); for (int i = 0; i < 4; i++) _points[i] *= mat; } }
float mgnear::linesHit( int n, const Point2d* points, bool closed, const Point2d& pt, float tol, Point2d& nearpt, int& segment, bool* inside, int* hitType) { Point2d ptTemp; float dist, distMin = _FLT_MAX; const Box2d rect (pt, 2 * tol, 2 * tol); int n2 = (closed && n > 1) ? n + 1 : n; int type = mglnrel::ptInArea(pt, n, points, segment, Tol(tol), closed); if (inside) { *inside = (closed && type == mglnrel::kPtInArea); } if (hitType) { *hitType = type; } if (type == mglnrel::kPtAtVertex) { nearpt = points[segment]; distMin = nearpt.distanceTo(pt); return distMin; } if (type == mglnrel::kPtOnEdge) { distMin = mglnrel::ptToLine(points[segment], points[(segment+1)%n], pt, nearpt); return distMin; } if (!closed || type != mglnrel::kPtInArea) { return distMin; } for (int i = 0; i + 1 < n2; i++) { const Point2d& pt2 = points[(i + 1) % n]; if (closed || rect.isIntersect(Box2d(points[i], pt2))) { dist = mglnrel::ptToLine(points[i], pt2, pt, ptTemp); if (distMin > 1e10f || (dist <= tol && dist < distMin)) { distMin = dist; nearpt = ptTemp; if (dist <= tol) segment = i; } } } return distMin; }
bool showContextActions(int /*selState*/, const int* actions, const Box2d& selbox, const MgShape*) { int n = 0; for (; actions && actions[n] > 0; n++) {} if (n > 0 && motion.pressDrag && isContextActionsVisible()) { return false; } mgvector<int> arr(actions, n); mgvector<float> pos(2 * n); calcContextButtonPosition(pos, n, selbox); return CALL_VIEW2(deviceView()->showContextActions(arr, pos, selbox.xmin, selbox.ymin, selbox.width(), selbox.height()), false); }
static void _RoundRectHit( const Box2d& rect, float rx, float ry, const Point2d& pt, float tol, const Box2d &rectTol, Point2d* pts, float& distMin, Point2d& nearpt, int& segment) { Point2d ptsBezier[13], ptTemp; Vector2d vec; float dx = rect.width() * 0.5f - rx; float dy = rect.height() * 0.5f - ry; // 按逆时针方向从第一象限到第四象限连接的四段 mgcurv::ellipseToBezier(ptsBezier, rect.center(), rx, ry); pts[3] = ptsBezier[0]; for (int i = 0; i < 4; i++) { pts[0] = pts[3]; pts[1] = ptsBezier[3 * i]; pts[2] = ptsBezier[3 * i + 1]; pts[3] = ptsBezier[3 * i + 2]; switch (i) { case 0: vec.set(dx, dy); break; case 1: vec.set(-dx, dy); break; case 2: vec.set(-dx, -dy); break; case 3: vec.set(dx, -dy); break; } for (int j = 0; j < 4; j++) pts[j] += vec; if (rectTol.isIntersect(Box2d(4, pts))) { mgnear::nearestOnBezier(pt, pts, ptTemp); float dist = pt.distanceTo(ptTemp); if (dist <= tol && dist < distMin) { distMin = dist; nearpt = ptTemp; segment = (5 - i) % 4; } } pts[3] -= vec; } }
Box2d GiTransform::setWorldLimits(const Box2d& rect) { Box2d ret = m_impl->rectLimitsW; m_impl->rectLimitsW = rect.isEmpty() ? Box2d(Point2d::kOrigin(), 2e5f, 2e5f) : rect; m_impl->rectLimitsW.normalize(); return ret; }
void mgnear::cubicSplinesBox( Box2d& box, int n, const Point2d* knots, const Vector2d* knotvs, bool closed, bool hermite) { int n2 = (closed && n > 1) ? n + 1 : n; float d = hermite ? 1.f/3.f : 1.f; box.empty(); for (int i = 0; i + 1 < n2; i++) { box.unionWith(computeCubicBox(knots[i], knots[i] + knotvs[i] * d, knots[(i + 1) % n] - knotvs[(i + 1) % n] * d, knots[(i + 1) % n])); } }
bool GiGraphics::drawRoundRect(const GiContext* ctx, const Box2d& rect, float rx, float ry, bool modelUnit) { if (rect.isEmpty() || isStopping()) return false; bool ret = false; if (ry < _MGZERO) ry = rx; if (!DRAW_RECT(m_impl, modelUnit).isIntersect(rect)) // 全部在显示区域外 return false; if (rx < _MGZERO) { Point2d points[4] = { rect.leftBottom(), rect.rightBottom(), rect.rightTop(), rect.leftTop() }; return drawPolygon(ctx, 4, points); } else { Point2d pxs[16]; mgcurv::roundRectToBeziers(pxs, rect, rx, ry); S2D(xf(), modelUnit).transformPoints(16, pxs); ret = rawBeginPath(); if (ret) { rawMoveTo(pxs[0].x, pxs[0].y); rawBezierTo(pxs[1].x, pxs[1].y, pxs[2].x, pxs[2].y, pxs[3].x, pxs[3].y); rawLineTo(pxs[4].x, pxs[4].y); rawBezierTo(pxs[5].x, pxs[5].y, pxs[6].x, pxs[6].y, pxs[7].x, pxs[7].y); rawLineTo(pxs[8].x, pxs[8].y); rawBezierTo(pxs[9].x, pxs[9].y, pxs[10].x, pxs[10].y, pxs[11].x, pxs[11].y); rawLineTo(pxs[12].x, pxs[12].y); rawBezierTo(pxs[13].x, pxs[13].y, pxs[14].x, pxs[14].y, pxs[15].x, pxs[15].y); rawClosePath(); ret = rawEndPath(ctx, true); } } return ret; }
static void AdjustCenterW(Point2d &ptW, float halfw, float halfh, const Box2d& rectW) { if (ptW.x - halfw < rectW.xmin) ptW.x += rectW.xmin - (ptW.x - halfw); if (ptW.x + halfw > rectW.xmax) ptW.x += rectW.xmax - (ptW.x + halfw); if (2 * halfw >= rectW.width()) ptW.x = rectW.center().x; if (ptW.y - halfh < rectW.ymin) ptW.y += rectW.ymin - (ptW.y - halfh); if (ptW.y + halfh > rectW.ymax) ptW.y += rectW.ymax - (ptW.y + halfh); if (2 * halfh >= rectW.height()) ptW.y = rectW.center().y; }
void mgcurv::roundRectToBeziers( Point2d points[16], const Box2d& rect, float rx, float ry) { if (2 * rx > rect.width()) rx = rect.width() / 2; if (2 * ry > rect.height()) ry = rect.height() / 2; int i, j; float dx = rect.width() / 2 - rx; float dy = rect.height() / 2 - ry; mgcurv::ellipseToBezier(points, rect.center(), rx, ry); for (i = 3; i >= 1; i--) { for (j = 3; j >= 0; j--) points[4 * i + j] = points[3 * i + j]; } for (i = 0; i < 4; i++) { float dx1 = (0 == i || 3 == i) ? dx : -dx; float dy1 = (0 == i || 1 == i) ? dy : -dy; for (j = 0; j < 4; j++) points[4 * i + j].offset(dx1, dy1); } }
void SplineGeometry::GetBoundingBox(Box2d& box) const { if (!splines.size()) { Point2d auxp{0.0, 0.0}; box.SetPoint(auxp); return; } std::vector<Point2d> points; for (size_t i = 0; i < splines.size(); i++) { splines[i]->GetPoints(20, points); if (i == 0) box.SetPoint(points[0]); for (size_t j = 0; j < points.size(); j++) { box.AddPoint(points[j]); } } }
bool GiCanvasGdipImpl::drawImage(G::Bitmap* pBmp, const Box2d& rectW, bool fast) { RECT_2D rc, rcDraw, rcFrom; Box2d rect; float width = (float)pBmp->GetWidth(); float height = (float)pBmp->GetHeight(); // rc: 整个图像对应的显示坐标区域 (rectW * gs()->xf().worldToDisplay()).get(rc); // rcDraw: 图像经剪裁后的可显示部分 gs()->getClipBox(rcDraw); if (rect.intersectWith(Box2d(rc), Box2d(rcDraw)).isEmpty()) return false; rect.get(rcDraw); // rcFrom: rcDraw在原始图像上对应的图像范围 rcFrom.left = (rcDraw.left - rc.left) * width / (rc.right - rc.left); rcFrom.top = (rcDraw.top - rc.top) * height / (rc.bottom - rc.top); rcFrom.right = (rcDraw.right - rc.left) * width / (rc.right - rc.left); rcFrom.bottom = (rcDraw.bottom - rc.top) * height / (rc.bottom - rc.top); // 根据rectW正负决定是否颠倒显示图像 if (rectW.xmin > rectW.xmax) mgSwap(rcDraw.left, rcDraw.right); if (rectW.ymin > rectW.ymax) mgSwap(rcDraw.top, rcDraw.bottom); G::InterpolationMode nOldMode = getDrawGs()->GetInterpolationMode(); getDrawGs()->SetInterpolationMode( (!fast || gs()->isPrint()) ? G::InterpolationModeBilinear : G::InterpolationModeLowQuality); G::Status ret = getDrawGs()->DrawImage(pBmp, G::RectF(rcDraw.left, rcDraw.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top), rcFrom.left, rcFrom.top, rcFrom.right - rcFrom.left, rcFrom.bottom - rcFrom.top, G::UnitPixel); getDrawGs()->SetInterpolationMode(nOldMode); return G::Ok == ret; }
void mgnear::getRectHandle(const Box2d& rect, int index, Point2d& pt) { switch (index) { case 0: pt = rect.leftTop(); break; case 1: pt = rect.rightTop(); break; case 2: pt = rect.rightBottom(); break; case 3: pt = rect.leftBottom(); break; case 4: pt = Point2d(rect.center().x, rect.ymax); break; case 5: pt = Point2d(rect.xmax, rect.center().y); break; case 6: pt = Point2d(rect.center().x, rect.ymin); break; case 7: pt = Point2d(rect.xmin, rect.center().y); break; default: pt = rect.center(); break; } }
bool MgArc::_hitTestBox(const Box2d& rect) const { if (!getExtent().isIntersect(rect)) return false; Point2d points[16]; int n = mgcurv::arcToBezier(points, getCenter(), getRadius(), 0, getStartAngle(), getSweepAngle()); return rect.contains(getCenter()) || mgnear::beziersIntersectBox(rect, n, points); }
GiTransformImpl(bool _ydown) : cxWnd(1), cyWnd(1), dpiX(96), dpiY(96), ydown(_ydown), viewScale(1) , zoomEnabled(true), tmpViewScale(1.f), zoomTimes(0) { minViewScale = 0.01f; // 最小显示比例为1% maxViewScale = 5.f; // 最大显示比例为500% rectLimitsW.set(Point2d::kOrigin(), 2e5f, 2e5f); updateTransforms(); }