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
c6f23035
Commit
c6f23035
authored
Jul 08, 2026
by
Numanoglu
Browse files
sketchs and notes sweep
parent
3032c1f9
Changes
11
Show whitespace changes
Inline
Side-by-side
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/CoEdge.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
de.hft.stuttgart.citydoctor2.datastructure.Edge
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
/**
* Gerichtetes Vorkommen einer Kante in genau einem Ring.
* * C++-Semantik: `CoEdge ist nicht die Kante selbst, sondern die Kante
* innerhalb eines konkreten `Loop.
* Dadurch kann dieselbe geometrische Kante in zwei Flächen vorkommen,
* mit entgegengesetzter Richtung und mit je eigenen Vorgänger-/Nachfolgerbeziehungen.
* wir könnten diese Klasse als Sweep-Arbeitsobjekt verwenden:
* * - `edge: die aus CityDoctor abgeleitete Kante.
* * - `polygon/ring: das konkrete Ringvorkommen.
* * - `start/end: Richtung dieser CoEdge im Ring.
* * - `previous/next: lokale Ringverkettung.
* * - `partner: CoEdge derselben Kante in der Nachbarfläche.* */
public
class
CoEdge
{
private
Edge
edge
;
private
Polygon
polygon
;
private
LinearRing
ring
;
private
Vertex
start
;
private
Vertex
end
;
private
CoEdge
previous
;
private
CoEdge
next
;
private
CoEdge
partner
;
public
CoEdge
(
Edge
edge
,
Polygon
polygon
,
LinearRing
ring
,
Vertex
start
,
Vertex
end
)
{
this
.
edge
=
edge
;
this
.
polygon
=
polygon
;
this
.
ring
=
ring
;
this
.
start
=
start
;
this
.
end
=
end
;
}
public
Edge
getEdge
()
{
return
edge
;
}
public
Polygon
getPolygon
()
{
return
polygon
;
}
public
LinearRing
getRing
()
{
return
ring
;
}
public
Vertex
getStart
()
{
return
start
;
}
public
Vertex
getEnd
()
{
return
end
;
}
public
CoEdge
getPrevious
()
{
return
previous
;
}
public
void
setPrevious
(
CoEdge
previous
)
{
this
.
previous
=
previous
;
}
public
CoEdge
getNext
()
{
return
next
;
}
public
void
setNext
(
CoEdge
next
)
{
this
.
next
=
next
;
}
public
CoEdge
getPartner
()
{
return
partner
;
}
public
void
setPartner
(
CoEdge
partner
)
{
this
.
partner
=
partner
;
}
/**
* Platzhalter für spätere Topologieänderungen, wenn eine CoEdge nach einem
* Vertex-Split auf eine neue Kante oder neue Vertex-Kopie zeigen muss.
*/
void
reset
(
Edge
edge
,
Vertex
start
,
Vertex
end
)
{
this
.
edge
=
edge
;
this
.
start
=
start
;
this
.
end
=
end
;
}
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/CoEdgeRing.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
java.util.ArrayList
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
/**
* Arbeitsrepräsentation eines LinearRing als Folge gerichteter CoEdges.
*
* In CityDoctor ist der Ring eine Vertexliste.
* Für Fall 3 des Sweeps müssen wir aber wissen,
* welche gerichtete Kante vor und nach einem Vertex liegt.
*
* Darum bildet diese Klasse die C++-Loop-Idee ab, ohne das CityDoctor-Datenmodell
* dauerhaft zu ersetzen.
*/
public
class
CoEdgeRing
{
private
final
Polygon
polygon
;
private
final
LinearRing
ring
;
private
final
List
<
CoEdge
>
coEdges
=
new
ArrayList
<>();
public
CoEdgeRing
(
Polygon
polygon
,
LinearRing
ring
)
{
this
.
polygon
=
polygon
;
this
.
ring
=
ring
;
}
public
Polygon
getPolygon
()
{
return
polygon
;
}
public
LinearRing
getRing
()
{
return
ring
;
}
public
List
<
CoEdge
>
getCoEdges
()
{
return
coEdges
;
}
/**
* Später: CoEdge 'vor' und 'nach' einem Vertex finden. in C++-Vgl:
* findPrevAndNextCoEdge(...).
*/
public
List
<
CoEdge
>
findCoEdgesAtVertex
()
{
// TODO Parameter Vertex ergänzen, sobald die erste Fall-3-Operation gebaut wird.
return
List
.
of
();
}
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/OutgoingEdgeFinder.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
java.util.ArrayList
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.datastructure.Edge
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
/**
* Findet die abführenden Kanten eines Sweep-Punktes.
*
* C++-Vorbild ist getOtherEdges(vertex, face) aus BRepObject_Navigate. Dort
* bedeutet "other edge": Kante hängt am Vertex, ist aber nicht Teil der
* Sweep-Fläche.
*
* In Java sind Kanten aus den LinearRing-Punktlisten abgeleitete Metadaten.
* Darum nutzt diese Klasse die vorhandenen Methoden Geometry.getEdgesAdjacentTo
* und Edge.getAdjacentPolygons statt eine eigene Kantenliste dauerhaft zu
* speichern.
*/
public
class
OutgoingEdgeFinder
{
/**
* Liefert alle Kanten, die am Vertex liegen, aber nicht zum Fehlerpolygon
* gehören.
*/
public
List
<
Edge
>
findOutgoingEdges
(
Geometry
geometry
,
Polygon
sweepPolygon
,
Vertex
vertex
)
{
List
<
Edge
>
outgoing
=
new
ArrayList
<>();
if
(
geometry
==
null
||
sweepPolygon
==
null
||
vertex
==
null
||
geometry
.
getEdges
()
==
null
)
{
return
outgoing
;
}
for
(
Edge
edge
:
geometry
.
getEdgesAdjacentTo
(
vertex
))
{
if
(!
edge
.
getAdjacentPolygons
().
contains
(
sweepPolygon
))
{
outgoing
.
add
(
edge
);
}
}
return
outgoing
;
}
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/PlanarPolygonSweeper.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
de.hft.stuttgart.citydoctor2.check.error.NonPlanarPolygonDistancePlaneError
;
/**
* Orchestriert den Punkt-Sweep für ein nicht-planares Polygon.
*
* Diese Klasse soll später aus HealPlanarPolygonSweep aufgerufen werden. Sie ist
* bewusst nicht selbst der HealingMethod-Einstieg, damit die fachliche
* Sweep-Algorithmik getrennt von CityDoctor-Fehlerdispatch, Logging und
* Listener-Anbindung bleibt.
*
* Semantische Vorlage ist Piepereit Kapitel 7.2.3 sowie der C++-Code in
* HealingMethod_Planarity::sweepFace(...) beziehungsweise
* Method_AdvancedSweep::sweepFace(...).
*
* Geplanter Ablauf:
* - Zielebene für das Fehlerpolygon bestimmen.
* - Alle Punkte der Sweep-Fläche betrachten.
* - Punkte, die schon in der Zielebene liegen, überspringen.
* - Abführende Kanten bestimmen.
* - Fall 1: keine abführende Kante, orthogonal projizieren.
* - Fall 2: eine abführende Kante, entlang der Kante zur Zielebene sweepen.
* - Fall 3: mehrere abführende Kanten, Vertex topologisch aufteilen. -->3.1, 3.2, 3.3
*/
public
class
PlanarPolygonSweeper
{
private
final
SweepTargetPlaneFactory
targetPlaneFactory
;
private
final
OutgoingEdgeFinder
outgoingEdgeFinder
;
private
final
SweepPointOperation
pointOperation
;
private
final
SweepDirectionClassifier
directionClassifier
;
private
final
TopologyEditor
topologyEditor
;
public
PlanarPolygonSweeper
()
{
this
(
new
SweepTargetPlaneFactory
(),
new
OutgoingEdgeFinder
(),
new
SweepPointOperation
(),
new
SweepDirectionClassifier
(),
new
TopologyEditor
());
}
PlanarPolygonSweeper
(
SweepTargetPlaneFactory
targetPlaneFactory
,
OutgoingEdgeFinder
outgoingEdgeFinder
,
SweepPointOperation
pointOperation
,
SweepDirectionClassifier
directionClassifier
,
TopologyEditor
topologyEditor
)
{
this
.
targetPlaneFactory
=
targetPlaneFactory
;
this
.
outgoingEdgeFinder
=
outgoingEdgeFinder
;
this
.
pointOperation
=
pointOperation
;
this
.
directionClassifier
=
directionClassifier
;
this
.
topologyEditor
=
topologyEditor
;
}
/**
* Platzhalter für die spätere Portierung.
*
* Hier sollen die Fälle aus Piepereit 7.2.3 dispatcht werden. Der aktuelle
* Methodenrumpf macht noch nichts, damit wir die Architektur gefahrlos
* einführen können.
*/
public
boolean
sweep
(
NonPlanarPolygonDistancePlaneError
error
)
{
// TODO Sweep-Portierung:
// Plane targetPlane = targetPlaneFactory.createFor(error.getPolygon());
// for (Vertex vertex : sweepTopology.verticesOf(error.getPolygon())) { ... }
// List<Edge> outgoing = outgoingEdgeFinder.findOutgoingEdges(geometry, polygon, vertex);
// switch (outgoing.size()) { case 0 -> Fall 1; case 1 -> Fall 2; default -> Fall 3; }
return
false
;
}
SweepTargetPlaneFactory
getTargetPlaneFactory
()
{
return
targetPlaneFactory
;
}
OutgoingEdgeFinder
getOutgoingEdgeFinder
()
{
return
outgoingEdgeFinder
;
}
SweepPointOperation
getPointOperation
()
{
return
pointOperation
;
}
SweepDirectionClassifier
getDirectionClassifier
()
{
return
directionClassifier
;
}
TopologyEditor
getTopologyEditor
()
{
return
topologyEditor
;
}
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/PlaneIntersections.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
java.util.Optional
;
import
de.hft.stuttgart.citydoctor2.math.Line3d
;
import
de.hft.stuttgart.citydoctor2.math.Plane
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
/**
* Mathematische Schnittoperationen
*
* In cpp verwendet er dafür freie Funktionen aus mathutils.h, vor allem
* plane_str_int(...) für Ebene-Gerade und plane_plane_int(...) für Ebene-Ebene.
*
* Im Java-Projekt existiert bisher Plane.intersects(Segment3d),
* also nur Segment-Ebene.
*
* Diese Klasse ist vorläuf. im Sweep-Paket, weil sie aus der Portierung heraus
* entsteht. Wenn sie sich bewährt, kann die Funktionalität nach citydoctor2.math
* wandern.
*/
public
final
class
PlaneIntersections
{
private
static
final
double
EPSILON
=
0.0000001
;
private
PlaneIntersections
()
{
}
/**
* Schnitt einer unendlichen Gerade mit einer Ebene.
*
* Formel für Gerade p + t*d und Ebene n*x = D:
* t = (D - n*p) / (n*d).
*
*
* Vorläuf. mit Container'Optional' aus java.utils
*/
public
static
Optional
<
Vector3d
>
intersectLine
(
Plane
plane
,
Line3d
line
)
{
double
denominator
=
plane
.
getNormal
().
dot
(
line
.
direction
());
if
(
Math
.
abs
(
denominator
)
<
EPSILON
)
{
return
Optional
.
empty
();
}
double
t
=
(
plane
.
getD
()
-
plane
.
getNormal
().
dot
(
line
.
point
()))
/
denominator
;
return
Optional
.
of
(
line
.
point
().
plus
(
line
.
direction
().
mult
(
t
)));
}
/**
* Schnitt zweier Ebenen als Gerade.
*
* Wird später für Fall 3.2 benötigt: die neue Kante liegt auf der
* Schnittgeraden der zwei Nachbarflächen zur Sweep-Fläche.
*/
public
static
Optional
<
Line3d
>
intersectPlanes
(
Plane
first
,
Plane
second
)
{
// TODO plane_plane_int aus C++ semantisch nachbauen.
// Richtung wäre n1 x n2; ein Punkt auf der Gerade muss (num. robust!) berechnet werden.
return
Optional
.
empty
();
}
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/SweepDirection.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
/**
* Sweep-Richtung einer abführenden Kante bezogen auf die Zielebene.
*
* Die Benennung folgt Piepereit:
* - NEGATIVE: Kante wird beim Sweep verkürzt und kann kollabieren.
* - POSITIVE: Kante wird beim Sweep verlängert.
* - UNDEFINED: Sonderfall, etwa parallele Gerade zur Zielebene.
*/
public
enum
SweepDirection
{
NEGATIVE
,
POSITIVE
,
UNDEFINED
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/SweepDirectionClassifier.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
java.util.EnumMap
;
import
java.util.List
;
import
java.util.Map
;
import
de.hft.stuttgart.citydoctor2.datastructure.Edge
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
import
de.hft.stuttgart.citydoctor2.math.Line3d
;
import
de.hft.stuttgart.citydoctor2.math.Plane
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
/**
* Klassifiziert abführende Kanten in positive und negative Sweep-Richtung.
*
* C++-Vorbild ist getVertexComplexity(...). Dort wird pro abführender Kante die
* Trägergerade mit der Zielebene geschnitten. Dann wird verglichen:
*
* dist1 = Abstand(otherVertex, Schnittpunkt)
* dist2 = Abstand(otherVertex, alter Sweep-Punkt)
*
* Wenn dist1 kleiner als dist2 ist, hat die Kante negative Richtung und wird
* verkürzt. Sonst hat sie positive Richtung und wird verlängert.
*
* Aus den Zählungen entstehen später die Fälle:
* - nur negative Kanten: Split-Cut, Punkt vervielfältigen.
* - mindestens zwei positive Kanten: Split-Pull, Punkt duplizieren.
* - gemischt: erst trennen, dann rekursiv weiterbehandeln.
*/
public
class
SweepDirectionClassifier
{
public
SweepDirection
classify
(
Vertex
sweepVertex
,
Edge
outgoingEdge
,
Plane
targetPlane
)
{
if
(
sweepVertex
==
null
||
outgoingEdge
==
null
||
targetPlane
==
null
)
{
return
SweepDirection
.
UNDEFINED
;
}
Vertex
otherVertex
=
outgoingEdge
.
getOppositeVertex
(
sweepVertex
);
if
(
otherVertex
==
null
)
{
return
SweepDirection
.
UNDEFINED
;
}
Line3d
carrierLine
=
new
Line3d
(
sweepVertex
,
otherVertex
.
minus
(
sweepVertex
));
return
PlaneIntersections
.
intersectLine
(
targetPlane
,
carrierLine
)
.
map
(
intersection
->
classifyByDistance
(
sweepVertex
,
otherVertex
,
intersection
))
.
orElse
(
SweepDirection
.
UNDEFINED
);
}
public
Map
<
SweepDirection
,
Integer
>
countDirections
(
Vertex
sweepVertex
,
List
<
Edge
>
outgoingEdges
,
Plane
targetPlane
)
{
Map
<
SweepDirection
,
Integer
>
result
=
new
EnumMap
<>(
SweepDirection
.
class
);
for
(
SweepDirection
direction
:
SweepDirection
.
values
())
{
result
.
put
(
direction
,
0
);
}
for
(
Edge
edge
:
outgoingEdges
)
{
SweepDirection
direction
=
classify
(
sweepVertex
,
edge
,
targetPlane
);
result
.
put
(
direction
,
result
.
get
(
direction
)
+
1
);
}
return
result
;
}
private
SweepDirection
classifyByDistance
(
Vertex
sweepVertex
,
Vertex
otherVertex
,
Vector3d
intersection
)
{
double
distToIntersection
=
otherVertex
.
getDistance
(
intersection
);
double
distToCurrentPoint
=
otherVertex
.
getDistance
(
sweepVertex
);
if
(
distToIntersection
<
distToCurrentPoint
)
{
return
SweepDirection
.
NEGATIVE
;
}
return
SweepDirection
.
POSITIVE
;
}
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/SweepPointOperation.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
java.util.Optional
;
import
de.hft.stuttgart.citydoctor2.datastructure.Edge
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
import
de.hft.stuttgart.citydoctor2.math.Line3d
;
import
de.hft.stuttgart.citydoctor2.math.Plane
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
/**
* *
* Verschiebt einzelne Punkte gemäß Raul Fall 1 und Fall 2.
*
* PS könnte nach HealPlanarPolygonSweep verlegt werden
*
* Diese Klasse enthält bewusst nur Punktbewegung, keine Topologieänderung. Fall
* 3 wird später durch TopologyEditor vorbereitet und danach wieder auf Fall 2
* zurückgeführt.
*/
public
class
SweepPointOperation
{
/**
* Fall 1: Der Punkt besitzt keine abführende Kante und wird orthogonal auf die
* Zielebene projiziert.
*/
public
void
projectOrthogonal
(
Vertex
vertex
,
Plane
targetPlane
)
{
Vector3d
projected
=
targetPlane
.
projectPointToPlane
(
vertex
);
move
(
vertex
,
projected
);
}
/**
* Fall 2: Der Punkt besitzt genau eine abführende Kante. Die neue Position ist
* der Schnittpunkt aus Zielebene und Trägergerade dieser Kante.
*/
public
boolean
sweepAlongEdge
(
Vertex
vertex
,
Edge
outgoingEdge
,
Plane
targetPlane
)
{
Vertex
otherVertex
=
outgoingEdge
.
getOppositeVertex
(
vertex
);
if
(
otherVertex
==
null
)
{
return
false
;
}
Line3d
carrierLine
=
new
Line3d
(
vertex
,
otherVertex
.
minus
(
vertex
));
Optional
<
Vector3d
>
intersection
=
PlaneIntersections
.
intersectLine
(
targetPlane
,
carrierLine
);
// aktuell noch dummy
intersection
.
ifPresent
(
point
->
move
(
vertex
,
point
));
return
intersection
.
isPresent
();
}
private
void
move
(
Vertex
vertex
,
Vector3d
point
)
{
vertex
.
setX
(
point
.
getX
());
vertex
.
setY
(
point
.
getY
());
vertex
.
setZ
(
point
.
getZ
());
}
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/SweepTargetPlaneFactory.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.math.Plane
;
/**
* Erzeugt die Zielebene für den Planaritäts-Sweep.
*
* Später kann hier Rauls-Sonderlogik aus cpp: createTargetPlane_planarity(...)
* ergänzt werden:
* - keine komplexen Punkte (nicht mehr als eine abführ. Kante): Regressionsebene über alle Punkte.
* - ein komplexer Punkt: Ebene mit alter Normalenrichtung durch diesen Punkt.
* - zwei komplexe Punkte: Ebene durch beide Punkte, möglichst nahe an alter Ebene.
* - drei oder mehr komplexe Punkte: Ebene durch beziehungsweise über diese Punkte.
*
* Für den ersten Portierungsschritt reicht die vorhandene CityDoctor-Logik
* Plane.of(Polygon): eine orthogonale Regressionsebene über alle Punkte des
* Polygons, ( wahrschein. inklusive innerer Ringe.)
*
*/
public
class
SweepTargetPlaneFactory
{
/**
* Startvariante: vorhandene Regressionsebene des Projekts verwenden.
*/
public
Plane
createFor
(
Polygon
polygon
)
{
return
Plane
.
of
(
polygon
);
}
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/SweepTopology.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
java.util.ArrayList
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
/**
* Temporäre Topologiesicht auf eine CityDoctor-Geometry.
*
* Motiv:
* CityDoctor speichert Topologie primär über Polygon, LinearRing und Vertex.
* Die Klasse Edge wird daraus neu aufgebaut.
*
* Der C++-Code arbeitet dagegen mit einer
* expliziten BRep-Topologie aus Face, Loop, CoEdge, Edge und Vertex.
*
* Diese Klasse könnte später anhand der vorhandenen Ringen gerichtete CoEdge und
* CoEdgeRing-Objekte(temp.Loop á la CityDoctor) erzeugen.
*
* Sie ist dann Arbeitsmodell für den Sweep, nicht dauerhaftes Datenmodell des Projekts.
*/
public
class
SweepTopology
{
private
final
Geometry
geometry
;
private
final
List
<
CoEdgeRing
>
rings
=
new
ArrayList
<>();
public
SweepTopology
(
Geometry
geometry
)
{
this
.
geometry
=
geometry
;
}
public
Geometry
getGeometry
()
{
return
geometry
;
}
public
List
<
CoEdgeRing
>
getRings
()
{
return
rings
;
}
/**
* Späterer Builder-Schritt: aus allen Polygonringen gerichtete CoEdges
* erzeugen und Partner über gemeinsame Kanten bestimmen.
*/
public
void
rebuild
()
{
rings
.
clear
();
if
(
geometry
==
null
||
geometry
.
getPolygons
()
==
null
)
{
return
;
}
for
(
Polygon
polygon
:
geometry
.
getPolygons
())
{
addRing
(
polygon
,
polygon
.
getExteriorRing
());
for
(
LinearRing
innerRing
:
polygon
.
getInnerRings
())
{
addRing
(
polygon
,
innerRing
);
}
}
// TODO Partnerbeziehungen zwischen CoEdges ergänzen.
}
private
void
addRing
(
Polygon
polygon
,
LinearRing
ring
)
{
if
(
ring
!=
null
)
{
rings
.
add
(
new
CoEdgeRing
(
polygon
,
ring
));
}
}
}
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healing/sweep/TopologyEditor.java
0 → 100644
View file @
c6f23035
package
de.hft.stuttgart.citydoctor2.healing.sweep
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.datastructure.Edge
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
/**
* Führt spätere Topologieänderungen für Fall 3 aus.
*
* C++-Vorbild:
* - splitVertexCut(...) für mehrere negative abführende Kanten.
* - splitVertexPull(...) für mehrere positive abführende Kanten.
*
* In Java sollen diese Operationen nicht direkt in Geometry landen, weil sie
* sehr spezifisch für den Sweep sind. Geometry soll weiterhin allgemeines
* Datenmodell bleiben; der Editor übersetzt Sweep-Entscheidungen in konkrete
* Ringänderungen.
*/
public
class
TopologyEditor
{
/**
* Fall 3.1: alle abführenden Kanten sind negativ. Der Punkt wird in mehrere
* Punkte aufgeteilt, Kanten werden je einer Kopie zugeordnet und neue
* Verbindungskanten werden in die betroffenen Ringe eingefügt.
*/
public
List
<
Vertex
>
splitForNegativeOutgoingEdges
(
Geometry
geometry
,
Polygon
sweepPolygon
,
Vertex
vertex
,
List
<
Edge
>
outgoingEdges
)
{
// TODO Entspricht grob C++ splitVertexCut(...).
// Danach kann jeder neue Punkt über Fall 2 entlang genau einer Kante gesweept werden.
return
List
.
of
(
vertex
);
}
/**
* Fall 3.2: alle abführenden Kanten sind positiv. Es entsteht eine neue Kante
* entlang der Schnittgeraden der beiden Nachbarflächen; Originalpunkt bleibt,
* Duplikat wird gesweept.
*/
public
Vertex
splitForPositiveOutgoingEdges
(
Geometry
geometry
,
Polygon
sweepPolygon
,
Vertex
vertex
,
List
<
Edge
>
outgoingEdges
)
{
// TODO Entspricht grob C++ splitVertexPull(...).
return
vertex
;
}
/**
* Fall 3.3: gemischte positive und negative Kanten. Zuerst werden die
* Kantengruppen auf Original und Duplikat verteilt; anschließend werden die
* Teilprobleme wieder wie Fall 3.1, 3.2 oder Fall 2 behandelt.
*/
public
Vertex
splitForMixedOutgoingEdges
(
Geometry
geometry
,
Polygon
sweepPolygon
,
Vertex
vertex
,
List
<
Edge
>
positiveEdges
,
List
<
Edge
>
negativeEdges
)
{
// TODO Rauls Dissert. Fall 3.3.
return
vertex
;
}
}
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