Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
9ae5cc7e
Commit
9ae5cc7e
authored
Aug 20, 2018
by
Thomas Gubler
Committed by
Thomas Gubler
Nov 07, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Survey transects generation] towards concave polygons
parent
059578e6
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
142 additions
and
28 deletions
+142
-28
SurveyComplexItem.cc
src/MissionManager/SurveyComplexItem.cc
+139
-26
SurveyComplexItem.h
src/MissionManager/SurveyComplexItem.h
+3
-2
No files found.
src/MissionManager/SurveyComplexItem.cc
View file @
9ae5cc7e
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include <QPolygonF>
#include <QPolygonF>
QGC_LOGGING_CATEGORY
(
SurveyComplexItemLog
,
"SurveyComplexItemLog"
)
QGC_LOGGING_CATEGORY
(
SurveyComplexItemLog
,
"SurveyComplexItemLog"
)
QGC_LOGGING_CATEGORY
(
PolygonDecomposeLog
,
"PolygonDecomposeLog"
)
const
char
*
SurveyComplexItem
::
jsonComplexItemTypeValue
=
"survey"
;
const
char
*
SurveyComplexItem
::
jsonComplexItemTypeValue
=
"survey"
;
const
char
*
SurveyComplexItem
::
jsonV3ComplexItemTypeValue
=
"survey"
;
const
char
*
SurveyComplexItem
::
jsonV3ComplexItemTypeValue
=
"survey"
;
...
@@ -1116,78 +1117,132 @@ void SurveyComplexItem::_rebuildTransectsPhase1Worker(bool refly)
...
@@ -1116,78 +1117,132 @@ void SurveyComplexItem::_rebuildTransectsPhase1Worker(bool refly)
// Create list of separate polygons
// Create list of separate polygons
QList
<
QPolygonF
>
polygons
{};
QList
<
QPolygonF
>
polygons
{};
qCDebug
(
PolygonDecomposeLog
)
<<
"*********_PolygonDecomposeConvex begin of recursion**************"
;
_PolygonDecomposeConvex
(
polygon
,
polygons
);
_PolygonDecomposeConvex
(
polygon
,
polygons
);
qCDebug
(
PolygonDecomposeLog
)
<<
"polygons.size() "
<<
polygons
.
size
()
;
// iterate over polygons
// iterate over polygons
for
(
auto
&
p
:
polygons
)
{
for
(
auto
p
=
polygons
.
begin
();
p
!=
polygons
.
end
();
++
p
)
{
QPointF
*
vMatch
=
nullptr
;
// find matching vertex in previous polygon
if
(
p
!=
polygons
.
begin
())
{
auto
pLast
=
p
-
1
;
for
(
auto
&
i
:
*
p
)
{
for
(
auto
&
j
:
*
pLast
)
{
if
(
i
==
j
)
{
vMatch
=
&
i
;
break
;
}
if
(
vMatch
)
break
;
}
}
if
(
nullptr
==
vMatch
)
qCDebug
(
PolygonDecomposeLog
)
<<
"no match found"
;
}
// close polygon
// close polygon
p
<<
p
.
front
();
*
p
<<
p
->
front
();
// build transects for this polygon
// build transects for this polygon
// TODO figure out tangent origin
// TODO figure out tangent origin
qCDebug
(
SurveyComplexItemLog
)
<<
"Transects from polynom p "
<<
p
;
// TODO improve selection of entry points
_rebuildTranscetsFromPolygon
(
refly
,
p
,
tangentOrigin
);
// qCDebug(SurveyComplexItemLog) << "Transects from polynom p " << p;
_rebuildTranscetsFromPolygon
(
refly
,
*
p
,
tangentOrigin
,
vMatch
);
}
}
}
}
void
SurveyComplexItem
::
_PolygonDecomposeConvex
(
const
QPolygonF
&
polygon
,
QList
<
QPolygonF
>&
decomposedPolygons
)
void
SurveyComplexItem
::
_PolygonDecomposeConvex
(
const
QPolygonF
&
polygon
,
QList
<
QPolygonF
>&
decomposedPolygons
)
{
{
qCDebug
(
SurveyComplexItemLog
)
<<
"_PolygonDecomposeConvex polygon.size() "
<<
polygon
.
size
();
// qCDebug(SurveyComplexItemLog) << "_PolygonDecomposeConvex polygon.size() " << polygon.size();
int
decompSize
=
std
::
numeric_limits
<
int
>::
max
();
if
(
polygon
.
size
()
<
3
)
return
;
if
(
polygon
.
size
()
<
3
)
return
;
if
(
polygon
.
size
()
==
3
)
{
decomposedPolygons
<<
polygon
;
// qCDebug(PolygonDecomposeLog) << polygon << " polygon of 3";
return
;
}
int
decompSize
=
std
::
numeric_limits
<
int
>::
max
();
QList
<
QPolygonF
>
decomposedPolygonsMin
{};
QList
<
QPolygonF
>
decomposedPolygonsMin
{};
for
(
auto
vertex
=
polygon
.
begin
();
vertex
!=
polygon
.
end
();
++
vertex
)
for
(
auto
vertex
=
polygon
.
begin
();
vertex
!=
polygon
.
end
();
++
vertex
)
{
{
// is vertex reflex?
// is vertex reflex?
auto
vertexBefore
=
vertex
==
polygon
.
begin
()
?
polygon
.
end
()
-
1
:
vertex
-
1
;
bool
vertexIsReflex
=
_VertexIsReflex
(
polygon
,
vertex
);
auto
vertexAfter
=
vertex
==
polygon
.
end
()
-
1
?
polygon
.
begin
()
:
vertex
+
1
;
// qCDebug(SurveyComplexItemLog) << "area " << area << " vertexIsReflex " << vertexIsReflex;
auto
area
=
(((
vertex
->
x
()
-
vertexBefore
->
x
())
*
(
vertexAfter
->
y
()
-
vertexBefore
->
y
()))
-
((
vertexAfter
->
x
()
-
vertexBefore
->
x
())
*
(
vertex
->
y
()
-
vertexBefore
->
y
())));
bool
vertexIsReflex
=
area
>
0
;
qCDebug
(
SurveyComplexItemLog
)
<<
"area "
<<
area
<<
" vertexIsReflex "
<<
vertexIsReflex
;
if
(
!
vertexIsReflex
)
continue
;
if
(
!
vertexIsReflex
)
continue
;
for
(
auto
vertexOther
=
polygon
.
begin
();
vertexOther
!=
polygon
.
end
();
++
vertexOther
)
for
(
auto
vertexOther
=
polygon
.
begin
();
vertexOther
!=
polygon
.
end
();
++
vertexOther
)
{
{
auto
vertexBefore
=
vertex
==
polygon
.
begin
()
?
polygon
.
end
()
-
1
:
vertex
-
1
;
auto
vertexAfter
=
vertex
==
polygon
.
end
()
-
1
?
polygon
.
begin
()
:
vertex
+
1
;
if
(
vertexOther
==
vertex
)
continue
;
if
(
vertexOther
==
vertex
)
continue
;
if
(
vertexAfter
==
vertexOther
)
continue
;
if
(
vertexBefore
==
vertexOther
)
continue
;
bool
canSee
=
_VertexCanSeeOther
(
polygon
,
vertex
,
vertexOther
);
bool
canSee
=
_VertexCanSeeOther
(
polygon
,
vertex
,
vertexOther
);
// qCDebug(SurveyComplexItemLog) << "canSee " << canSee;
if
(
!
canSee
)
continue
;
if
(
!
canSee
)
continue
;
QPolygonF
polyLeft
;
QPolygonF
polyLeft
;
auto
v
=
vertex
;
auto
v
=
vertex
;
auto
polyLeftContainsReflex
=
false
;
while
(
v
!=
vertexOther
)
{
while
(
v
!=
vertexOther
)
{
if
(
v
!=
vertex
&&
_VertexIsReflex
(
polygon
,
v
))
{
polyLeftContainsReflex
=
true
;
}
polyLeft
<<
*
v
;
polyLeft
<<
*
v
;
++
v
;
++
v
;
if
(
v
==
polygon
.
end
())
v
=
polygon
.
begin
();
if
(
v
==
polygon
.
end
())
v
=
polygon
.
begin
();
}
}
polyLeft
<<
*
vertexOther
;
polyLeft
<<
*
vertexOther
;
qCDebug
(
SurveyComplexItemLog
)
<<
"polyLeft.size() "
<<
polyLeft
.
size
(
);
auto
polyLeftValid
=
!
(
polyLeftContainsReflex
&&
polyLeft
.
size
()
==
3
);
QPolygonF
polyRight
;
QPolygonF
polyRight
;
v
=
vertexOther
;
v
=
vertexOther
;
auto
polyRightContainsReflex
=
false
;
while
(
v
!=
vertex
)
{
while
(
v
!=
vertex
)
{
if
(
v
!=
vertex
&&
_VertexIsReflex
(
polygon
,
v
))
{
polyRightContainsReflex
=
true
;
}
polyRight
<<
*
v
;
polyRight
<<
*
v
;
++
v
;
++
v
;
if
(
v
==
polygon
.
end
())
v
=
polygon
.
begin
();
if
(
v
==
polygon
.
end
())
v
=
polygon
.
begin
();
}
}
polyRight
<<
*
vertex
;
polyRight
<<
*
vertex
;
qCDebug
(
SurveyComplexItemLog
)
<<
"polyRight.size() "
<<
polyRight
.
size
();
auto
polyRightValid
=
!
(
polyRightContainsReflex
&&
polyRight
.
size
()
==
3
);
if
(
!
polyLeftValid
||
!
polyRightValid
)
{
// decompSize = std::numeric_limits<int>::max();
continue
;
}
// recursion
// recursion
QList
<
QPolygonF
>
polyLeftDecomposed
{};
QList
<
QPolygonF
>
polyLeftDecomposed
{};
// qCDebug(PolygonDecomposeLog) << " polyLeft "<< polyLeft;
_PolygonDecomposeConvex
(
polyLeft
,
polyLeftDecomposed
);
_PolygonDecomposeConvex
(
polyLeft
,
polyLeftDecomposed
);
QList
<
QPolygonF
>
polyRightDecomposed
{};
QList
<
QPolygonF
>
polyRightDecomposed
{};
// qCDebug(PolygonDecomposeLog) << " polyRight "<< polyRight;
_PolygonDecomposeConvex
(
polyRight
,
polyRightDecomposed
);
_PolygonDecomposeConvex
(
polyRight
,
polyRightDecomposed
);
// compositon
// compositon
if
(
polyLeftDecomposed
.
size
()
+
polyRightDecomposed
.
size
()
<
decompSize
)
{
auto
subSize
=
polyLeftDecomposed
.
size
()
+
polyRightDecomposed
.
size
();
decompSize
=
polyLeftDecomposed
.
size
()
+
polyRightDecomposed
.
size
();
if
((
polyLeftContainsReflex
&&
polyLeftDecomposed
.
size
()
==
1
)
||
(
polyRightContainsReflex
&&
polyRightDecomposed
.
size
()
==
1
))
{
// don't accept polygons that contian reflex vertices and were not split
subSize
=
std
::
numeric_limits
<
int
>::
max
();
}
if
(
subSize
<
decompSize
)
{
decompSize
=
subSize
;
decomposedPolygonsMin
=
polyLeftDecomposed
+
polyRightDecomposed
;
decomposedPolygonsMin
=
polyLeftDecomposed
+
polyRightDecomposed
;
qCDebug
(
SurveyComplexItemLog
)
<<
"changing decomposedPolygonsMin"
;
// qCDebug(PolygonDecomposeLog) << "_PolygonDecomposeConvex polygon " << polygon;
// qCDebug(PolygonDecomposeLog) << "polyLeft.size() " << polyLeft.size() << " polyRight.size() " << polyRight.size() << " out of " << polygon.size();
// qCDebug(PolygonDecomposeLog) << "vertex " << *vertex << " vertexOther " << *vertexOther << " vertexAfter " << *vertexAfter << " vertexBefore " << *vertexBefore;
// qCDebug(SurveyComplexItemLog) << "changing decomposedPolygonsMin";
}
}
else
{
else
{
qCDebug
(
SurveyComplexItemLog
)
<<
"NOT changing decomposedPolygonsMin"
;
//
qCDebug(SurveyComplexItemLog) << "NOT changing decomposedPolygonsMin";
}
}
}
}
...
@@ -1195,23 +1250,71 @@ void SurveyComplexItem::_PolygonDecomposeConvex(const QPolygonF& polygon, QList<
...
@@ -1195,23 +1250,71 @@ void SurveyComplexItem::_PolygonDecomposeConvex(const QPolygonF& polygon, QList<
// assemble output
// assemble output
if
(
decomposedPolygonsMin
.
size
()
>
0
)
{
if
(
decomposedPolygonsMin
.
size
()
>
0
)
{
qCDebug
(
SurveyComplexItemLog
)
<<
"use decomposed polygon, decomposedPolygonsMin.size() "
<<
decomposedPolygonsMin
.
size
();
//
qCDebug(SurveyComplexItemLog) << "use decomposed polygon, decomposedPolygonsMin.size() " << decomposedPolygonsMin.size();
decomposedPolygons
<<
decomposedPolygonsMin
;
decomposedPolygons
<<
decomposedPolygonsMin
;
// qCDebug(PolygonDecomposeLog) << decomposedPolygonsMin;
}
else
{
}
else
{
qCDebug
(
SurveyComplexItemLog
)
<<
"use default polygon"
;
//
qCDebug(SurveyComplexItemLog) << "use default polygon";
decomposedPolygons
<<
polygon
;
decomposedPolygons
<<
polygon
;
// qCDebug(PolygonDecomposeLog) << polygon << " empty polygon";
}
}
return
;
}
}
bool
SurveyComplexItem
::
_VertexCanSeeOther
(
const
QPolygonF
&
polygon
,
const
QPointF
*
VertexA
,
const
QPointF
*
VertexB
)
{
bool
SurveyComplexItem
::
_VertexCanSeeOther
(
const
QPolygonF
&
polygon
,
const
QPointF
*
vertexA
,
const
QPointF
*
vertexB
)
{
if
(
VertexA
==
VertexB
)
return
false
;
if
(
vertexA
==
vertexB
)
return
false
;
if
(
VertexA
+
1
==
VertexB
)
return
false
;
auto
vertexAAfter
=
vertexA
+
1
==
polygon
.
end
()
?
polygon
.
begin
()
:
vertexA
+
1
;
if
(
VertexA
-
1
==
VertexB
)
return
false
;
auto
vertexABefore
=
vertexA
==
polygon
.
begin
()
?
polygon
.
end
()
-
1
:
vertexA
-
1
;
if
(
vertexAAfter
==
vertexB
)
return
false
;
if
(
vertexABefore
==
vertexB
)
return
false
;
// qCDebug(SurveyComplexItemLog) << "_VertexCanSeeOther false after first checks ";
bool
visible
=
true
;
// auto diff = *vertexA - *vertexB;
QLineF
lineAB
{
*
vertexA
,
*
vertexB
};
auto
distanceAB
=
lineAB
.
length
();
//sqrtf(diff.x() * diff.x() + diff.y()*diff.y());
// qCDebug(SurveyComplexItemLog) << "_VertexCanSeeOther distanceAB " << distanceAB;
for
(
auto
vertexC
=
polygon
.
begin
();
vertexC
!=
polygon
.
end
();
++
vertexC
)
{
if
(
vertexC
==
vertexA
)
continue
;
if
(
vertexC
==
vertexB
)
continue
;
auto
vertexD
=
vertexC
+
1
==
polygon
.
end
()
?
polygon
.
begin
()
:
vertexC
+
1
;
if
(
vertexD
==
vertexA
)
continue
;
if
(
vertexD
==
vertexB
)
continue
;
QLineF
lineCD
(
*
vertexC
,
*
vertexD
);
QPointF
intersection
{};
auto
intersects
=
lineAB
.
intersect
(
lineCD
,
&
intersection
);
if
(
intersects
==
QLineF
::
IntersectType
::
BoundedIntersection
)
{
// auto diffIntersection = *vertexA - intersection;
// auto distanceIntersection = sqrtf(diffIntersection.x() * diffIntersection.x() + diffIntersection.y()*diffIntersection.y());
// qCDebug(SurveyComplexItemLog) << "*vertexA " << *vertexA << "*vertexB " << *vertexB << " intersection " << intersection;
QLineF
lineIntersection
{
*
vertexA
,
intersection
};
auto
distanceIntersection
=
lineIntersection
.
length
();
//sqrtf(diff.x() * diff.x() + diff.y()*diff.y());
qCDebug
(
SurveyComplexItemLog
)
<<
"_VertexCanSeeOther distanceIntersection "
<<
distanceIntersection
;
if
(
distanceIntersection
<
distanceAB
)
{
visible
=
false
;
break
;
}
}
return
true
;
}
return
visible
;
}
}
void
SurveyComplexItem
::
_rebuildTranscetsFromPolygon
(
bool
refly
,
const
QPolygonF
&
polygon
,
const
QGeoCoordinate
&
tangentOrigin
)
bool
SurveyComplexItem
::
_VertexIsReflex
(
const
QPolygonF
&
polygon
,
const
QPointF
*
vertex
)
{
auto
vertexBefore
=
vertex
==
polygon
.
begin
()
?
polygon
.
end
()
-
1
:
vertex
-
1
;
auto
vertexAfter
=
vertex
==
polygon
.
end
()
-
1
?
polygon
.
begin
()
:
vertex
+
1
;
auto
area
=
(((
vertex
->
x
()
-
vertexBefore
->
x
())
*
(
vertexAfter
->
y
()
-
vertexBefore
->
y
()))
-
((
vertexAfter
->
x
()
-
vertexBefore
->
x
())
*
(
vertex
->
y
()
-
vertexBefore
->
y
())));
return
area
>
0
;
}
void
SurveyComplexItem
::
_rebuildTranscetsFromPolygon
(
bool
refly
,
const
QPolygonF
&
polygon
,
const
QGeoCoordinate
&
tangentOrigin
,
const
QPointF
*
const
transitionPoint
)
{
{
// Generate transects
// Generate transects
...
@@ -1282,9 +1385,19 @@ void SurveyComplexItem::_rebuildTranscetsFromPolygon(bool refly, const QPolygonF
...
@@ -1282,9 +1385,19 @@ void SurveyComplexItem::_rebuildTranscetsFromPolygon(bool refly, const QPolygonF
// Convert from NED to Geo
// Convert from NED to Geo
QList
<
QList
<
QGeoCoordinate
>>
transects
;
QList
<
QList
<
QGeoCoordinate
>>
transects
;
for
(
const
QLineF
&
line
:
resultLines
)
{
if
(
transitionPoint
!=
nullptr
)
{
QList
<
QGeoCoordinate
>
transect
;
QGeoCoordinate
coord
;
QGeoCoordinate
coord
;
convertNedToGeo
(
transitionPoint
->
y
(),
transitionPoint
->
x
(),
0
,
tangentOrigin
,
&
coord
);
transect
.
append
(
coord
);
transect
.
append
(
coord
);
//TODO
transects
.
append
(
transect
);
}
for
(
const
QLineF
&
line
:
resultLines
)
{
QList
<
QGeoCoordinate
>
transect
;
QList
<
QGeoCoordinate
>
transect
;
QGeoCoordinate
coord
;
convertNedToGeo
(
line
.
p1
().
y
(),
line
.
p1
().
x
(),
0
,
tangentOrigin
,
&
coord
);
convertNedToGeo
(
line
.
p1
().
y
(),
line
.
p1
().
x
(),
0
,
tangentOrigin
,
&
coord
);
transect
.
append
(
coord
);
transect
.
append
(
coord
);
...
...
src/MissionManager/SurveyComplexItem.h
View file @
9ae5cc7e
...
@@ -112,11 +112,12 @@ private:
...
@@ -112,11 +112,12 @@ private:
bool
_loadV4
(
const
QJsonObject
&
complexObject
,
int
sequenceNumber
,
QString
&
errorString
);
bool
_loadV4
(
const
QJsonObject
&
complexObject
,
int
sequenceNumber
,
QString
&
errorString
);
void
_rebuildTransectsPhase1Worker
(
bool
refly
);
void
_rebuildTransectsPhase1Worker
(
bool
refly
);
/// Adds to the _transects array from one polygon
/// Adds to the _transects array from one polygon
void
_rebuildTranscetsFromPolygon
(
bool
refly
,
const
QPolygonF
&
polygon
,
const
QGeoCoordinate
&
tangentOrigin
);
void
_rebuildTranscetsFromPolygon
(
bool
refly
,
const
QPolygonF
&
polygon
,
const
QGeoCoordinate
&
tangentOrigin
,
const
QPointF
*
const
transitionPoint
);
// Decompose polygon into list of convex sub polygons
// Decompose polygon into list of convex sub polygons
void
_PolygonDecomposeConvex
(
const
QPolygonF
&
polygon
,
QList
<
QPolygonF
>&
decomposedPolygons
);
void
_PolygonDecomposeConvex
(
const
QPolygonF
&
polygon
,
QList
<
QPolygonF
>&
decomposedPolygons
);
// return true if vertex a can see vertex b
// return true if vertex a can see vertex b
bool
_VertexCanSeeOther
(
const
QPolygonF
&
polygon
,
const
QPointF
*
VertexA
,
const
QPointF
*
VertexB
);
bool
_VertexCanSeeOther
(
const
QPolygonF
&
polygon
,
const
QPointF
*
vertexA
,
const
QPointF
*
vertexB
);
bool
_VertexIsReflex
(
const
QPolygonF
&
polygon
,
const
QPointF
*
vertex
);
QMap
<
QString
,
FactMetaData
*>
_metaDataMap
;
QMap
<
QString
,
FactMetaData
*>
_metaDataMap
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment