SplinePath.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package
19  * @author
20  * @date
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 #include "SplinePath.h"
25 
26 #include <cassert>
27 #include <cmath>
28 
30 
32 {
33 }
34 
35 QPainterPath
37 {
38  //assert((simpleControlPoints.size() == 2) || (simpleControlPoints.size() % 3 == 1));
39 
40  QPainterPath path;
41 
42  if (simpleControlPoints.size() == 2)
43  {
44  // ARMARX_DEBUG_S << "Direct Line";
45  path.moveTo(simpleControlPoints.first());
46  path.lineTo(simpleControlPoints.last());
47  }
48  else if (simpleControlPoints.size() == 3)
49  {
50  // ARMARX_DEBUG_S << "Quad. path";
51  path.moveTo(simpleControlPoints.first());
52  path.quadTo(simpleControlPoints.at(1), simpleControlPoints.last());
53  }
54  else
55  {
56  // ARMARX_DEBUG_S << "complex path";
57  path = complexPath(simpleControlPoints);
58  }
59 
60  return path;
61 
62  /*
63  * this doesn't work
64  *
65  QPointVector fullControlPoints;
66 
67  if(simpleControlPoints.size() > 1)
68  {
69  //add first given simpleControlPoint also as first complexControlPoint
70  auto iter = simpleControlPoints.begin();
71  fullControlPoints.push_back(*iter);
72 
73  //create point between the first two simpleControlPoints
74  QPoint2Array linePoints = line(*iter, *(iter + 1));
75  iter++;
76  //add the new point and the second simpleControlPoint to the fullControlPoints
77  fullControlPoints.insert(fullControlPoints.end(), linePoints.begin(), linePoints.end());
78 
79  while(iter < simpleControlPoints.end() - 1)
80  {
81  QPoint2Array linePoints = line(*iter, *(iter + 1));
82  iter++;
83  fullControlPoints.insert(fullControlPoints.end(), linePoints.begin(), linePoints.end());
84 
85  if(iter < simpleControlPoints.end() - 2)
86  {
87  QPoint4Array transitionPoints = smoothTransition(*iter, *(iter + 1), *(iter + 2));
88  iter = iter + 2;
89  fullControlPoints.insert(fullControlPoints.end(), transitionPoints.begin(), transitionPoints.end());
90  }
91  }
92  }
93 
94  //ensure that there are enough control points to create a cubic Bezierspline
95  while((fullControlPoints.size() % 3 != 1) || (fullControlPoints.size() < 4))
96  {
97  fullControlPoints.insert(fullControlPoints.begin(), simpleControlPoints.front());
98  }
99 
100  return complexPath(fullControlPoints);
101  */
102 }
103 
104 QPainterPath
106 {
107  assert((fullControlPoints.size() % 3 == 1) && (fullControlPoints.size() > 3));
108 
109  QPainterPath path{fullControlPoints.at(0)};
110 
111  for (int i = 1; i < fullControlPoints.size(); i += 3)
112  {
113  assert(i + 2 < fullControlPoints.size()); //size of controlPoints == 1 mod 3
114 
115  path.cubicTo(
116  fullControlPoints.at(i), fullControlPoints.at(i + 1), fullControlPoints.at(i + 2));
117  }
118 
119  /*
120  //print circles on control points
121  for(QPointF controlPoint : fullControlPoints)
122  {
123  path.addEllipse(controlPoint, 5, 5);
124  }
125  */
126 
127  //only for debugging
128  //pathToString(path);
129  return path;
130 }
131 
133 armarx::SplinePath::line(QPointF start, QPointF end)
134 {
135  QPointF direction = end - start; //vector from start to end
136  QPointF middle = start + 0.5 * direction;
137 
138  QPoint2Array array{{middle, end}};
139  return array;
140 }
141 
143 armarx::SplinePath::smoothTransition(QPointF start, QPointF middle, QPointF end)
144 {
145  QPointF parallelLine = end - start; //vector from start to end
146 
147  //put the two new points on the line parallel to parallelLine that goes through middle.
148  QPointF new1 = middle - relativeDistance * parallelLine;
149  QPointF new2 = middle + relativeDistance * parallelLine;
150 
151  QPoint4Array array{{new1, middle, new2, end}};
152  return array;
153 }
154 
155 void
156 armarx::SplinePath::pathToString(QPainterPath path)
157 {
158  // ARMARX_LOG_S << "New path begins:";
159  for (size_t i = 0; i < static_cast<size_t>(path.elementCount()); i++)
160  {
161  QPainterPath::Element elem = path.elementAt(i);
162 
163  std::string type;
164 
165  switch (elem.type)
166  {
167  case QPainterPath::MoveToElement:
168  {
169  type = "Move";
170  break;
171  }
172 
173  case QPainterPath::LineToElement:
174  {
175  type = "Line";
176  break;
177  }
178 
179  case QPainterPath::CurveToElement:
180  {
181  type = "Curve";
182  break;
183  }
184 
185  default:
186  break;
187  }
188 
189  if (elem.type != QPainterPath::CurveToDataElement)
190  {
191  // ARMARX_LOG_S << type << " at (" << elem.x << ", " << elem.y << ")";
192  }
193  }
194 }
armarx::QPointList
QList< QPointF > QPointList
Definition: Transition.h:38
armarx::SplinePath::SplinePath
SplinePath()
Definition: SplinePath.cpp:31
armarx::SplinePath::simplePath
static QPainterPath simplePath(QPointList simpleControlPoints)
simplePath Constructs a cubic Beziercurve with an arbitrary number of control points.
Definition: SplinePath.cpp:36
armarx::QPoint2Array
std::array< QPointF, 2 > QPoint2Array
Definition: SplinePath.h:36
armarx::SplinePath::complexPath
static QPainterPath complexPath(QPointList fullControlPoints)
complexPath Constructs a cubic Beziercurve with a correctly specified vector of control points.
Definition: SplinePath.cpp:105
SplinePath.h
Logging.h
armarx::QPoint4Array
std::array< QPointF, 4 > QPoint4Array
Definition: SplinePath.h:37