Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CityDoctor
CityDoctor2
Commits
1d8506eb
Commit
1d8506eb
authored
Aug 12, 2024
by
Riegel
Browse files
Extracted methods to reduce cognitive complexity. Ref
#69
parent
e284489e
Pipeline
#10052
passed with stage
in 1 minute and 16 seconds
Changes
1
Pipelines
1
Show whitespace changes
Inline
Side-by-side
CityDoctorParent/CityDoctorEdge/src/main/java/de/hft/stuttgart/citydoctor2/edge/IntersectPlanarPolygons.java
View file @
1d8506eb
...
@@ -82,6 +82,22 @@ public class IntersectPlanarPolygons {
...
@@ -82,6 +82,22 @@ public class IntersectPlanarPolygons {
for
(
Interval
in2
:
intervals2
)
{
for
(
Interval
in2
:
intervals2
)
{
if
(
in1
.
isOverlapping
(
in2
))
{
if
(
in1
.
isOverlapping
(
in2
))
{
Interval
overlap
=
in1
.
overlap
(
in2
);
Interval
overlap
=
in1
.
overlap
(
in2
);
handleIntersectionIntervalOverlap
(
cpPolygon1
,
cpPolygon2
,
straight
,
intersections
,
epsilon
,
overlap
);
}
else
if
(
Math
.
abs
(
in1
.
getStart
()
-
in2
.
getEnd
())
<
Global
.
getHighAccuracyTolerance
())
{
// check if the overlaps with a tolerance (numeric errors)
Point3d
point
=
straight
.
evaluate
(
in1
.
getStart
());
checkAndAddRealIntersectionPoint
(
cpPolygon1
,
cpPolygon2
,
point
,
intersections
,
epsilon
);
}
else
if
(
Math
.
abs
(
in1
.
getEnd
()
-
in2
.
getStart
())
<
Global
.
getHighAccuracyTolerance
())
{
Point3d
point
=
straight
.
evaluate
(
in1
.
getEnd
());
checkAndAddRealIntersectionPoint
(
cpPolygon1
,
cpPolygon2
,
point
,
intersections
,
epsilon
);
}
}
}
}
private
static
void
handleIntersectionIntervalOverlap
(
EdgePolygon
cpPolygon1
,
EdgePolygon
cpPolygon2
,
GmStraight
straight
,
List
<
PolygonPolygonIntersection
>
intersections
,
double
epsilon
,
Interval
overlap
)
{
Point3d
start
=
straight
.
evaluate
(
overlap
.
getStart
());
Point3d
start
=
straight
.
evaluate
(
overlap
.
getStart
());
if
(
overlap
.
getLength
()
<
Global
.
getHighAccuracyTolerance
()
*
1
e6
)
{
if
(
overlap
.
getLength
()
<
Global
.
getHighAccuracyTolerance
()
*
1
e6
)
{
checkAndAddRealIntersectionPoint
(
cpPolygon1
,
cpPolygon2
,
start
,
intersections
,
epsilon
);
checkAndAddRealIntersectionPoint
(
cpPolygon1
,
cpPolygon2
,
start
,
intersections
,
epsilon
);
...
@@ -96,16 +112,6 @@ public class IntersectPlanarPolygons {
...
@@ -96,16 +112,6 @@ public class IntersectPlanarPolygons {
}
}
}
}
}
else
if
(
Math
.
abs
(
in1
.
getStart
()
-
in2
.
getEnd
())
<
Global
.
getHighAccuracyTolerance
())
{
// check if the overlaps with a tolerance (numeric errors)
Point3d
point
=
straight
.
evaluate
(
in1
.
getStart
());
checkAndAddRealIntersectionPoint
(
cpPolygon1
,
cpPolygon2
,
point
,
intersections
,
epsilon
);
}
else
if
(
Math
.
abs
(
in1
.
getEnd
()
-
in2
.
getStart
())
<
Global
.
getHighAccuracyTolerance
())
{
Point3d
point
=
straight
.
evaluate
(
in1
.
getEnd
());
checkAndAddRealIntersectionPoint
(
cpPolygon1
,
cpPolygon2
,
point
,
intersections
,
epsilon
);
}
}
}
}
}
private
static
boolean
isPolyLineASharedEdge
(
EdgePolygon
p1
,
PolyLine
polyLine
)
{
private
static
boolean
isPolyLineASharedEdge
(
EdgePolygon
p1
,
PolyLine
polyLine
)
{
...
@@ -136,10 +142,12 @@ public class IntersectPlanarPolygons {
...
@@ -136,10 +142,12 @@ public class IntersectPlanarPolygons {
/**
/**
*
*
* Checks if the given point is a
"
real
"
intersection point and add
'
s it to the
* Checks if the given point is a
'
real
'
intersection point and adds it to the
* intersection segments member variable. Real mean
s
, that this point isn't
* intersection segments member variable.
'
Real
'
mean
ing
, that this point isn't
* shared
by both polygons as corner point
.
*
a
shared
corner point of both polygons
.
*
*
* @param p1 First polygon
* @param p2 Second polygon
* @param point A possible intersection point
* @param point A possible intersection point
*/
*/
private
static
void
checkAndAddRealIntersectionPoint
(
EdgePolygon
p1
,
EdgePolygon
p2
,
Point3d
point
,
private
static
void
checkAndAddRealIntersectionPoint
(
EdgePolygon
p1
,
EdgePolygon
p2
,
Point3d
point
,
...
@@ -200,7 +208,6 @@ public class IntersectPlanarPolygons {
...
@@ -200,7 +208,6 @@ public class IntersectPlanarPolygons {
* with the exception, that the straight and the half edges of the polygon will
* with the exception, that the straight and the half edges of the polygon will
* be projected on the plane of the polygon, so the calculation of the
* be projected on the plane of the polygon, so the calculation of the
* intersection will be reduced to a 2d problem.
* intersection will be reduced to a 2d problem.
*
* The intersection intervals contains pairs of parameters from the intersection
* The intersection intervals contains pairs of parameters from the intersection
* straight. If an intersection between the straight and the polygon contains
* straight. If an intersection between the straight and the polygon contains
* only a point, the according interval will contain the same parameter twice
* only a point, the according interval will contain the same parameter twice
...
@@ -271,6 +278,16 @@ public class IntersectPlanarPolygons {
...
@@ -271,6 +278,16 @@ public class IntersectPlanarPolygons {
GmBoundedStraight2d
heStraight2d
=
polyPlane
.
projectOn2dStraight
(
heStraight
);
GmBoundedStraight2d
heStraight2d
=
polyPlane
.
projectOn2dStraight
(
heStraight
);
GmStraight2dIntersectionResult
intersectionResult
=
heStraight2d
.
intersect
(
intersectingStraight2d
);
GmStraight2dIntersectionResult
intersectionResult
=
heStraight2d
.
intersect
(
intersectingStraight2d
);
analyseProjectedIntersection
(
intersectionResult
,
intersectingStraight2d
,
heStraight2d
,
intersectionValues
,
intersectedPolygonPoints
);
}
processIntersectionIntervals
(
p
,
intersectingStraight
,
intersectionValues
,
intersectedPolygonPoints
,
intersectionIntervals
);
return
intersectionIntervals
;
}
private
static
void
analyseProjectedIntersection
(
GmStraight2dIntersectionResult
intersectionResult
,
GmStraight2d
intersectingStraight2d
,
GmBoundedStraight2d
heStraight2d
,
TreeSet
<
Double
>
intersectionValues
,
TreeSet
<
Double
>
intersectedPolygonPoints
)
{
if
(
intersectionResult
.
areParallel
())
{
if
(
intersectionResult
.
areParallel
())
{
Vector2d
dir
=
intersectingStraight2d
.
getDirection
();
Vector2d
dir
=
intersectingStraight2d
.
getDirection
();
Vector2d
diffVec
=
heStraight2d
.
getOrigin
().
minus
(
intersectingStraight2d
.
getOrigin
());
Vector2d
diffVec
=
heStraight2d
.
getOrigin
().
minus
(
intersectingStraight2d
.
getOrigin
());
...
@@ -306,12 +323,6 @@ public class IntersectPlanarPolygons {
...
@@ -306,12 +323,6 @@ public class IntersectPlanarPolygons {
}
}
}
}
processIntersectionIntervals
(
p
,
intersectingStraight
,
intersectionValues
,
intersectedPolygonPoints
,
intersectionIntervals
);
return
intersectionIntervals
;
}
/**
/**
* This methods computes the intervals of the intersection between the given
* This methods computes the intervals of the intersection between the given
* straight and polygon. It gets only parameters where the straight hits the
* straight and polygon. It gets only parameters where the straight hits the
...
@@ -350,14 +361,35 @@ public class IntersectPlanarPolygons {
...
@@ -350,14 +361,35 @@ public class IntersectPlanarPolygons {
List
<
Double
>
valuesList
=
new
ArrayList
<>(
intersectionValues
);
List
<
Double
>
valuesList
=
new
ArrayList
<>(
intersectionValues
);
for
(
int
i
=
0
;
i
<
valuesList
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
valuesList
.
size
();
i
++)
{
double
i1
=
valuesList
.
get
(
i
);
double
i1
=
valuesList
.
get
(
i
);
i
=
i
+
1
;
i
nt
j
=
i
+
1
;
if
(
i
<
valuesList
.
size
())
{
if
(
j
<
valuesList
.
size
())
{
double
i2
=
valuesList
.
get
(
i
);
double
i2
=
valuesList
.
get
(
j
);
// check if the double values are corner points of the polygon
// check if the double values are corner points of the polygon
boolean
gotPolygonPoint
=
intersectedPolygonPoints
.
contains
(
i1
)
||
boolean
gotPolygonPoint
=
intersectedPolygonPoints
.
contains
(
i1
)
||
intersectedPolygonPoints
.
contains
(
i2
);
intersectedPolygonPoints
.
contains
(
i2
);
if
(
gotPolygonPoint
)
{
if
(
gotPolygonPoint
)
{
Interval
newLineInt
=
checkIntersectionInvervalPoints
(
pcPolygon
,
intersectingStraight
,
intersectionIntervals
,
i1
,
i2
);
if
(
newLineInt
!=
null
)
{
intersectionIntervals
.
add
(
newLineInt
);
}
}
else
{
intersectionIntervals
.
add
(
new
Interval
(
i1
,
i2
));
}
}
// it's possible, that 'it' equals 'endIt' at the end of the loop.
// this would lead to an increment of an iterator pointing to the end
// iterator. don't ask me why, but incrementing such an iterator
// is forbidden and you get an assertion.
if
(
i
>=
valuesList
.
size
())
{
break
;
}
}
}
private
static
Interval
checkIntersectionInvervalPoints
(
EdgePolygon
pcPolygon
,
GmStraight
intersectingStraight
,
List
<
Interval
>
intersectionIntervals
,
double
i1
,
double
i2
)
{
// maybe an interval
// maybe an interval
// check if the point between the two parameters is inside the
// check if the point between the two parameters is inside the
// polygon or outside ( i.e. i1 and i2 are both corner points of
// polygon or outside ( i.e. i1 and i2 are both corner points of
...
@@ -373,34 +405,19 @@ public class IntersectPlanarPolygons {
...
@@ -373,34 +405,19 @@ public class IntersectPlanarPolygons {
while
(
intervalIterator
.
hasNext
()
&&
!
intersectionIntervals
.
isEmpty
())
{
while
(
intervalIterator
.
hasNext
()
&&
!
intersectionIntervals
.
isEmpty
())
{
for
(
Interval
inter
=
intervalIterator
.
next
();
intervalIterator
for
(
Interval
inter
=
intervalIterator
.
next
();
intervalIterator
.
hasNext
();
inter
=
intervalIterator
.
next
())
{
.
hasNext
();
inter
=
intervalIterator
.
next
())
{
if
(
Math
.
abs
(
inter
.
getLength
())
<
Global
.
getHighAccuracyTolerance
())
{
if
(
Math
.
abs
(
inter
.
getLength
())
<
Global
.
getHighAccuracyTolerance
()
&&
if
(
Math
.
abs
(
inter
.
getStart
()
-
i1
)
<
1
e
-
9
(
Math
.
abs
(
inter
.
getStart
()
-
i1
)
<
1
e
-
9
||
Math
.
abs
(
inter
.
getStart
()
-
i2
)
<
1
e
-
9
))
{
||
Math
.
abs
(
inter
.
getStart
()
-
i2
)
<
1
e
-
9
)
{
intervalIterator
.
remove
();
intervalIterator
.
remove
();
intervalIterator
=
intersectionIntervals
.
iterator
();
intervalIterator
=
intersectionIntervals
.
iterator
();
break
;
break
;
}
}
}
}
}
intersectionIntervals
.
add
(
newLineInt
);
}
else
{
i
--;
}
}
else
{
intersectionIntervals
.
add
(
new
Interval
(
i1
,
i2
));
}
}
}
}
// it's possible, that 'it' equals 'endIt' at the end of the loop.
return
newLineInt
;
// this would lead to an increment of an iterator pointing to the end
// iterator. don't ask me why, but incrementing such an iterator
// is forbidden and you get an assertion.
if
(
i
>=
valuesList
.
size
())
{
break
;
}
}
}
return
null
;
}
}
/**
/**
...
@@ -442,46 +459,9 @@ public class IntersectPlanarPolygons {
...
@@ -442,46 +459,9 @@ public class IntersectPlanarPolygons {
List
<
HalfEdge
>
heList
=
new
ArrayList
<>(
p1
.
getHalfEdges
());
List
<
HalfEdge
>
heList
=
new
ArrayList
<>(
p1
.
getHalfEdges
());
heList
.
addAll
(
p2
.
getHalfEdges
());
heList
.
addAll
(
p2
.
getHalfEdges
());
List
<
HalfEdge
>
heListColinear
=
new
ArrayList
<>();
List
<
HalfEdge
>
heListCollinear
=
getCollinearHalfEdgeList
(
p1
,
p2
,
straight
,
epsilon
,
angleEpsilon
,
heList
);
for
(
HalfEdge
he
:
heList
)
{
if
(
null
!=
he
.
getPartner
())
{
// this half edge is shared by both polygons ==> no intersection
// NOTE: The issue of more than 2 half edges per edge is solved by
// circular pointer, so we have to cycle threw all partners
HalfEdge
pStartHE
=
he
;
HalfEdge
pPartnerHE
=
pStartHE
.
getPartner
();
boolean
bothPolysShareThisEdge
=
false
;
while
(
pStartHE
!=
pPartnerHE
&&
!
bothPolysShareThisEdge
)
{
if
(
pPartnerHE
.
getPolygon
()
==
p1
||
pPartnerHE
.
getPolygon
()
==
p2
)
{
bothPolysShareThisEdge
=
true
;
}
pPartnerHE
=
pPartnerHE
.
getPartner
();
}
if
(
bothPolysShareThisEdge
)
{
continue
;
}
}
GmBoundedStraight
straightHe
=
he
.
getStraight
();
Point3d
origin
=
straightHe
.
getOrigin
();
Point3d
target
=
straightHe
.
getTarget
();
boolean
straightsAreColinear
=
IntersectPlanarPolygons
.
areStraightsColinear
(
straightHe
,
straight
,
epsilon
,
for
(
HalfEdge
he
:
heListCollinear
)
{
angleEpsilon
);
ProjectedPoint3d
projPoint1
=
straight
.
project
(
origin
);
ProjectedPoint3d
projPoint2
=
straight
.
project
(
target
);
boolean
originLiesOnIntStraight
=
projPoint1
.
getPoint
().
isAlmostEqual
(
origin
,
PROJECTED_POINT_DISTANCE_EPSILON
);
boolean
targetLiesOnIntStraight
=
projPoint2
.
getPoint
().
isAlmostEqual
(
target
,
PROJECTED_POINT_DISTANCE_EPSILON
);
if
(
straightsAreColinear
&&
(
originLiesOnIntStraight
||
targetLiesOnIntStraight
))
{
heListColinear
.
add
(
he
);
}
}
for
(
HalfEdge
he
:
heListColinear
)
{
// 1.2) determine if fully or partially or not at all embedded
// 1.2) determine if fully or partially or not at all embedded
// create parameter interval of the first projected half edge
// create parameter interval of the first projected half edge
Point3d
startPoint1
=
he
.
getStraight
().
getOrigin
();
Point3d
startPoint1
=
he
.
getStraight
().
getOrigin
();
...
@@ -489,7 +469,7 @@ public class IntersectPlanarPolygons {
...
@@ -489,7 +469,7 @@ public class IntersectPlanarPolygons {
ProjectedPoint3d
projP1
=
straight
.
project
(
startPoint1
);
ProjectedPoint3d
projP1
=
straight
.
project
(
startPoint1
);
ProjectedPoint3d
projP2
=
straight
.
project
(
endPoint1
);
ProjectedPoint3d
projP2
=
straight
.
project
(
endPoint1
);
Interval
int1
=
new
Interval
(
projP1
.
getParameter
(),
projP2
.
getParameter
());
Interval
int1
=
new
Interval
(
projP1
.
getParameter
(),
projP2
.
getParameter
());
for
(
HalfEdge
he2
:
heListColinear
)
{
for
(
HalfEdge
he2
:
heListCol
l
inear
)
{
if
(
he
==
he2
)
{
if
(
he
==
he2
)
{
continue
;
continue
;
}
}
...
@@ -526,7 +506,62 @@ public class IntersectPlanarPolygons {
...
@@ -526,7 +506,62 @@ public class IntersectPlanarPolygons {
}
}
}
}
private
static
boolean
areStraightsColinear
(
GmBoundedStraight
straight1
,
GmStraight
straight2
,
double
epsilon
,
private
static
List
<
HalfEdge
>
getCollinearHalfEdgeList
(
EdgePolygon
p1
,
EdgePolygon
p2
,
GmStraight
straight
,
double
epsilon
,
double
angleEpsilon
,
List
<
HalfEdge
>
heList
)
{
List
<
HalfEdge
>
heListCollinear
=
new
ArrayList
<>();
for
(
HalfEdge
he
:
heList
)
{
if
(
isHalfEdgeSharedByPolygons
(
he
,
p1
,
p2
)){
// If the HalfEdge is shared, it is not collinear.
// Ignore it and continue with next HalfEdge.
continue
;
}
GmBoundedStraight
straightHe
=
he
.
getStraight
();
Point3d
origin
=
straightHe
.
getOrigin
();
Point3d
target
=
straightHe
.
getTarget
();
boolean
straightsAreCollinear
=
IntersectPlanarPolygons
.
areStraightsCollinear
(
straightHe
,
straight
,
epsilon
,
angleEpsilon
);
ProjectedPoint3d
projPoint1
=
straight
.
project
(
origin
);
ProjectedPoint3d
projPoint2
=
straight
.
project
(
target
);
boolean
originLiesOnIntStraight
=
projPoint1
.
getPoint
().
isAlmostEqual
(
origin
,
PROJECTED_POINT_DISTANCE_EPSILON
);
boolean
targetLiesOnIntStraight
=
projPoint2
.
getPoint
().
isAlmostEqual
(
target
,
PROJECTED_POINT_DISTANCE_EPSILON
);
if
(
straightsAreCollinear
&&
(
originLiesOnIntStraight
||
targetLiesOnIntStraight
))
{
heListCollinear
.
add
(
he
);
}
}
return
heListCollinear
;
}
/**
* Checks whether a specific HalfEdge is shared by two EdgePolygons.
*
*
* @param he The HalfEdge in question
* @param p1 First Polygon
* @param p2 Second Polygon
* @return true if the HalfEdge is shared
*/
private
static
boolean
isHalfEdgeSharedByPolygons
(
HalfEdge
he
,
EdgePolygon
p1
,
EdgePolygon
p2
)
{
boolean
bothPolysShareThisEdge
=
false
;
if
(
he
.
getPartner
()
!=
null
)
{
// NOTE: The issue of more than 2 half edges per edge is solved by
// circular pointer, so we have to cycle threw all partners
HalfEdge
pPartnerHE
=
he
.
getPartner
();
while
(
he
!=
pPartnerHE
&&
!
bothPolysShareThisEdge
)
{
if
(
pPartnerHE
.
getPolygon
()
==
p1
||
pPartnerHE
.
getPolygon
()
==
p2
)
{
bothPolysShareThisEdge
=
true
;
}
pPartnerHE
=
pPartnerHE
.
getPartner
();
}
}
return
bothPolysShareThisEdge
;
}
private
static
boolean
areStraightsCollinear
(
GmBoundedStraight
straight1
,
GmStraight
straight2
,
double
epsilon
,
double
angleEpsilon
)
{
double
angleEpsilon
)
{
UnitVector3d
rDir1
=
straight1
.
getDir
();
UnitVector3d
rDir1
=
straight1
.
getDir
();
...
@@ -541,11 +576,8 @@ public class IntersectPlanarPolygons {
...
@@ -541,11 +576,8 @@ public class IntersectPlanarPolygons {
ProjectedPoint3d
foot1
=
straight2
.
project
(
rOrigin
);
ProjectedPoint3d
foot1
=
straight2
.
project
(
rOrigin
);
Point3d
rTarget
=
straight1
.
getTarget
();
Point3d
rTarget
=
straight1
.
getTarget
();
ProjectedPoint3d
foot2
=
straight2
.
project
(
rTarget
);
ProjectedPoint3d
foot2
=
straight2
.
project
(
rTarget
);
if
((
foot1
.
getPoint
().
minus
(
rOrigin
)).
getLength
()
>
epsilon
return
!(((
foot1
.
getPoint
().
minus
(
rOrigin
)).
getLength
()
>
epsilon
)
||
(
foot2
.
getPoint
().
minus
(
rTarget
)).
getLength
()
>
epsilon
)
{
||
((
foot2
.
getPoint
().
minus
(
rTarget
)).
getLength
()
>
epsilon
));
return
false
;
}
return
true
;
}
}
private
static
List
<
PolygonPolygonIntersection
>
handlePolygonsInSamePlane
(
GmPlane
plane
,
EdgePolygon
p1
,
private
static
List
<
PolygonPolygonIntersection
>
handlePolygonsInSamePlane
(
GmPlane
plane
,
EdgePolygon
p1
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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