File indexing completed on 2024-06-23 04:27:03
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "EnhancedPathHandle.h" 0008 #include "EnhancedPathShape.h" 0009 #include "EnhancedPathParameter.h" 0010 #include <KoShapeSavingContext.h> 0011 #include <KoXmlWriter.h> 0012 #include <KoXmlNS.h> 0013 #include <KoShapeLoadingContext.h> 0014 0015 #include <math.h> 0016 0017 EnhancedPathHandle::EnhancedPathHandle(EnhancedPathShape *parent) 0018 : m_parent(parent) 0019 , m_positionX(0) 0020 , m_positionY(0) 0021 , m_minimumX(0) 0022 , m_minimumY(0) 0023 , m_maximumX(0) 0024 , m_maximumY(0) 0025 , m_polarX(0) 0026 , m_polarY(0) 0027 , m_minRadius(0) 0028 , m_maxRadius(0) 0029 { 0030 Q_ASSERT(m_parent); 0031 } 0032 0033 EnhancedPathHandle::~EnhancedPathHandle() 0034 { 0035 } 0036 0037 bool EnhancedPathHandle::hasPosition() const 0038 { 0039 return m_positionX && m_positionY; 0040 } 0041 0042 void EnhancedPathHandle::setPosition(EnhancedPathParameter *positionX, EnhancedPathParameter *positionY) 0043 { 0044 m_positionX = positionX; 0045 m_positionY = positionY; 0046 } 0047 0048 QPointF EnhancedPathHandle::position() 0049 { 0050 if (!hasPosition()) { 0051 return QPointF(); 0052 } 0053 0054 QPointF position(m_positionX->evaluate(), m_positionY->evaluate()); 0055 if (isPolar()) { 0056 // convert polar coordinates into cartesian coordinates 0057 QPointF center(m_polarX->evaluate(), m_polarY->evaluate()); 0058 qreal angleInRadian = position.x() * M_PI / 180.0; 0059 position = center + position.y() * QPointF(cos(angleInRadian), sin(angleInRadian)); 0060 } 0061 0062 return position; 0063 } 0064 0065 void EnhancedPathHandle::changePosition(const QPointF &position) 0066 { 0067 if (!hasPosition()) { 0068 return; 0069 } 0070 0071 QPointF constrainedPosition(position); 0072 0073 if (isPolar()) { 0074 // convert cartesian coordinates into polar coordinates 0075 QPointF polarCenter(m_polarX->evaluate(), m_polarY->evaluate()); 0076 QPointF diff = constrainedPosition - polarCenter; 0077 // compute the polar radius 0078 qreal radius = sqrt(diff.x() * diff.x() + diff.y() * diff.y()); 0079 // compute the polar angle 0080 qreal angle = atan2(diff.y(), diff.x()); 0081 if (angle < 0.0) { 0082 angle += 2 * M_PI; 0083 } 0084 0085 // constrain the radius 0086 if (m_minRadius) { 0087 radius = qMax(m_minRadius->evaluate(), radius); 0088 } 0089 if (m_maxRadius) { 0090 radius = qMin(m_maxRadius->evaluate(), radius); 0091 } 0092 0093 constrainedPosition.setX(angle * 180.0 / M_PI); 0094 constrainedPosition.setY(radius); 0095 } else { 0096 // constrain x coordinate 0097 if (m_minimumX) { 0098 constrainedPosition.setX(qMax(m_minimumX->evaluate(), constrainedPosition.x())); 0099 } 0100 if (m_maximumX) { 0101 constrainedPosition.setX(qMin(m_maximumX->evaluate(), constrainedPosition.x())); 0102 } 0103 0104 // constrain y coordinate 0105 if (m_minimumY) { 0106 constrainedPosition.setY(qMax(m_minimumY->evaluate(), constrainedPosition.y())); 0107 } 0108 if (m_maximumY) { 0109 constrainedPosition.setY(qMin(m_maximumY->evaluate(), constrainedPosition.y())); 0110 } 0111 } 0112 0113 m_positionX->modify(constrainedPosition.x()); 0114 m_positionY->modify(constrainedPosition.y()); 0115 } 0116 0117 void EnhancedPathHandle::setRangeX(EnhancedPathParameter *minX, EnhancedPathParameter *maxX) 0118 { 0119 m_minimumX = minX; 0120 m_maximumX = maxX; 0121 } 0122 0123 void EnhancedPathHandle::setRangeY(EnhancedPathParameter *minY, EnhancedPathParameter *maxY) 0124 { 0125 m_minimumY = minY; 0126 m_maximumY = maxY; 0127 } 0128 0129 void EnhancedPathHandle::setPolarCenter(EnhancedPathParameter *polarX, EnhancedPathParameter *polarY) 0130 { 0131 m_polarX = polarX; 0132 m_polarY = polarY; 0133 } 0134 0135 void EnhancedPathHandle::setRadiusRange(EnhancedPathParameter *minRadius, EnhancedPathParameter *maxRadius) 0136 { 0137 m_minRadius = minRadius; 0138 m_maxRadius = maxRadius; 0139 } 0140 0141 bool EnhancedPathHandle::isPolar() const 0142 { 0143 return m_polarX && m_polarY; 0144 }