brcain
3rd November 2014, 22:58
I’m hoping someone might shed some light as to why I’m having a problem with QPainterPath::arcTo() used to draw the inner pie boundary in the image below.
The inner and outer arcs have the same start angle and sweep length, but they don't render that way. Why?
10722
The pie shapes are drawn with:
QPainterPath::arcTo(const QRectF & rectangle, qreal startAngle, qreal sweepLength)
The method is giving unexpected results with the startAngle and sweepLength.
Looking at the image, I expect the inner arc to begin (and end) coincident with the outer arc, but it doesn’t. The center, startAngle, and sweepLength are the same for both.
Note, I computed the desired arc start/end point (shown in the red circle as a yellow square).
void GraphicsPieFramed::createPaths()
{
// Clear the paths.
mOutlinePath = QPainterPath();
mFacePath = QPainterPath();
mMaxelSize = SCENE_SCALE*maxelDiameter(printHeadDiameter(), mVoltage);
double span = -normAngle360(mAngleEnd-mAngleBegin);
mOutlinePath.addRect(-0.5*mSize.width(), -0.5*mSize.height(), mSize.width(), mSize.height());
// outer pie
QPainterPath outerPie;
outerPie.moveTo(QPointF(0.0, 0.0));
outerPie.arcTo(QRectF(-0.5*mSize.width(), -0.5*mSize.height(), mSize.width(), mSize.height()),
-mAngleBegin, span);
outerPie.closeSubpath();
mFacePath.addPath(outerPie);
// inner pie
QPainterPath innerPie;
innerPie.moveTo(QPointF(0.0, 0.0));
innerPie.arcTo(QRectF(-0.5*mSize.width()+mFrameWidth, -0.5*mSize.height()+mFrameHeight,
mSize.width()-2.0*mFrameWidth, mSize.height()-2.0*mFrameHeight),
-mAngleBegin, span);
innerPie.closeSubpath();
mFacePath.addPath(innerPie);
if(mFrameEnabled && mFrameWidth < 0.5*mSize.width() && mFrameHeight < 0.5*mSize.height())
{
mFacePath.addPath(innerPie);
}
mFacePath.addEllipse(QPointF(0.0, 0.0), 3.0, 3.0); // Center location
createMaxelPaths();
createResizeHandlePaths();
createRotateHandlePath();
}
void GraphicsPieFramed::createResizeHandlePaths()
{
// Clear the paths.
mResizeLeftPath = QPainterPath();
mResizeRightPath = QPainterPath();
mResizeBottomPath = QPainterPath();
mResizeTopPath = QPainterPath();
mResizeBottomLeftPath = QPainterPath();
mResizeBottomRightPath = QPainterPath();
mResizeTopLeftPath = QPainterPath();
mResizeTopRightPath = QPainterPath();
mResizeAngleBeginPath = QPainterPath();
mResizeAngleEndPath = QPainterPath();
mResizeFrameWidthPath = QPainterPath();
mResizeFrameHeightPath = QPainterPath();
double const sizeHandleHalf(0.5*SIZE_HANDLE);
double const sizeHandleHalfDiag(sizeHandleHalf*sqrt(2.0));
double const left(-0.5*mSize.width());
double const right(0.5*mSize.width());
double const bottom(-0.5*mSize.height());
double const top(0.5*mSize.height());
// left
mResizeLeftPath.addRect(left-sizeHandleHalf, -sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// right
mResizeRightPath.addRect(right-sizeHandleHalf, -sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// bottom
mResizeBottomPath.addRect(-sizeHandleHalf, bottom-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// top
mResizeTopPath.addRect(-sizeHandleHalf, top-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// bottom-left
mResizeBottomLeftPath.addRect(left-sizeHandleHalf, bottom-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// bottom-right
mResizeBottomRightPath.addRect(right-sizeHandleHalf, bottom-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// top-left
mResizeTopLeftPath.addRect(left-sizeHandleHalf, top-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// top-right
mResizeTopRightPath.addRect(right-sizeHandleHalf, top-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// begin angle
double xBegin = 0.5*mSize.width()*cos(DEG2RAD*mAngleBegin);
double yBegin = 0.5*mSize.height()*sin(DEG2RAD*mAngleBegin);
mResizeAngleBeginPath.addEllipse(xBegin-sizeHandleHalfDiag, yBegin-sizeHandleHalfDiag,
2.0*sizeHandleHalfDiag, 2.0*sizeHandleHalfDiag);
// begin angle inner frame
double lenBegin = sqrt(xBegin*xBegin + yBegin*yBegin);
double xBeginPart = mFrameWidth*cos(DEG2RAD*mAngleBegin);
double yBeginPart = mFrameHeight*sin(DEG2RAD*mAngleBegin);
double lenBeginPart = sqrt(xBeginPart*xBeginPart + yBeginPart*yBeginPart);
double x2Begin = interp(xBegin, 0.0, lenBeginPart/lenBegin);
double y2Begin = interp(yBegin, 0.0, lenBeginPart/lenBegin);
mResizeAngleBeginPath.addRect(x2Begin-sizeHandleHalf, y2Begin-sizeHandleHalf, 2.0*sizeHandleHalf, 2.0*sizeHandleHalf);
// end angle
double xEnd = 0.5*mSize.width()*cos(DEG2RAD*mAngleEnd);
double yEnd = 0.5*mSize.height()*sin(DEG2RAD*mAngleEnd);
mResizeAngleEndPath.addEllipse(xEnd-sizeHandleHalfDiag, yEnd-sizeHandleHalfDiag,
2.0*sizeHandleHalfDiag, 2.0*sizeHandleHalfDiag);
// end angle inner frame
double lenEnd = sqrt(xEnd*xEnd + yEnd*yEnd);
double xEndPart = mFrameWidth*cos(DEG2RAD*mAngleEnd);
double yEndPart = mFrameHeight*sin(DEG2RAD*mAngleEnd);
double lenEndPart = sqrt(xEndPart*xEndPart + yEndPart*yEndPart);
double x2End = interp(xEnd, 0.0, lenEndPart/lenEnd);
double y2End = interp(yEnd, 0.0, lenEndPart/lenEnd);
mResizeAngleEndPath.addRect(x2End-sizeHandleHalf, y2End-sizeHandleHalf, 2.0*sizeHandleHalf, 2.0*sizeHandleHalf);
// frame width
mResizeFrameWidthPath.addEllipse(left-sizeHandleHalfDiag+mFrameWidth, top-sizeHandleHalfDiag,
2.0*sizeHandleHalfDiag, 2.0*sizeHandleHalfDiag);
// frame height
mResizeFrameHeightPath.addEllipse(left-sizeHandleHalfDiag, top-sizeHandleHalfDiag-mFrameHeight,
2.0*sizeHandleHalfDiag, 2.0*sizeHandleHalfDiag);
}
Thanks!
The inner and outer arcs have the same start angle and sweep length, but they don't render that way. Why?
10722
The pie shapes are drawn with:
QPainterPath::arcTo(const QRectF & rectangle, qreal startAngle, qreal sweepLength)
The method is giving unexpected results with the startAngle and sweepLength.
Looking at the image, I expect the inner arc to begin (and end) coincident with the outer arc, but it doesn’t. The center, startAngle, and sweepLength are the same for both.
Note, I computed the desired arc start/end point (shown in the red circle as a yellow square).
void GraphicsPieFramed::createPaths()
{
// Clear the paths.
mOutlinePath = QPainterPath();
mFacePath = QPainterPath();
mMaxelSize = SCENE_SCALE*maxelDiameter(printHeadDiameter(), mVoltage);
double span = -normAngle360(mAngleEnd-mAngleBegin);
mOutlinePath.addRect(-0.5*mSize.width(), -0.5*mSize.height(), mSize.width(), mSize.height());
// outer pie
QPainterPath outerPie;
outerPie.moveTo(QPointF(0.0, 0.0));
outerPie.arcTo(QRectF(-0.5*mSize.width(), -0.5*mSize.height(), mSize.width(), mSize.height()),
-mAngleBegin, span);
outerPie.closeSubpath();
mFacePath.addPath(outerPie);
// inner pie
QPainterPath innerPie;
innerPie.moveTo(QPointF(0.0, 0.0));
innerPie.arcTo(QRectF(-0.5*mSize.width()+mFrameWidth, -0.5*mSize.height()+mFrameHeight,
mSize.width()-2.0*mFrameWidth, mSize.height()-2.0*mFrameHeight),
-mAngleBegin, span);
innerPie.closeSubpath();
mFacePath.addPath(innerPie);
if(mFrameEnabled && mFrameWidth < 0.5*mSize.width() && mFrameHeight < 0.5*mSize.height())
{
mFacePath.addPath(innerPie);
}
mFacePath.addEllipse(QPointF(0.0, 0.0), 3.0, 3.0); // Center location
createMaxelPaths();
createResizeHandlePaths();
createRotateHandlePath();
}
void GraphicsPieFramed::createResizeHandlePaths()
{
// Clear the paths.
mResizeLeftPath = QPainterPath();
mResizeRightPath = QPainterPath();
mResizeBottomPath = QPainterPath();
mResizeTopPath = QPainterPath();
mResizeBottomLeftPath = QPainterPath();
mResizeBottomRightPath = QPainterPath();
mResizeTopLeftPath = QPainterPath();
mResizeTopRightPath = QPainterPath();
mResizeAngleBeginPath = QPainterPath();
mResizeAngleEndPath = QPainterPath();
mResizeFrameWidthPath = QPainterPath();
mResizeFrameHeightPath = QPainterPath();
double const sizeHandleHalf(0.5*SIZE_HANDLE);
double const sizeHandleHalfDiag(sizeHandleHalf*sqrt(2.0));
double const left(-0.5*mSize.width());
double const right(0.5*mSize.width());
double const bottom(-0.5*mSize.height());
double const top(0.5*mSize.height());
// left
mResizeLeftPath.addRect(left-sizeHandleHalf, -sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// right
mResizeRightPath.addRect(right-sizeHandleHalf, -sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// bottom
mResizeBottomPath.addRect(-sizeHandleHalf, bottom-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// top
mResizeTopPath.addRect(-sizeHandleHalf, top-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// bottom-left
mResizeBottomLeftPath.addRect(left-sizeHandleHalf, bottom-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// bottom-right
mResizeBottomRightPath.addRect(right-sizeHandleHalf, bottom-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// top-left
mResizeTopLeftPath.addRect(left-sizeHandleHalf, top-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// top-right
mResizeTopRightPath.addRect(right-sizeHandleHalf, top-sizeHandleHalf, SIZE_HANDLE, SIZE_HANDLE);
// begin angle
double xBegin = 0.5*mSize.width()*cos(DEG2RAD*mAngleBegin);
double yBegin = 0.5*mSize.height()*sin(DEG2RAD*mAngleBegin);
mResizeAngleBeginPath.addEllipse(xBegin-sizeHandleHalfDiag, yBegin-sizeHandleHalfDiag,
2.0*sizeHandleHalfDiag, 2.0*sizeHandleHalfDiag);
// begin angle inner frame
double lenBegin = sqrt(xBegin*xBegin + yBegin*yBegin);
double xBeginPart = mFrameWidth*cos(DEG2RAD*mAngleBegin);
double yBeginPart = mFrameHeight*sin(DEG2RAD*mAngleBegin);
double lenBeginPart = sqrt(xBeginPart*xBeginPart + yBeginPart*yBeginPart);
double x2Begin = interp(xBegin, 0.0, lenBeginPart/lenBegin);
double y2Begin = interp(yBegin, 0.0, lenBeginPart/lenBegin);
mResizeAngleBeginPath.addRect(x2Begin-sizeHandleHalf, y2Begin-sizeHandleHalf, 2.0*sizeHandleHalf, 2.0*sizeHandleHalf);
// end angle
double xEnd = 0.5*mSize.width()*cos(DEG2RAD*mAngleEnd);
double yEnd = 0.5*mSize.height()*sin(DEG2RAD*mAngleEnd);
mResizeAngleEndPath.addEllipse(xEnd-sizeHandleHalfDiag, yEnd-sizeHandleHalfDiag,
2.0*sizeHandleHalfDiag, 2.0*sizeHandleHalfDiag);
// end angle inner frame
double lenEnd = sqrt(xEnd*xEnd + yEnd*yEnd);
double xEndPart = mFrameWidth*cos(DEG2RAD*mAngleEnd);
double yEndPart = mFrameHeight*sin(DEG2RAD*mAngleEnd);
double lenEndPart = sqrt(xEndPart*xEndPart + yEndPart*yEndPart);
double x2End = interp(xEnd, 0.0, lenEndPart/lenEnd);
double y2End = interp(yEnd, 0.0, lenEndPart/lenEnd);
mResizeAngleEndPath.addRect(x2End-sizeHandleHalf, y2End-sizeHandleHalf, 2.0*sizeHandleHalf, 2.0*sizeHandleHalf);
// frame width
mResizeFrameWidthPath.addEllipse(left-sizeHandleHalfDiag+mFrameWidth, top-sizeHandleHalfDiag,
2.0*sizeHandleHalfDiag, 2.0*sizeHandleHalfDiag);
// frame height
mResizeFrameHeightPath.addEllipse(left-sizeHandleHalfDiag, top-sizeHandleHalfDiag-mFrameHeight,
2.0*sizeHandleHalfDiag, 2.0*sizeHandleHalfDiag);
}
Thanks!