6 * $Date: 2012-07-05 16:45:20 +0200 (Do, 05. Jul 2012) $
7 ***************************************************************/
10 * \brief Implements simple labeling algorithm
12 * \author Joachim Kupke
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
44 #include <ogdf/labeling/ELabelPosSimple.h>
49 ELabelPosSimple::ELabelPosSimple() :
51 m_marginDistance(0.2),
57 ELabelPosSimple::~ELabelPosSimple()
61 // returns the segment of the polyline containing the point
62 // that is fraction*bends.length() away from the start
63 static DLine
segment(DPolyline
&bends
, double fraction
)
65 double targetpos
= bends
.length()*fraction
;
68 ListConstIterator
<DPoint
> iter
, next
;
69 for (iter
= next
= bends
.begin(), next
++; next
.valid(); iter
++, next
++) {
70 pos
+= (*iter
).distance(*next
);
72 return DLine(*iter
, *next
);
75 return DLine(*--iter
, bends
.back());
79 // liefert den Punkt neben dem Segment (links oder rechts, siehe 'left'), der orthogonal von
80 // 'p' die Entfernung 'newLen' von diesem Segment hat.
81 static DPoint
leftOfSegment(const DLine
&segment
, const DPoint
&p
, double newLen
, bool left
= true)
84 if (p
== segment
.start())
85 v
= segment
.end() - p
;
87 v
= p
- segment
.start();
90 if (left
) newPos
= ++v
;
93 // newPos hat immer L?nge != 0
94 newPos
= (newPos
* newLen
) / newPos
.length();
100 void ELabelPosSimple::call(GraphAttributes
&ug
, ELabelInterface
<double> &eli
)
102 //ug.addNodeCenter2Bends();
104 forall_edges(e
, ug
.constGraph()) {
105 EdgeLabel
<double> &el
= eli
.getLabel(e
);
106 DPolyline bends
= ug
.bends(e
);
110 if (bends
.size() < 2)
111 OGDF_THROW_PARAM(AlgorithmFailureException
, afcLabel
);
116 double len
= bends
.length();
120 frac
= m_marginDistance
/ len
;
124 frac
= m_marginDistance
;
127 if (frac
< 0.0) frac
= 0.0;
128 if (frac
> 0.4) frac
= 0.4;
130 double midFrac
= 0.5;
131 double startFrac
= frac
;
132 double endFrac
= 1.0 -frac
;
134 // hole Positionen auf der Kante
135 DPoint midPoint
= bends
.position(midFrac
);
136 DPoint startPoint
= bends
.position(startFrac
);
137 DPoint endPoint
= bends
.position(endFrac
);
139 // hole die beteiligten Segmente
140 DLine midLine
= segment(bends
, midFrac
);
141 DLine startLine
= segment(bends
, startFrac
);
142 DLine endLine
= segment(bends
, endFrac
);
144 // berechne die Labelpositionen
145 if (el
.usedLabel(elEnd1
)) {
146 DPoint np
= leftOfSegment(startLine
, startPoint
, m_edgeDistance
, true);
147 el
.setX(elEnd1
, np
.m_x
);
148 el
.setY(elEnd1
, np
.m_y
);
151 if (el
.usedLabel(elMult1
)) {
152 DPoint np
= leftOfSegment(startLine
, startPoint
, m_edgeDistance
, false);
153 el
.setX(elMult1
, np
.m_x
);
154 el
.setY(elMult1
, np
.m_y
);
157 if (el
.usedLabel(elName
)) {
158 DPoint np
= m_midOnEdge
? midPoint
: leftOfSegment(midLine
, midPoint
, m_edgeDistance
, true);
159 el
.setX(elName
, np
.m_x
);
160 el
.setY(elName
, np
.m_y
);
163 if (el
.usedLabel(elEnd2
)) {
164 DPoint np
= leftOfSegment(endLine
, endPoint
, m_edgeDistance
, true);
165 el
.setX(elEnd2
, np
.m_x
);
166 el
.setY(elEnd2
, np
.m_y
);
169 if (el
.usedLabel(elMult2
)) {
170 DPoint np
= leftOfSegment(endLine
, endPoint
, m_edgeDistance
, false);
171 el
.setX(elMult2
, np
.m_x
);
172 el
.setY(elMult2
, np
.m_y
);