Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
9.2.2023: Due to updates GitLab will be unavailable for some minutes between 9:00 and 11:00.
Open sidebar
vadere
vadere
Commits
1d6c7133
Commit
1d6c7133
authored
Jul 02, 2019
by
Benedikt Zoennchen
Browse files
finish new property data structure supported by fastutil.
parent
7ac00df9
Changes
9
Hide whitespace changes
Inline
Side-by-side
VadereMeshing/src/org/vadere/meshing/mesh/gen/AMesh.java
View file @
1d6c7133
package
org.vadere.meshing.mesh.gen
;
import
it.unimi.dsi.fastutil.booleans.BooleanArrayList
;
import
it.unimi.dsi.fastutil.doubles.DoubleArrayList
;
import
it.unimi.dsi.fastutil.ints.IntArrayList
;
import
it.unimi.dsi.fastutil.objects.ObjectArrayList
;
...
...
@@ -38,12 +39,17 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
private
AFace
boundary
;
private
List
<
AHalfEdge
>
edges
;
private
List
<
AVertex
>
vertices
;
//TODO: test the new property structure!
private
Map
<
String
,
AObjectArrayList
<?>>
verticesData
;
private
Map
<
String
,
AObjectArrayList
<?>>
halfEdgesData
;
private
Map
<
String
,
AObjectArrayList
<?>>
facesData
;
private
Map
<
String
,
DoubleArrayList
>
verticesDoubleData
;
private
Map
<
String
,
DoubleArrayList
>
facesDoubleData
;
private
Map
<
String
,
DoubleArrayList
>
halfEdgesDoubleData
;
private
Map
<
String
,
BooleanArrayList
>
verticesBooleanData
;
private
Map
<
String
,
BooleanArrayList
>
facesBooleanData
;
private
Map
<
String
,
BooleanArrayList
>
halfEdgesBooleanData
;
public
AMesh
()
{
clear
();
...
...
@@ -61,12 +67,18 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
this
.
numberOfEdges
=
0
;
this
.
numberOfVertices
=
0
;
this
.
numberOfHoles
=
0
;
this
.
verticesData
=
new
HashMap
<>();
this
.
halfEdgesData
=
new
HashMap
<>();
this
.
facesData
=
new
HashMap
<>();
this
.
verticesDoubleData
=
new
HashMap
<>();
this
.
halfEdgesData
=
new
HashMap
<>();
this
.
facesDoubleData
=
new
HashMap
<>();
this
.
verticesBooleanData
=
new
HashMap
<>();
this
.
halfEdgesBooleanData
=
new
HashMap
<>();
this
.
facesBooleanData
=
new
HashMap
<>();
}
@Override
...
...
@@ -223,6 +235,72 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
dataArray
.
set
(
face
.
getId
(),
data
);
}
@Override
public
void
setDoubleData
(
@NotNull
final
AFace
face
,
@NotNull
final
String
name
,
final
double
data
)
{
if
(!
facesDoubleData
.
containsKey
(
name
))
{
DoubleArrayList
dataArray
=
new
DoubleArrayList
(
faces
.
size
());
facesDoubleData
.
put
(
name
,
dataArray
);
}
DoubleArrayList
dataArray
=
facesDoubleData
.
get
(
name
);
assert
dataArray
.
size
()
==
faces
.
size
();
dataArray
.
set
(
face
.
getId
(),
data
);
}
@Override
public
void
setDoubleData
(
@NotNull
final
AVertex
vertex
,
@NotNull
final
String
name
,
final
double
data
)
{
if
(!
verticesDoubleData
.
containsKey
(
name
))
{
DoubleArrayList
dataArray
=
new
DoubleArrayList
(
vertices
.
size
());
verticesDoubleData
.
put
(
name
,
dataArray
);
}
DoubleArrayList
dataArray
=
verticesDoubleData
.
get
(
name
);
assert
dataArray
.
size
()
==
vertices
.
size
();
dataArray
.
set
(
vertex
.
getId
(),
data
);
}
@Override
public
void
setDoubleData
(
@NotNull
final
AHalfEdge
edge
,
@NotNull
final
String
name
,
final
double
data
)
{
if
(!
halfEdgesDoubleData
.
containsKey
(
name
))
{
DoubleArrayList
dataArray
=
new
DoubleArrayList
(
edges
.
size
());
halfEdgesDoubleData
.
put
(
name
,
dataArray
);
}
DoubleArrayList
dataArray
=
halfEdgesDoubleData
.
get
(
name
);
assert
dataArray
.
size
()
==
edges
.
size
();
dataArray
.
set
(
edge
.
getId
(),
data
);
}
@Override
public
void
setBooleanData
(
@NotNull
final
AFace
face
,
@NotNull
final
String
name
,
final
boolean
data
)
{
if
(!
facesBooleanData
.
containsKey
(
name
))
{
BooleanArrayList
dataArray
=
new
BooleanArrayList
(
faces
.
size
());
facesBooleanData
.
put
(
name
,
dataArray
);
}
BooleanArrayList
dataArray
=
facesBooleanData
.
get
(
name
);
assert
dataArray
.
size
()
==
faces
.
size
();
dataArray
.
set
(
face
.
getId
(),
data
);
}
@Override
public
void
setBooleanData
(
@NotNull
final
AVertex
vertex
,
@NotNull
final
String
name
,
final
boolean
data
)
{
if
(!
verticesBooleanData
.
containsKey
(
name
))
{
BooleanArrayList
dataArray
=
new
BooleanArrayList
(
vertices
.
size
());
verticesBooleanData
.
put
(
name
,
dataArray
);
}
BooleanArrayList
dataArray
=
verticesBooleanData
.
get
(
name
);
assert
dataArray
.
size
()
==
vertices
.
size
();
dataArray
.
set
(
vertex
.
getId
(),
data
);
}
@Override
public
void
setBooleanData
(
@NotNull
final
AHalfEdge
edge
,
@NotNull
final
String
name
,
final
boolean
data
)
{
if
(!
halfEdgesBooleanData
.
containsKey
(
name
))
{
BooleanArrayList
dataArray
=
new
BooleanArrayList
(
edges
.
size
());
halfEdgesBooleanData
.
put
(
name
,
dataArray
);
}
BooleanArrayList
dataArray
=
halfEdgesBooleanData
.
get
(
name
);
assert
dataArray
.
size
()
==
edges
.
size
();
dataArray
.
set
(
edge
.
getId
(),
data
);
}
private
void
fill
(
@NotNull
final
ObjectArrayList
<?>
data
,
final
int
n
)
{
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
data
.
add
(
null
);
...
...
@@ -574,6 +652,24 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
}
clone
.
verticesDoubleData
=
clonedVerticessDoubleData
;
Map
<
String
,
BooleanArrayList
>
clonedFacesBooleanData
=
new
HashMap
<>();
for
(
var
entry
:
facesBooleanData
.
entrySet
())
{
clonedFacesBooleanData
.
put
(
entry
.
getKey
(),
entry
.
getValue
().
clone
());
}
clone
.
facesBooleanData
=
clonedFacesBooleanData
;
Map
<
String
,
BooleanArrayList
>
clonedHalfEdgesBooleanData
=
new
HashMap
<>();
for
(
var
entry
:
halfEdgesBooleanData
.
entrySet
())
{
clonedHalfEdgesBooleanData
.
put
(
entry
.
getKey
(),
entry
.
getValue
().
clone
());
}
clone
.
halfEdgesBooleanData
=
clonedHalfEdgesBooleanData
;
Map
<
String
,
BooleanArrayList
>
clonedVerticessBooleanData
=
new
HashMap
<>();
for
(
var
entry
:
verticesBooleanData
.
entrySet
())
{
clonedVerticessBooleanData
.
put
(
entry
.
getKey
(),
entry
.
getValue
().
clone
());
}
clone
.
verticesBooleanData
=
clonedVerticessBooleanData
;
return
clone
;
}
catch
(
CloneNotSupportedException
e
)
{
...
...
@@ -694,16 +790,28 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
list
.
set
(
vertexMap
[
i
],
list
.
getDouble
(
i
));
list
.
set
(
i
,
tmp
);
}
for
(
var
list
:
verticesBooleanData
.
values
())
{
boolean
tmp
=
list
.
getBoolean
(
vertexMap
[
i
]);
list
.
set
(
vertexMap
[
i
],
list
.
getBoolean
(
i
));
list
.
set
(
i
,
tmp
);
}
}
for
(
var
list
:
verticesDoubleData
.
values
())
{
if
(
vertexMap
.
length
<
facesDoubleData
.
size
())
{
if
(
vertexMap
.
length
<
verticesDoubleData
.
size
())
{
list
.
trim
(
vertexMap
.
length
);
}
}
for
(
var
list
:
verticesBooleanData
.
values
())
{
if
(
vertexMap
.
length
<
verticesBooleanData
.
size
())
{
list
.
trim
(
vertexMap
.
length
);
}
}
for
(
var
list
:
verticesData
.
values
())
{
if
(
vertexMap
.
length
<
facesDouble
Data
.
size
())
{
if
(
vertexMap
.
length
<
vertices
Data
.
size
())
{
list
.
trim
(
vertexMap
.
length
);
}
}
...
...
@@ -720,16 +828,28 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
list
.
set
(
edgeMap
[
i
],
list
.
getDouble
(
i
));
list
.
set
(
i
,
tmp
);
}
for
(
var
list
:
halfEdgesBooleanData
.
values
())
{
boolean
tmp
=
list
.
getBoolean
(
edgeMap
[
i
]);
list
.
set
(
edgeMap
[
i
],
list
.
getBoolean
(
i
));
list
.
set
(
i
,
tmp
);
}
}
for
(
var
list
:
halfEdgesDoubleData
.
values
())
{
if
(
edgeMap
.
length
<
facesDoubleData
.
size
())
{
if
(
edgeMap
.
length
<
halfEdgesDoubleData
.
size
())
{
list
.
trim
(
edgeMap
.
length
);
}
}
for
(
var
list
:
halfEdgesBooleanData
.
values
())
{
if
(
edgeMap
.
length
<
halfEdgesBooleanData
.
size
())
{
list
.
trim
(
edgeMap
.
length
);
}
}
for
(
var
list
:
halfEdgesData
.
values
())
{
if
(
edgeMap
.
length
<
facesDouble
Data
.
size
())
{
if
(
edgeMap
.
length
<
halfEdges
Data
.
size
())
{
list
.
trim
(
edgeMap
.
length
);
}
}
...
...
@@ -746,6 +866,12 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
list
.
set
(
faceMap
[
i
],
list
.
getDouble
(
i
));
list
.
set
(
i
,
tmp
);
}
for
(
var
list
:
facesBooleanData
.
values
())
{
boolean
tmp
=
list
.
getBoolean
(
faceMap
[
i
]);
list
.
set
(
faceMap
[
i
],
list
.
getBoolean
(
i
));
list
.
set
(
i
,
tmp
);
}
}
for
(
var
list
:
facesDoubleData
.
values
())
{
...
...
@@ -754,8 +880,14 @@ public class AMesh implements IMesh<AVertex, AHalfEdge, AFace>, Cloneable {
}
}
for
(
var
list
:
facesBooleanData
.
values
())
{
if
(
faceMap
.
length
<
facesBooleanData
.
size
())
{
list
.
trim
(
faceMap
.
length
);
}
}
for
(
var
list
:
facesData
.
values
())
{
if
(
faceMap
.
length
<
facesD
oubleD
ata
.
size
())
{
if
(
faceMap
.
length
<
facesData
.
size
())
{
list
.
trim
(
faceMap
.
length
);
}
}
...
...
VadereMeshing/src/org/vadere/meshing/mesh/inter/IMesh.java
View file @
1d6c7133
...
...
@@ -319,7 +319,9 @@ public interface IMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
setData
(
vertex
,
name
,
data
);
}
//default void setDoubleDataNull
//default void setBooleanNull(@NotNull final V vertex, @NotNull final String name, boolean nil) {}
//default void setDoubleNull(@NotNull final V vertex, @NotNull final String name, double nil) {}
/**
* Returns the data saved on the half-edge in O(1) if there is any and otherwise <tt>Optional.empty()</tt>.
...
...
VadereSimulator/src/org/vadere/simulator/models/osm/updateScheme/UpdateSchemeEventDrivenParallel.java
View file @
1d6c7133
package
org.vadere.simulator.models.osm.updateScheme
;
import
org.jetbrains.annotations.NotNull
;
import
org.vadere.meshing.mesh.gen.IncrementalTriangulation
;
import
org.vadere.meshing.mesh.gen.MeshPanel
;
import
org.vadere.meshing.mesh.gen.PFace
;
import
org.vadere.meshing.mesh.gen.PHalfEdge
;
import
org.vadere.meshing.mesh.gen.PMesh
;
import
org.vadere.meshing.mesh.gen.PVertex
;
import
org.vadere.meshing.mesh.
triangulation.triangulator.gen.GenPointSet
Triangulat
or
;
import
org.vadere.meshing.mesh.
inter.IIncremental
Triangulat
ion
;
import
org.vadere.simulator.models.osm.PedestrianOSM
;
import
org.vadere.state.scenario.Topography
;
import
org.vadere.util.geometry.LinkedCellsGrid
;
...
...
@@ -30,9 +31,10 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
private
LinkedCellsGrid
<
PedestrianOSM
>
linkedCellsGrid
;
private
boolean
[][]
locked
;
private
double
pedestrianPotentialWidth
;
private
Map
<
PedestrianOSM
,
PVertex
>
map
;
private
PMesh
mesh
;
private
MeshPanel
<
PVertex
,
PHalfEdge
,
PFace
>
panel
;
private
Map
<
PedestrianOSM
,
PVertex
>
map
;
private
IIncrementalTriangulation
<
PVertex
,
PHalfEdge
,
PFace
>
triangulation
;
public
UpdateSchemeEventDrivenParallel
(
@NotNull
final
Topography
topography
,
@NotNull
final
double
pedestrianPotentialWidth
)
{
...
...
@@ -74,16 +76,22 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
int
counter
=
1
;
// event driven update ignores time credits
do
{
mesh
=
new
PMesh
<>
();
Collection
<
Pedestrian
Point
>
pedPoints
=
topography
.
getElements
(
PedestrianOSM
.
class
)
do
{
mesh
=
new
PMesh
();
Collection
<
V
Point
>
pedPoints
=
topography
.
getElements
(
PedestrianOSM
.
class
)
.
stream
()
.
map
(
ped
->
new
PedestrianPoint
(
ped
.
getPosition
()
,
ped
)
)
.
map
(
ped
->
ped
.
getPosition
())
.
collect
(
Collectors
.
toList
());
GenPointSetTriangulator
<
PVertex
,
PHalfEdge
,
PFace
>
triangulator
=
new
GenPointSetTriangulator
<>(
pedPoints
,
mesh
);
triangulator
.
generate
();
triangulation
=
new
IncrementalTriangulation
(
mesh
);
for
(
PedestrianOSM
pedestrianOSM
:
topography
.
getElements
(
PedestrianOSM
.
class
))
{
PHalfEdge
halfEdge
=
triangulation
.
insert
(
pedestrianOSM
.
getPosition
().
getX
(),
pedestrianOSM
.
getPosition
().
getY
());
PVertex
vertex
=
triangulation
.
getMesh
().
getVertex
(
halfEdge
);
triangulation
.
getMesh
().
setData
(
vertex
,
"pedestrian"
,
pedestrianOSM
);
map
.
put
(
pedestrianOSM
,
vertex
);
}
triangulation
.
finish
();
if
(
panel
==
null
)
{
panel
=
new
MeshPanel
<>(
mesh
,
1000
,
1000
);
...
...
@@ -93,9 +101,9 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
panel
.
getMeshRenderer
().
setMesh
(
mesh
);
}
for
(
PVertex
pedestrianPoint
:
mesh
.
getVertices
())
{
/*
for(PVertex pedestrianPoint : mesh.getVertices()) {
map.put(mesh.getPoint(pedestrianPoint).pedestrianOSM, pedestrianPoint);
}
}
*/
panel
.
repaint
();
...
...
@@ -151,19 +159,26 @@ public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
logger
.
info
(
"avoided updates: "
+
count
);
}
private
boolean
requireUpdate
(
PedestrianOSM
pedestrianOSM
)
{
private
boolean
requireUpdate
(
@NotNull
final
PedestrianOSM
pedestrianOSM
)
{
PVertex
vertex
=
map
.
get
(
pedestrianOSM
);
if
(
mesh
.
getPoint
(
vertex
).
hasChanged
(
))
{
if
(
hasChanged
(
pedestrianOSM
))
{
return
true
;
}
for
(
PVertex
v
:
mesh
.
getAdjacentVertexIt
(
vertex
))
{
if
(
mesh
.
getPoint
(
v
).
hasChanged
())
{
PedestrianOSM
ped
=
triangulation
.
getMesh
().
getData
(
v
,
"pedestrian"
,
PedestrianOSM
.
class
).
get
();
if
(
hasChanged
(
ped
))
{
return
true
;
}
}
return
false
;
}
private
boolean
hasChanged
(
@NotNull
final
PedestrianOSM
pedestrianOSM
)
{
return
pedestrianOSM
.
getLastPosition
().
equals
(
pedestrianOSM
.
getPosition
());
}
private
class
PedestrianPoint
implements
IPoint
{
private
final
PedestrianOSM
pedestrianOSM
;
...
...
VadereSimulator/src/org/vadere/simulator/models/potential/fields/IPotentialField.java
View file @
1d6c7133
...
...
@@ -155,7 +155,7 @@ public interface IPotentialField {
/**
* Generate the mesh, we use the pointer based implementation here.
*/
PEikMesh
meshGenerator
=
new
PEikMesh
<>
(
distanceFunc
,
edgeLengthFunction
,
0.7
,
bbox
,
holes
);
PEikMesh
meshGenerator
=
new
PEikMesh
(
distanceFunc
,
edgeLengthFunction
,
0.7
,
bbox
,
holes
);
IIncrementalTriangulation
<
PVertex
,
PHalfEdge
,
PFace
>
triangulation
=
meshGenerator
.
generate
();
ITimeCostFunction
timeCost
=
TimeCostFunctionFactory
.
create
(
...
...
VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/PotentialFieldCalculatorNone.java
View file @
1d6c7133
...
...
@@ -41,6 +41,6 @@ public class PotentialFieldCalculatorNone implements EikonalSolver {
*/
@Override
public
IMesh
<?,
?,
?>
getDiscretization
()
{
return
new
PMesh
<>
();
return
new
PMesh
();
}
}
VadereSimulator/src/org/vadere/simulator/models/potential/solver/calculators/mesh/EikonalSolverFMMTriangulation.java
View file @
1d6c7133
package
org.vadere.simulator.models.potential.solver.calculators.mesh
;
import
org.apache.commons.lang3.tuple.Triple
;
import
org.jetbrains.annotations.NotNull
;
import
org.vadere.meshing.mesh.inter.IFace
;
import
org.vadere.meshing.mesh.inter.IHalfEdge
;
...
...
@@ -9,7 +8,6 @@ import org.vadere.meshing.mesh.inter.IMesh;
import
org.vadere.meshing.mesh.inter.IVertex
;
import
org.vadere.simulator.models.potential.solver.calculators.EikonalSolver
;
import
org.vadere.simulator.models.potential.solver.timecost.ITimeCostFunction
;
import
org.vadere.util.data.cellgrid.IPotentialPoint
;
import
org.vadere.util.data.cellgrid.PathFindingTag
;
import
org.vadere.util.geometry.GeometryUtils
;
import
org.vadere.util.geometry.shapes.IPoint
;
...
...
@@ -22,11 +20,9 @@ import org.vadere.util.math.MathUtil;
import
java.util.Collection
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Optional
;
import
java.util.PriorityQueue
;
import
java.util.Set
;
...
...
@@ -39,18 +35,17 @@ import java.util.function.Predicate;
* The quality of the result depends on the quality of the triangulation. For a high accuracy the triangulation
* should not contain too many non-acute triangles.
*
* @param <P> the type of the points of the triangulation extending {@link IPotentialPoint}
* @param <V> the type of the vertices of the triangulation
* @param <E> the type of the half-edges of the triangulation
* @param <F> the type of the faces of the triangulation
*/
public
class
EikonalSolverFMMTriangulation
<
P
extends
IPotentialPoint
,
V
extends
IVertex
,
E
extends
IHalfEdge
,
F
extends
IFace
>
implements
EikonalSolver
{
public
class
EikonalSolverFMMTriangulation
<
V
extends
IVertex
,
E
extends
IHalfEdge
,
F
extends
IFace
>
implements
EikonalSolver
{
private
static
Logger
logger
=
Logger
.
getLogger
(
EikonalSolverFMMTriangulation
.
class
);
private
Set
<
F
>
nonAccuteTris
=
new
HashSet
<>();
private
Map
<
Triple
<
P
,
P
,
P
>,
Double
>
angles
=
new
HashMap
();
private
Map
<
Triple
<
P
,
P
,
P
>,
Double
>
sinPhis
=
new
HashMap
()
;
private
Map
<
Triple
<
P
,
P
,
P
>,
Double
>
cosPhis
=
new
HashMap
()
;
public
static
final
String
namePotential
=
"potential"
;
public
static
final
String
namePathFindingTag
=
"pathFindingTag"
;
static
{
logger
.
setInfo
();
...
...
@@ -87,11 +82,9 @@ public class EikonalSolverFMMTriangulation<P extends IPotentialPoint, V extends
* Comparator for the heap. Vertices of points with small potentials are at the top of the heap.
*/
private
Comparator
<
V
>
pointComparator
=
(
v1
,
v2
)
->
{
P
p1
=
getMesh
().
getPoint
(
v1
);
P
p2
=
getMesh
().
getPoint
(
v2
);
if
(
p1
.
getPotential
()
<
p2
.
getPotential
())
{
if
(
getPotential
(
v1
)
<
getPotential
(
v2
))
{
return
-
1
;
}
else
if
(
p1
.
getPotential
()
>
p2
.
getPotential
())
{
}
else
if
(
getPotential
(
v1
)
>
getPotential
(
v2
))
{
return
1
;
}
else
{
...
...
@@ -189,15 +182,12 @@ public class EikonalSolverFMMTriangulation<P extends IPotentialPoint, V extends
*/
private
void
initialFace
(
@NotNull
final
F
face
,
@NotNull
final
IDistanceFunction
distanceFunction
)
{
for
(
V
vertex
:
getMesh
().
getVertexIt
(
face
))
{
P
potentialPoint
=
getMesh
().
getPoint
(
vertex
);
double
distance
=
distanceFunction
.
apply
(
potentialPoint
);
if
(
potentialPoint
.
getPathFindingTag
()
!=
PathFindingTag
.
Undefined
)
{
double
distance
=
distanceFunction
.
apply
(
vertex
);
if
(
getPathFindingTag
(
vertex
)
!=
PathFindingTag
.
Undefined
)
{
narrowBand
.
remove
(
vertex
);
}
potentialPoint
.
setPotential
(
Math
.
min
(
potentialPoint
.
getPotential
(),
distance
*
timeCostFunction
.
costAt
(
potentialPoint
)));
potentialPoint
.
setPathFindingTag
(
PathFindingTag
.
Reached
);
updatePotential
(
vertex
,
distance
/
getTimeCost
(
vertex
));
setPathFindingTag
(
vertex
,
PathFindingTag
.
Reached
);
narrowBand
.
add
(
vertex
);
}
}
...
...
@@ -212,7 +202,7 @@ public class EikonalSolverFMMTriangulation<P extends IPotentialPoint, V extends
if
(!
calculationFinished
)
{
while
(
narrowBand
.
size
()
>
0
)
{
V
vertex
=
narrowBand
.
poll
();
getMesh
().
getPoint
(
vertex
).
setPathFindingTag
(
PathFindingTag
.
Reached
);
setPathFindingTag
(
vertex
,
PathFindingTag
.
Reached
);
updatePotentialOfNeighbours
(
vertex
);
}
calculationFinished
=
true
;
...
...
@@ -220,36 +210,40 @@ public class EikonalSolverFMMTriangulation<P extends IPotentialPoint, V extends
}
private
void
reset
()
{
triangulation
.
getMesh
().
stream
Point
s
().
forEach
(
p
->
p
.
setPathFindingTag
(
PathFindingTag
.
Undefined
));
triangulation
.
getMesh
().
stream
Point
s
().
forEach
(
p
->
p
.
setPotential
(
Double
.
MAX_VALUE
));
triangulation
.
getMesh
().
stream
Vertice
s
().
forEach
(
v
->
setPathFindingTag
(
v
,
PathFindingTag
.
Undefined
));
triangulation
.
getMesh
().
stream
Vertice
s
().
forEach
(
v
->
setPotential
(
v
,
Double
.
MAX_VALUE
));
calculationFinished
=
false
;
for
(
V
vertex
:
targetVertices
)
{
P
potentialPoint
=
getMesh
().
getPoint
(
vertex
);
double
distance
=
Math
.
max
(
distFunc
.
apply
(
potentialPoint
),
0
);
double
distance
=
Math
.
max
(
distFunc
.
apply
(
vertex
),
0
);
if
(
potentialPoint
.
getPathFindingTag
()
!=
PathFindingTag
.
Undefined
)
{
if
(
getPathFindingTag
(
vertex
)
!=
PathFindingTag
.
Undefined
)
{
narrowBand
.
remove
(
vertex
);
}
potentialPoint
.
setPotential
(
Math
.
min
(
potentialPoint
.
getPotential
(),
distance
/
timeCostFunction
.
costAt
(
potentialPoint
)));
potentialPoint
.
setPathFindingTag
(
PathFindingTag
.
Reached
);
updatePotential
(
vertex
,
distance
/
getTimeCost
(
vertex
));
setPathFindingTag
(
vertex
,
PathFindingTag
.
Reached
);
narrowBand
.
add
(
vertex
);
for
(
V
v
:
triangulation
.
getMesh
().
getAdjacentVertexIt
(
vertex
))
{
P
potentialP
=
getMesh
().
getPoint
(
v
);
if
(
potentialP
.
getPathFindingTag
()
==
PathFindingTag
.
Undefined
)
{
double
dist
=
Math
.
max
(
distFunc
.
apply
(
potentialP
),
0
);
logger
.
debug
(
"T at "
+
potentialP
+
" = "
+
dist
);
potentialP
.
setPotential
(
Math
.
min
(
potentialP
.
getPotential
(),
dist
/
timeCostFunction
.
costAt
(
potentialP
)));
potentialP
.
setPathFindingTag
(
PathFindingTag
.
Reachable
);
if
(
getPathFindingTag
(
v
)
==
PathFindingTag
.
Undefined
)
{
double
dist
=
Math
.
max
(
distFunc
.
apply
(
v
),
0
);
logger
.
debug
(
"T at "
+
v
+
" = "
+
dist
);
updatePotential
(
v
,
dist
/
getTimeCost
(
v
));
setPathFindingTag
(
v
,
PathFindingTag
.
Reachable
);
narrowBand
.
add
(
v
);
}
}
}
}
private
double
getTimeCost
(
@NotNull
final
V
vertex
)
{
return
timeCostFunction
.
costAt
(
vertex
);
}
private
void
updatePotential
(
@NotNull
final
V
vertex
,
final
double
potential
)
{
setPotential
(
vertex
,
Math
.
min
(
getPotential
(
vertex
),
potential
));
}
// unknownPenalty is ignored.
@Override
public
double
getPotential
(
@NotNull
final
IPoint
pos
,
final
double
unknownPenalty
,
final
double
weight
)
{
...
...
@@ -280,14 +274,13 @@ public class EikonalSolverFMMTriangulation<P extends IPotentialPoint, V extends
* @param x the x-coordinate of the point
* @param y the y-coordinate of the point
*
* @param <P> the type of the points of the triangulation extending {@link IPotentialPoint}
* @param <V> the type of the vertices of the triangulation
* @param <E> the type of the half-edges of the triangulation
* @param <F> the type of the faces of the triangulation
*
* @return the interpolated value of the traveling time T at (x, y)
*/
private
static
<
P
extends
IPotentialPoint
,
V
extends
IVertex
,
E
extends
IHalfEdge
,
F
extends
IFace
>
double
getPotential
(
private
static
<
V
extends
IVertex
,
E
extends
IHalfEdge
,
F
extends
IFace
>
double
getPotential
(
@NotNull
final
IIncrementalTriangulation
<
V
,
E
,
F
>
triangulation
,
final
double
x
,
final
double
y
)
{
...
...
@@ -302,7 +295,11 @@ public class EikonalSolverFMMTriangulation<P extends IPotentialPoint, V extends
// logger.warn("no triangle found for coordinates (" + x + "," + y + ")");
}
else
{
result
=
InterpolationUtil
.
barycentricInterpolation
(
triangulation
.
getMesh
().
getPoints
(
optFace
.
get
()),
x
,
y
);
E
edge
=
triangulation
.
getMesh
().
getEdge
(
optFace
.
get
());
V
v1
=
triangulation
.
getMesh
().
getVertex
(
edge
);
V
v2
=
triangulation
.
getMesh
().
getVertex
(
triangulation
.
getMesh
().
getNext
(
edge
));
V
v3
=
triangulation
.
getMesh
().
getVertex
(
triangulation
.
getMesh
().
getPrev
(
edge
));
result
=
InterpolationUtil
.
barycentricInterpolation
(
v1
,
v2
,
v3
,
v
->
triangulation
.
getMesh
().
getDoubleData
(
v
,
namePotential
),
x
,
y
);
}
return
result
;
}
...
...
@@ -331,18 +328,16 @@ public class EikonalSolverFMMTriangulation<P extends IPotentialPoint, V extends
*/
private
void
updatePotential
(
@NotNull
final
V
vertex
)
{
double
potential
=
recomputePotential
(
vertex
);
P
potentialPoint
=
getMesh
().
getPoint
(
vertex
);
if
(
potential
<
potentialPoint
.
getPotential
())
{
if
(
potentialPoint
.
getPathFindingTag
()
==
PathFindingTag
.
Reachable
)
{
if
(
potential
<
getPotential
(
vertex
))
{
if
(
getPathFindingTag
(
vertex
)
==
PathFindingTag
.
Reachable
)
{
narrowBand
.
remove
(
vertex
);
}
potentialPoint
.
setPotential
(
potential
);
potentialPoint
.
setPathFindingTag
(
PathFindingTag
.
Reachable
);
setPotential
(
vertex
,
potential
);
setPathFindingTag
(
vertex
,
PathFindingTag
.
Reachable
);
narrowBand
.
add
(
vertex
);
}
if
(
potentialPoint
.
getPathFindingTag
()
==
PathFindingTag
.
Undefined
)
{
if
(
getPathFindingTag
(
vertex
)
==
PathFindingTag
.
Undefined
)
{
logger
.
debug
(
"could not set neighbour vertex"
+
vertex
);
}
}
...
...
@@ -361,9 +356,9 @@ public class EikonalSolverFMMTriangulation<P extends IPotentialPoint, V extends
// value accordingly
double
potential
=
Double
.
MAX_VALUE
;
<