parent
7f26289b50
commit
9c8a49f8c6
@ -1,225 +1,235 @@ |
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#ifndef UBSVGSUBSETADAPTOR_H_ |
||||
#define UBSVGSUBSETADAPTOR_H_ |
||||
|
||||
#include <QtGui> |
||||
#include <QtXml> |
||||
|
||||
#include "frameworks/UBGeometryUtils.h" |
||||
|
||||
class UBGraphicsSvgItem; |
||||
class UBGraphicsPolygonItem; |
||||
class UBGraphicsPixmapItem; |
||||
class UBGraphicsPDFItem; |
||||
class UBGraphicsWidgetItem; |
||||
class UBGraphicsVideoItem; |
||||
class UBGraphicsAudioItem; |
||||
class UBGraphicsAppleWidgetItem; |
||||
class UBGraphicsW3CWidgetItem; |
||||
class UBGraphicsTextItem; |
||||
class UBGraphicsCurtainItem; |
||||
class UBGraphicsRuler; |
||||
class UBGraphicsCompass; |
||||
class UBGraphicsProtractor; |
||||
class UBGraphicsScene; |
||||
class UBDocumentProxy; |
||||
class UBGraphicsStroke; |
||||
class UBPersistenceManager; |
||||
class UBGraphicsTriangle; |
||||
class UBGraphicsCache; |
||||
|
||||
class UBSvgSubsetAdaptor |
||||
{ |
||||
private: |
||||
|
||||
UBSvgSubsetAdaptor() {;} |
||||
virtual ~UBSvgSubsetAdaptor() {;} |
||||
|
||||
public: |
||||
|
||||
static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const int pageIndex); |
||||
static void persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex); |
||||
static void upgradeScene(UBDocumentProxy* proxy, const int pageIndex); |
||||
|
||||
static QUuid sceneUuid(UBDocumentProxy* proxy, const int pageIndex); |
||||
static void setSceneUuid(UBDocumentProxy* proxy, const int pageIndex, QUuid pUuid); |
||||
|
||||
static void convertPDFObjectsToImages(UBDocumentProxy* proxy); |
||||
static void convertSvgImagesToImages(UBDocumentProxy* proxy); |
||||
|
||||
static const QString nsSvg; |
||||
static const QString nsXLink; |
||||
static const QString nsXHtml; |
||||
static const QString nsUb; |
||||
static const QString xmlTrue; |
||||
static const QString xmlFalse; |
||||
|
||||
static const QString sFontSizePrefix; |
||||
static const QString sPixelUnit; |
||||
static const QString sFontWeightPrefix; |
||||
static const QString sFontStylePrefix; |
||||
|
||||
private: |
||||
|
||||
static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const QByteArray& pArray); |
||||
|
||||
static QDomDocument loadSceneDocument(UBDocumentProxy* proxy, const int pPageIndex); |
||||
|
||||
static QString uniboardDocumentNamespaceUriFromVersion(int fileVersion); |
||||
|
||||
static const QString sFormerUniboardDocumentNamespaceUri; |
||||
|
||||
static QString toSvgTransform(const QMatrix& matrix); |
||||
static QMatrix fromSvgTransform(const QString& transform); |
||||
|
||||
class UBSvgSubsetReader |
||||
{ |
||||
public: |
||||
|
||||
UBSvgSubsetReader(UBDocumentProxy* proxy, const QByteArray& pXmlData); |
||||
|
||||
virtual ~UBSvgSubsetReader(){} |
||||
|
||||
UBGraphicsScene* loadScene(); |
||||
|
||||
private: |
||||
|
||||
UBGraphicsPolygonItem* polygonItemFromLineSvg(const QColor& pDefaultBrushColor); |
||||
|
||||
UBGraphicsPolygonItem* polygonItemFromPolygonSvg(const QColor& pDefaultBrushColor); |
||||
|
||||
QList<UBGraphicsPolygonItem*> polygonItemsFromPolylineSvg(const QColor& pDefaultColor); |
||||
|
||||
UBGraphicsPixmapItem* pixmapItemFromSvg(); |
||||
|
||||
UBGraphicsSvgItem* svgItemFromSvg(); |
||||
|
||||
UBGraphicsPDFItem* pdfItemFromPDF(); |
||||
|
||||
UBGraphicsVideoItem* videoItemFromSvg(); |
||||
|
||||
UBGraphicsAudioItem* audioItemFromSvg(); |
||||
|
||||
UBGraphicsAppleWidgetItem* graphicsAppleWidgetFromSvg(); |
||||
|
||||
UBGraphicsW3CWidgetItem* graphicsW3CWidgetFromSvg(); |
||||
|
||||
UBGraphicsTextItem* textItemFromSvg(); |
||||
|
||||
UBGraphicsCurtainItem* curtainItemFromSvg(); |
||||
|
||||
UBGraphicsRuler* rulerFromSvg(); |
||||
|
||||
UBGraphicsCompass* compassFromSvg(); |
||||
|
||||
UBGraphicsProtractor* protractorFromSvg(); |
||||
|
||||
UBGraphicsTriangle* triangleFromSvg(); |
||||
|
||||
UBGraphicsCache* cacheFromSvg(); |
||||
|
||||
void graphicsItemFromSvg(QGraphicsItem* gItem); |
||||
|
||||
QXmlStreamReader mXmlReader; |
||||
int mFileVersion; |
||||
UBDocumentProxy *mProxy; |
||||
QString mDocumentPath; |
||||
|
||||
QColor mGroupDarkBackgroundColor; |
||||
QColor mGroupLightBackgroundColor; |
||||
qreal mGroupZIndex; |
||||
bool mGroupHasInfo; |
||||
|
||||
QString mNamespaceUri; |
||||
}; |
||||
|
||||
class UBSvgSubsetWriter |
||||
{ |
||||
public: |
||||
|
||||
UBSvgSubsetWriter(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex); |
||||
|
||||
bool persistScene(); |
||||
|
||||
virtual ~UBSvgSubsetWriter(){} |
||||
|
||||
private: |
||||
|
||||
void polygonItemToSvgPolygon(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); |
||||
void polygonItemToSvgLine(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); |
||||
void strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo); |
||||
void strokeToSvgPolygon(UBGraphicsStroke* stroke, bool groupHoldsInfo); |
||||
|
||||
inline QString pointsToSvgPointsAttribute(const QVector<QPointF> points) |
||||
{ |
||||
const QVector<QPointF> crashedPoints = UBGeometryUtils::crashPointList(points); |
||||
|
||||
int pointsCount = crashedPoints.size(); |
||||
QString svgPoints; |
||||
|
||||
int length = 0; |
||||
QString sBuf; |
||||
for(int j = 0; j < pointsCount; j++) |
||||
{ |
||||
const QPointF & point = crashedPoints.at(j);
|
||||
sBuf.sprintf("%.2f,%.2f ", point.x(), point.y()); |
||||
svgPoints.insert(length, sBuf); |
||||
length += sBuf.length(); |
||||
} |
||||
return svgPoints; |
||||
} |
||||
|
||||
inline qreal trickAlpha(qreal alpha) |
||||
{ |
||||
qreal trickAlpha = alpha; |
||||
if(trickAlpha >= 0.2 && trickAlpha < 0.6){ |
||||
trickAlpha /= 5; |
||||
}else if (trickAlpha < 0.8) |
||||
trickAlpha /= 3; |
||||
|
||||
return trickAlpha; |
||||
} |
||||
|
||||
void pixmapItemToLinkedImage(UBGraphicsPixmapItem *pixmapItem); |
||||
void svgItemToLinkedSvg(UBGraphicsSvgItem *svgItem); |
||||
void pdfItemToLinkedPDF(UBGraphicsPDFItem *pdfItem); |
||||
void videoItemToLinkedVideo(UBGraphicsVideoItem *videoItem); |
||||
void audioItemToLinkedAudio(UBGraphicsAudioItem* audioItem); |
||||
void graphicsItemToSvg(QGraphicsItem *item); |
||||
void graphicsAppleWidgetToSvg(UBGraphicsAppleWidgetItem *item); |
||||
void graphicsW3CWidgetToSvg(UBGraphicsW3CWidgetItem *item); |
||||
void graphicsWidgetToSvg(UBGraphicsWidgetItem *item); |
||||
void textItemToSvg(UBGraphicsTextItem *item); |
||||
void curtainItemToSvg(UBGraphicsCurtainItem *item); |
||||
void rulerToSvg(UBGraphicsRuler *item); |
||||
void compassToSvg(UBGraphicsCompass *item); |
||||
void protractorToSvg(UBGraphicsProtractor *item); |
||||
void cacheToSvg(UBGraphicsCache* item); |
||||
void triangleToSvg(UBGraphicsTriangle *item); |
||||
void writeSvgElement(); |
||||
|
||||
private: |
||||
|
||||
UBGraphicsScene* mScene; |
||||
QXmlStreamWriter mXmlWriter; |
||||
QString mDocumentPath; |
||||
int mPageIndex; |
||||
|
||||
}; |
||||
}; |
||||
|
||||
#endif /* UBSVGSUBSETADAPTOR_H_ */ |
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#ifndef UBSVGSUBSETADAPTOR_H_ |
||||
#define UBSVGSUBSETADAPTOR_H_ |
||||
|
||||
#include <QtGui> |
||||
#include <QtXml> |
||||
|
||||
#include "frameworks/UBGeometryUtils.h" |
||||
|
||||
class UBGraphicsSvgItem; |
||||
class UBGraphicsPolygonItem; |
||||
class UBGraphicsPixmapItem; |
||||
class UBGraphicsPDFItem; |
||||
class UBGraphicsWidgetItem; |
||||
class UBGraphicsVideoItem; |
||||
class UBGraphicsAudioItem; |
||||
class UBGraphicsAppleWidgetItem; |
||||
class UBGraphicsW3CWidgetItem; |
||||
class UBGraphicsTextItem; |
||||
class UBGraphicsCurtainItem; |
||||
class UBGraphicsRuler; |
||||
class UBGraphicsCompass; |
||||
class UBGraphicsProtractor; |
||||
class UBGraphicsScene; |
||||
class UBDocumentProxy; |
||||
class UBGraphicsStroke; |
||||
class UBPersistenceManager; |
||||
class UBGraphicsTriangle; |
||||
class UBGraphicsCache; |
||||
|
||||
class UBSvgSubsetAdaptor |
||||
{ |
||||
private: |
||||
|
||||
UBSvgSubsetAdaptor() {;} |
||||
virtual ~UBSvgSubsetAdaptor() {;} |
||||
|
||||
public: |
||||
|
||||
static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const int pageIndex); |
||||
static void persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex); |
||||
static void upgradeScene(UBDocumentProxy* proxy, const int pageIndex); |
||||
|
||||
static QUuid sceneUuid(UBDocumentProxy* proxy, const int pageIndex); |
||||
static void setSceneUuid(UBDocumentProxy* proxy, const int pageIndex, QUuid pUuid); |
||||
|
||||
static void convertPDFObjectsToImages(UBDocumentProxy* proxy); |
||||
static void convertSvgImagesToImages(UBDocumentProxy* proxy); |
||||
|
||||
static const QString nsSvg; |
||||
static const QString nsXLink; |
||||
static const QString nsXHtml; |
||||
static const QString nsUb; |
||||
static const QString xmlTrue; |
||||
static const QString xmlFalse; |
||||
|
||||
static const QString sFontSizePrefix; |
||||
static const QString sPixelUnit; |
||||
static const QString sFontWeightPrefix; |
||||
static const QString sFontStylePrefix; |
||||
|
||||
private: |
||||
|
||||
static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const QByteArray& pArray); |
||||
|
||||
static QDomDocument loadSceneDocument(UBDocumentProxy* proxy, const int pPageIndex); |
||||
|
||||
static QString uniboardDocumentNamespaceUriFromVersion(int fileVersion); |
||||
|
||||
static const QString sFormerUniboardDocumentNamespaceUri; |
||||
|
||||
static QString toSvgTransform(const QMatrix& matrix); |
||||
static QMatrix fromSvgTransform(const QString& transform); |
||||
|
||||
class UBSvgSubsetReader |
||||
{ |
||||
public: |
||||
|
||||
UBSvgSubsetReader(UBDocumentProxy* proxy, const QByteArray& pXmlData); |
||||
|
||||
virtual ~UBSvgSubsetReader(){} |
||||
|
||||
UBGraphicsScene* loadScene(); |
||||
|
||||
private: |
||||
|
||||
UBGraphicsPolygonItem* polygonItemFromLineSvg(const QColor& pDefaultBrushColor); |
||||
|
||||
UBGraphicsPolygonItem* polygonItemFromPolygonSvg(const QColor& pDefaultBrushColor); |
||||
|
||||
QList<UBGraphicsPolygonItem*> polygonItemsFromPolylineSvg(const QColor& pDefaultColor); |
||||
|
||||
UBGraphicsPixmapItem* pixmapItemFromSvg(); |
||||
|
||||
UBGraphicsSvgItem* svgItemFromSvg(); |
||||
|
||||
UBGraphicsPDFItem* pdfItemFromPDF(); |
||||
|
||||
UBGraphicsVideoItem* videoItemFromSvg(); |
||||
|
||||
UBGraphicsAudioItem* audioItemFromSvg(); |
||||
|
||||
UBGraphicsAppleWidgetItem* graphicsAppleWidgetFromSvg(); |
||||
|
||||
UBGraphicsW3CWidgetItem* graphicsW3CWidgetFromSvg(); |
||||
|
||||
UBGraphicsTextItem* textItemFromSvg(); |
||||
|
||||
UBGraphicsCurtainItem* curtainItemFromSvg(); |
||||
|
||||
UBGraphicsRuler* rulerFromSvg(); |
||||
|
||||
UBGraphicsCompass* compassFromSvg(); |
||||
|
||||
UBGraphicsProtractor* protractorFromSvg(); |
||||
|
||||
UBGraphicsTriangle* triangleFromSvg(); |
||||
|
||||
UBGraphicsCache* cacheFromSvg(); |
||||
|
||||
void graphicsItemFromSvg(QGraphicsItem* gItem); |
||||
|
||||
QXmlStreamReader mXmlReader; |
||||
int mFileVersion; |
||||
UBDocumentProxy *mProxy; |
||||
QString mDocumentPath; |
||||
|
||||
QColor mGroupDarkBackgroundColor; |
||||
QColor mGroupLightBackgroundColor; |
||||
qreal mGroupZIndex; |
||||
bool mGroupHasInfo; |
||||
|
||||
QString mNamespaceUri; |
||||
}; |
||||
|
||||
class UBSvgSubsetWriter |
||||
{ |
||||
public: |
||||
|
||||
UBSvgSubsetWriter(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex); |
||||
|
||||
bool persistScene(); |
||||
|
||||
virtual ~UBSvgSubsetWriter(){} |
||||
|
||||
private: |
||||
|
||||
void polygonItemToSvgPolygon(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); |
||||
void polygonItemToSvgLine(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); |
||||
void strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo); |
||||
void strokeToSvgPolygon(UBGraphicsStroke* stroke, bool groupHoldsInfo); |
||||
|
||||
inline QString pointsToSvgPointsAttribute(QVector<QPointF> points) |
||||
{ |
||||
UBGeometryUtils::crashPointList(points); |
||||
|
||||
int pointsCount = points.size(); |
||||
QString svgPoints; |
||||
|
||||
int length = 0; |
||||
QString sBuf; |
||||
|
||||
for(int j = 0; j < pointsCount; j++) |
||||
{ |
||||
sBuf = "%1,%2 "; |
||||
const QPointF & point = points.at(j); |
||||
|
||||
QString temp1 = "%1", temp2 = "%2"; |
||||
|
||||
temp1 = temp1.arg(point.x()); |
||||
temp2 = temp2.arg(point.y()); |
||||
|
||||
QLocale loc(QLocale::C); |
||||
sBuf = sBuf.arg(loc.toFloat(temp1)).arg(loc.toFloat(temp2)); |
||||
|
||||
svgPoints.insert(length, sBuf); |
||||
length += sBuf.length();
|
||||
} |
||||
return svgPoints; |
||||
} |
||||
|
||||
inline qreal trickAlpha(qreal alpha) |
||||
{ |
||||
qreal trickAlpha = alpha; |
||||
if(trickAlpha >= 0.2 && trickAlpha < 0.6){ |
||||
trickAlpha /= 5; |
||||
}else if (trickAlpha < 0.8) |
||||
trickAlpha /= 3; |
||||
|
||||
return trickAlpha; |
||||
} |
||||
|
||||
void pixmapItemToLinkedImage(UBGraphicsPixmapItem *pixmapItem); |
||||
void svgItemToLinkedSvg(UBGraphicsSvgItem *svgItem); |
||||
void pdfItemToLinkedPDF(UBGraphicsPDFItem *pdfItem); |
||||
void videoItemToLinkedVideo(UBGraphicsVideoItem *videoItem); |
||||
void audioItemToLinkedAudio(UBGraphicsAudioItem* audioItem); |
||||
void graphicsItemToSvg(QGraphicsItem *item); |
||||
void graphicsAppleWidgetToSvg(UBGraphicsAppleWidgetItem *item); |
||||
void graphicsW3CWidgetToSvg(UBGraphicsW3CWidgetItem *item); |
||||
void graphicsWidgetToSvg(UBGraphicsWidgetItem *item); |
||||
void textItemToSvg(UBGraphicsTextItem *item); |
||||
void curtainItemToSvg(UBGraphicsCurtainItem *item); |
||||
void rulerToSvg(UBGraphicsRuler *item); |
||||
void compassToSvg(UBGraphicsCompass *item); |
||||
void protractorToSvg(UBGraphicsProtractor *item); |
||||
void cacheToSvg(UBGraphicsCache* item); |
||||
void triangleToSvg(UBGraphicsTriangle *item); |
||||
void writeSvgElement(); |
||||
|
||||
private: |
||||
|
||||
UBGraphicsScene* mScene; |
||||
QXmlStreamWriter mXmlWriter; |
||||
QString mDocumentPath; |
||||
int mPageIndex; |
||||
|
||||
}; |
||||
}; |
||||
|
||||
#endif /* UBSVGSUBSETADAPTOR_H_ */ |
||||
|
@ -1,226 +1,224 @@ |
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include "UBGeometryUtils.h" |
||||
|
||||
#include "core/memcheck.h" |
||||
|
||||
const double PI = 4.0 * atan(1.0); |
||||
|
||||
UBGeometryUtils::UBGeometryUtils() |
||||
{ |
||||
// NOOP
|
||||
} |
||||
|
||||
UBGeometryUtils::~UBGeometryUtils() |
||||
{ |
||||
// NOOP
|
||||
} |
||||
|
||||
QPolygonF UBGeometryUtils::lineToPolygon(const QLineF& pLine, const qreal& pWidth) |
||||
{ |
||||
qreal x1 = pLine.x1(); |
||||
qreal y1 = pLine.y1(); |
||||
|
||||
qreal x2 = pLine.x2(); |
||||
qreal y2 = pLine.y2(); |
||||
|
||||
qreal alpha = (90.0 - pLine.angle()) * PI / 180.0; |
||||
qreal hypothenuse = pWidth / 2; |
||||
|
||||
// TODO UB 4.x PERF cache sin/cos table
|
||||
qreal opposite = sin(alpha) * hypothenuse; |
||||
qreal adjacent = cos(alpha) * hypothenuse; |
||||
|
||||
QPointF p1a(x1 - adjacent, y1 - opposite); |
||||
QPointF p1b(x1 + adjacent, y1 + opposite); |
||||
|
||||
QPointF p2a(x2 - adjacent, y2 - opposite); |
||||
QPointF p2b(x2 + adjacent, y2 + opposite); |
||||
|
||||
QPainterPath painterPath; |
||||
|
||||
painterPath.moveTo(p1a); |
||||
painterPath.lineTo(p2a); |
||||
|
||||
painterPath.arcTo(x2 - hypothenuse, y2 - hypothenuse, pWidth, pWidth, (90.0 + pLine.angle()), -180.0); |
||||
|
||||
//painterPath.lineTo(p2b);
|
||||
painterPath.lineTo(p1b); |
||||
|
||||
painterPath.arcTo(x1 - hypothenuse, y1 - hypothenuse, pWidth, pWidth, -1 * (90.0 - pLine.angle()), -180.0); |
||||
|
||||
painterPath.closeSubpath(); |
||||
|
||||
return painterPath.toFillPolygon(); |
||||
} |
||||
|
||||
QPolygonF UBGeometryUtils::lineToPolygon(const QPointF& pStart, const QPointF& pEnd, |
||||
const qreal& pStartWidth, const qreal& pEndWidth) |
||||
{ |
||||
|
||||
qreal x1 = pStart.x(); |
||||
qreal y1 = pStart.y(); |
||||
|
||||
qreal x2 = pEnd.x(); |
||||
qreal y2 = pEnd.y(); |
||||
|
||||
QLineF line(pStart, pEnd); |
||||
|
||||
qreal alpha = (90.0 - line.angle()) * PI / 180.0; |
||||
qreal hypothenuseStart = pStartWidth / 2; |
||||
|
||||
qreal hypothenuseEnd = pEndWidth / 2; |
||||
|
||||
qreal sinAlpha = sin(alpha); |
||||
qreal cosAlpha = cos(alpha); |
||||
|
||||
// TODO UB 4.x PERF cache sin/cos table
|
||||
qreal oppositeStart = sinAlpha * hypothenuseStart; |
||||
qreal adjacentStart = cosAlpha * hypothenuseStart; |
||||
|
||||
QPointF p1a(x1 - adjacentStart, y1 - oppositeStart); |
||||
QPointF p1b(x1 + adjacentStart, y1 + oppositeStart); |
||||
|
||||
qreal oppositeEnd = sinAlpha * hypothenuseEnd; |
||||
qreal adjacentEnd = cosAlpha * hypothenuseEnd; |
||||
|
||||
QPointF p2a(x2 - adjacentEnd, y2 - oppositeEnd); |
||||
|
||||
QPainterPath painterPath; |
||||
|
||||
painterPath.moveTo(p1a); |
||||
painterPath.lineTo(p2a); |
||||
|
||||
painterPath.arcTo(x2 - hypothenuseEnd, y2 - hypothenuseEnd, pEndWidth, pEndWidth, (90.0 + line.angle()), -180.0); |
||||
|
||||
painterPath.lineTo(p1b); |
||||
|
||||
painterPath.arcTo(x1 - hypothenuseStart, y1 - hypothenuseStart, pStartWidth, pStartWidth, -1 * (90.0 - line.angle()), -180.0); |
||||
|
||||
painterPath.closeSubpath(); |
||||
|
||||
return painterPath.toFillPolygon(); |
||||
} |
||||
|
||||
QPolygonF UBGeometryUtils::arcToPolygon(const QLineF& startRadius, qreal spanAngleInDegrees, qreal width) |
||||
{ |
||||
qreal startAngleInDegrees = - startRadius.angle(); |
||||
if (startAngleInDegrees > 180) |
||||
startAngleInDegrees -= 360; |
||||
else if (startAngleInDegrees < -180) |
||||
startAngleInDegrees += 360; |
||||
|
||||
qreal radiusLength = startRadius.length(); |
||||
qreal angle = 2 * asin(width / (2 * radiusLength)) * 180 / PI; |
||||
bool overlap = abs(spanAngleInDegrees) > 360 - angle; |
||||
if (overlap) |
||||
spanAngleInDegrees = spanAngleInDegrees < 0 ? -360 : 360; |
||||
|
||||
qreal endAngleInDegrees = startAngleInDegrees + spanAngleInDegrees; |
||||
|
||||
qreal innerRadius = radiusLength - width / 2; |
||||
QRectF innerSquare( |
||||
startRadius.p1().x() - innerRadius, |
||||
startRadius.p1().y() - innerRadius, |
||||
2 * innerRadius, |
||||
2 * innerRadius); |
||||
qreal outerRadius = radiusLength + width / 2; |
||||
QRectF outerSquare( |
||||
startRadius.p1().x() - outerRadius, |
||||
startRadius.p1().y() - outerRadius, |
||||
2 * outerRadius, |
||||
2 * outerRadius); |
||||
QRectF startSquare( |
||||
startRadius.p2().x() - width / 2, |
||||
startRadius.p2().y() - width / 2, |
||||
width, |
||||
width); |
||||
QRectF endSquare( |
||||
startRadius.p1().x() + radiusLength * cos(endAngleInDegrees * PI / 180.0) - width / 2, |
||||
startRadius.p1().y() + radiusLength * sin(endAngleInDegrees * PI / 180.0) - width / 2, |
||||
width, |
||||
width); |
||||
|
||||
QPainterPath painterPath( |
||||
QPointF( |
||||
startRadius.p1().x() + innerRadius * cos(startAngleInDegrees * PI / 180.0), |
||||
startRadius.p1().y() + innerRadius * sin(startAngleInDegrees * PI / 180.0))); |
||||
startAngleInDegrees = - startAngleInDegrees; |
||||
endAngleInDegrees = - endAngleInDegrees; |
||||
spanAngleInDegrees = - spanAngleInDegrees; |
||||
|
||||
if (overlap) |
||||
{ |
||||
painterPath.addEllipse(outerSquare); |
||||
QPainterPath innerPainterPath; |
||||
innerPainterPath.addEllipse(innerSquare); |
||||
painterPath = painterPath.subtracted(innerPainterPath); |
||||
} |
||||
else |
||||
{ |
||||
painterPath.arcTo(innerSquare, startAngleInDegrees, spanAngleInDegrees); |
||||
painterPath.arcTo(endSquare, 180.0 + endAngleInDegrees, spanAngleInDegrees > 0 ? -180.0 : 180.0); |
||||
painterPath.arcTo(outerSquare, endAngleInDegrees, - spanAngleInDegrees); |
||||
painterPath.arcTo(startSquare, startAngleInDegrees, spanAngleInDegrees > 0 ? -180.0 : 180.0); |
||||
painterPath.closeSubpath(); |
||||
} |
||||
|
||||
return painterPath.toFillPolygon(); |
||||
} |
||||
|
||||
QPointF UBGeometryUtils::pointConstrainedInRect(QPointF point, QRectF rect) |
||||
{ |
||||
return QPointF(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y()))); |
||||
} |
||||
|
||||
|
||||
QPoint UBGeometryUtils::pointConstrainedInRect(QPoint point, QRect rect) |
||||
{ |
||||
return QPoint(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y()))); |
||||
} |
||||
|
||||
|
||||
QRectF UBGeometryUtils::lineToInnerRect(const QLineF& pLine, const qreal& pWidth) |
||||
{ |
||||
qreal centerX = (pLine.x1() + pLine.x2()) / 2; |
||||
qreal centerY = (pLine.y1() + pLine.y2()) / 2; |
||||
|
||||
qreal side = sqrt((pWidth * pWidth) / 2); |
||||
qreal halfSide = side / 2; |
||||
|
||||
return QRectF(centerX - halfSide, centerY - halfSide, side, side); |
||||
} |
||||
|
||||
|
||||
QVector<QPointF> UBGeometryUtils::crashPointList(const QVector<QPointF> points) |
||||
{ |
||||
QVector<QPointF> result(points); |
||||
int position = 1; |
||||
|
||||
while(position < result.size()) |
||||
{ |
||||
if (result.at(position) == result.at(position - 1)) |
||||
{ |
||||
result.remove(position); |
||||
} |
||||
else |
||||
{ |
||||
++position; |
||||
} |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include "UBGeometryUtils.h" |
||||
|
||||
#include "core/memcheck.h" |
||||
|
||||
const double PI = 4.0 * atan(1.0); |
||||
|
||||
UBGeometryUtils::UBGeometryUtils() |
||||
{ |
||||
// NOOP
|
||||
} |
||||
|
||||
UBGeometryUtils::~UBGeometryUtils() |
||||
{ |
||||
// NOOP
|
||||
} |
||||
|
||||
QPolygonF UBGeometryUtils::lineToPolygon(const QLineF& pLine, const qreal& pWidth) |
||||
{ |
||||
qreal x1 = pLine.x1(); |
||||
qreal y1 = pLine.y1(); |
||||
|
||||
qreal x2 = pLine.x2(); |
||||
qreal y2 = pLine.y2(); |
||||
|
||||
qreal alpha = (90.0 - pLine.angle()) * PI / 180.0; |
||||
qreal hypothenuse = pWidth / 2; |
||||
|
||||
// TODO UB 4.x PERF cache sin/cos table
|
||||
qreal opposite = sin(alpha) * hypothenuse; |
||||
qreal adjacent = cos(alpha) * hypothenuse; |
||||
|
||||
QPointF p1a(x1 - adjacent, y1 - opposite); |
||||
QPointF p1b(x1 + adjacent, y1 + opposite); |
||||
|
||||
QPointF p2a(x2 - adjacent, y2 - opposite); |
||||
QPointF p2b(x2 + adjacent, y2 + opposite); |
||||
|
||||
QPainterPath painterPath; |
||||
|
||||
painterPath.moveTo(p1a); |
||||
painterPath.lineTo(p2a); |
||||
|
||||
painterPath.arcTo(x2 - hypothenuse, y2 - hypothenuse, pWidth, pWidth, (90.0 + pLine.angle()), -180.0); |
||||
|
||||
//painterPath.lineTo(p2b);
|
||||
painterPath.lineTo(p1b); |
||||
|
||||
painterPath.arcTo(x1 - hypothenuse, y1 - hypothenuse, pWidth, pWidth, -1 * (90.0 - pLine.angle()), -180.0); |
||||
|
||||
painterPath.closeSubpath(); |
||||
|
||||
return painterPath.toFillPolygon(); |
||||
} |
||||
|
||||
QPolygonF UBGeometryUtils::lineToPolygon(const QPointF& pStart, const QPointF& pEnd, |
||||
const qreal& pStartWidth, const qreal& pEndWidth) |
||||
{ |
||||
|
||||
qreal x1 = pStart.x(); |
||||
qreal y1 = pStart.y(); |
||||
|
||||
qreal x2 = pEnd.x(); |
||||
qreal y2 = pEnd.y(); |
||||
|
||||
QLineF line(pStart, pEnd); |
||||
|
||||
qreal alpha = (90.0 - line.angle()) * PI / 180.0; |
||||
qreal hypothenuseStart = pStartWidth / 2; |
||||
|
||||
qreal hypothenuseEnd = pEndWidth / 2; |
||||
|
||||
qreal sinAlpha = sin(alpha); |
||||
qreal cosAlpha = cos(alpha); |
||||
|
||||
// TODO UB 4.x PERF cache sin/cos table
|
||||
qreal oppositeStart = sinAlpha * hypothenuseStart; |
||||
qreal adjacentStart = cosAlpha * hypothenuseStart; |
||||
|
||||
QPointF p1a(x1 - adjacentStart, y1 - oppositeStart); |
||||
QPointF p1b(x1 + adjacentStart, y1 + oppositeStart); |
||||
|
||||
qreal oppositeEnd = sinAlpha * hypothenuseEnd; |
||||
qreal adjacentEnd = cosAlpha * hypothenuseEnd; |
||||
|
||||
QPointF p2a(x2 - adjacentEnd, y2 - oppositeEnd); |
||||
|
||||
QPainterPath painterPath; |
||||
|
||||
painterPath.moveTo(p1a); |
||||
painterPath.lineTo(p2a); |
||||
|
||||
painterPath.arcTo(x2 - hypothenuseEnd, y2 - hypothenuseEnd, pEndWidth, pEndWidth, (90.0 + line.angle()), -180.0); |
||||
|
||||
painterPath.lineTo(p1b); |
||||
|
||||
painterPath.arcTo(x1 - hypothenuseStart, y1 - hypothenuseStart, pStartWidth, pStartWidth, -1 * (90.0 - line.angle()), -180.0); |
||||
|
||||
painterPath.closeSubpath(); |
||||
|
||||
return painterPath.toFillPolygon(); |
||||
} |
||||
|
||||
QPolygonF UBGeometryUtils::arcToPolygon(const QLineF& startRadius, qreal spanAngleInDegrees, qreal width) |
||||
{ |
||||
qreal startAngleInDegrees = - startRadius.angle(); |
||||
if (startAngleInDegrees > 180) |
||||
startAngleInDegrees -= 360; |
||||
else if (startAngleInDegrees < -180) |
||||
startAngleInDegrees += 360; |
||||
|
||||
qreal radiusLength = startRadius.length(); |
||||
qreal angle = 2 * asin(width / (2 * radiusLength)) * 180 / PI; |
||||
bool overlap = abs(spanAngleInDegrees) > 360 - angle; |
||||
if (overlap) |
||||
spanAngleInDegrees = spanAngleInDegrees < 0 ? -360 : 360; |
||||
|
||||
qreal endAngleInDegrees = startAngleInDegrees + spanAngleInDegrees; |
||||
|
||||
qreal innerRadius = radiusLength - width / 2; |
||||
QRectF innerSquare( |
||||
startRadius.p1().x() - innerRadius, |
||||
startRadius.p1().y() - innerRadius, |
||||
2 * innerRadius, |
||||
2 * innerRadius); |
||||
qreal outerRadius = radiusLength + width / 2; |
||||
QRectF outerSquare( |
||||
startRadius.p1().x() - outerRadius, |
||||
startRadius.p1().y() - outerRadius, |
||||
2 * outerRadius, |
||||
2 * outerRadius); |
||||
QRectF startSquare( |
||||
startRadius.p2().x() - width / 2, |
||||
startRadius.p2().y() - width / 2, |
||||
width, |
||||
width); |
||||
QRectF endSquare( |
||||
startRadius.p1().x() + radiusLength * cos(endAngleInDegrees * PI / 180.0) - width / 2, |
||||
startRadius.p1().y() + radiusLength * sin(endAngleInDegrees * PI / 180.0) - width / 2, |
||||
width, |
||||
width); |
||||
|
||||
QPainterPath painterPath( |
||||
QPointF( |
||||
startRadius.p1().x() + innerRadius * cos(startAngleInDegrees * PI / 180.0), |
||||
startRadius.p1().y() + innerRadius * sin(startAngleInDegrees * PI / 180.0))); |
||||
startAngleInDegrees = - startAngleInDegrees; |
||||
endAngleInDegrees = - endAngleInDegrees; |
||||
spanAngleInDegrees = - spanAngleInDegrees; |
||||
|
||||
if (overlap) |
||||
{ |
||||
painterPath.addEllipse(outerSquare); |
||||
QPainterPath innerPainterPath; |
||||
innerPainterPath.addEllipse(innerSquare); |
||||
painterPath = painterPath.subtracted(innerPainterPath); |
||||
} |
||||
else |
||||
{ |
||||
painterPath.arcTo(innerSquare, startAngleInDegrees, spanAngleInDegrees); |
||||
painterPath.arcTo(endSquare, 180.0 + endAngleInDegrees, spanAngleInDegrees > 0 ? -180.0 : 180.0); |
||||
painterPath.arcTo(outerSquare, endAngleInDegrees, - spanAngleInDegrees); |
||||
painterPath.arcTo(startSquare, startAngleInDegrees, spanAngleInDegrees > 0 ? -180.0 : 180.0); |
||||
painterPath.closeSubpath(); |
||||
} |
||||
|
||||
return painterPath.toFillPolygon(); |
||||
} |
||||
|
||||
QPointF UBGeometryUtils::pointConstrainedInRect(QPointF point, QRectF rect) |
||||
{ |
||||
return QPointF(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y()))); |
||||
} |
||||
|
||||
|
||||
QPoint UBGeometryUtils::pointConstrainedInRect(QPoint point, QRect rect) |
||||
{ |
||||
return QPoint(qMax(rect.x(), qMin(rect.x() + rect.width(), point.x())), qMax(rect.y(), qMin(rect.y() + rect.height(), point.y()))); |
||||
} |
||||
|
||||
|
||||
QRectF UBGeometryUtils::lineToInnerRect(const QLineF& pLine, const qreal& pWidth) |
||||
{ |
||||
qreal centerX = (pLine.x1() + pLine.x2()) / 2; |
||||
qreal centerY = (pLine.y1() + pLine.y2()) / 2; |
||||
|
||||
qreal side = sqrt((pWidth * pWidth) / 2); |
||||
qreal halfSide = side / 2; |
||||
|
||||
return QRectF(centerX - halfSide, centerY - halfSide, side, side); |
||||
} |
||||
|
||||
|
||||
void UBGeometryUtils::crashPointList(QVector<QPointF> &points) |
||||
{ |
||||
// QVector<QPointF> result(points);
|
||||
int position = 1; |
||||
|
||||
while(position < points.size()) |
||||
{ |
||||
if (points.at(position) == points.at(position - 1)) |
||||
{ |
||||
points.remove(position); |
||||
} |
||||
else |
||||
{ |
||||
++position; |
||||
} |
||||
} |
||||
} |
||||
|
@ -1,42 +1,42 @@ |
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#ifndef UBGEOMETRYUTILS_H_ |
||||
#define UBGEOMETRYUTILS_H_ |
||||
|
||||
#include <QtGui> |
||||
|
||||
class UBGeometryUtils |
||||
{ |
||||
private: |
||||
UBGeometryUtils(); |
||||
virtual ~UBGeometryUtils(); |
||||
|
||||
public: |
||||
static QPolygonF lineToPolygon(const QLineF& pLine, const qreal& pWidth); |
||||
static QRectF lineToInnerRect(const QLineF& pLine, const qreal& pWidth); |
||||
|
||||
static QPolygonF arcToPolygon(const QLineF& startRadius, qreal spanAngle, qreal width); |
||||
|
||||
static QPolygonF lineToPolygon(const QPointF& pStart, const QPointF& pEnd, |
||||
const qreal& pStartWidth, const qreal& pEndWidth); |
||||
|
||||
static QPointF pointConstrainedInRect(QPointF point, QRectF rect); |
||||
static QPoint pointConstrainedInRect(QPoint point, QRect rect); |
||||
|
||||
static QVector<QPointF> crashPointList(const QVector<QPointF> points); |
||||
}; |
||||
|
||||
#endif /* UBGEOMETRYUTILS_H_ */ |
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#ifndef UBGEOMETRYUTILS_H_ |
||||
#define UBGEOMETRYUTILS_H_ |
||||
|
||||
#include <QtGui> |
||||
|
||||
class UBGeometryUtils |
||||
{ |
||||
private: |
||||
UBGeometryUtils(); |
||||
virtual ~UBGeometryUtils(); |
||||
|
||||
public: |
||||
static QPolygonF lineToPolygon(const QLineF& pLine, const qreal& pWidth); |
||||
static QRectF lineToInnerRect(const QLineF& pLine, const qreal& pWidth); |
||||
|
||||
static QPolygonF arcToPolygon(const QLineF& startRadius, qreal spanAngle, qreal width); |
||||
|
||||
static QPolygonF lineToPolygon(const QPointF& pStart, const QPointF& pEnd, |
||||
const qreal& pStartWidth, const qreal& pEndWidth); |
||||
|
||||
static QPointF pointConstrainedInRect(QPointF point, QRectF rect); |
||||
static QPoint pointConstrainedInRect(QPoint point, QRect rect); |
||||
|
||||
static void crashPointList(QVector<QPointF> &points); |
||||
}; |
||||
|
||||
#endif /* UBGEOMETRYUTILS_H_ */ |
||||
|
Loading…
Reference in new issue