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
a138df4b
Commit
a138df4b
authored
Jun 09, 2021
by
Matthias Betz
Browse files
changing math api to be more robust
parent
f74c2f52
Pipeline
#4354
passed with stage
in 2 minutes and 21 seconds
Changes
19
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LinearRing.java
View file @
a138df4b
...
...
@@ -22,6 +22,9 @@ import java.util.ArrayList;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.math.ProjectionAxis
;
import
de.hft.stuttgart.citydoctor2.math.Ring2d
;
import
de.hft.stuttgart.citydoctor2.math.UnitVector3d
;
import
de.hft.stuttgart.citydoctor2.math.Vector2d
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
...
...
@@ -57,37 +60,13 @@ public class LinearRing extends GmlElement {
*/
public
boolean
isPointInside
(
Vector3d
v
)
{
// project to 2d ring
List
<
Vector2d
>
projectedRing
=
new
ArrayList
<>();
Vector2d
point
;
Vector3d
normal
=
calculateNormalNormalized
();
double
x
=
Math
.
abs
(
normal
.
getX
());
double
y
=
Math
.
abs
(
normal
.
getY
());
double
z
=
Math
.
abs
(
normal
.
getZ
());
if
(
x
>
y
&&
x
>
z
)
{
for
(
Vertex
vert
:
vertices
)
{
Vector2d
projCoords
=
new
Vector2d
(
vert
.
getY
(),
vert
.
getZ
());
projectedRing
.
add
(
projCoords
);
}
point
=
new
Vector2d
(
v
.
getY
(),
v
.
getZ
());
}
else
if
(
y
>
x
&&
y
>
z
)
{
for
(
Vertex
vert
:
vertices
)
{
Vector2d
projCoords
=
new
Vector2d
(
vert
.
getX
(),
vert
.
getZ
());
projectedRing
.
add
(
projCoords
);
}
point
=
new
Vector2d
(
v
.
getX
(),
v
.
getZ
());
}
else
{
for
(
Vertex
vert
:
vertices
)
{
Vector2d
projCoords
=
new
Vector2d
(
vert
.
getX
(),
vert
.
getY
());
projectedRing
.
add
(
projCoords
);
}
point
=
new
Vector2d
(
v
.
getX
(),
v
.
getY
());
}
ProjectionAxis
axis
=
ProjectionAxis
.
of
(
this
);
Vector2d
point
=
axis
.
project
(
v
);
Ring2d
ring
=
Ring2d
.
of
(
this
,
axis
);
int
t
=
-
1
;
for
(
int
i
=
0
;
i
<
projectedRing
.
size
()
-
1
;
i
++)
{
t
=
t
*
crossProdTest
(
point
,
projectedRing
.
get
(
i
),
projectedRing
.
get
(
i
+
1
));
for
(
int
i
=
0
;
i
<
ring
.
getVertices
()
.
size
()
-
1
;
i
++)
{
t
=
t
*
crossProdTest
(
point
,
ring
.
getVertices
().
get
(
i
),
ring
.
getVertices
()
.
get
(
i
+
1
));
if
(
t
==
0
)
{
return
true
;
}
...
...
@@ -135,31 +114,8 @@ public class LinearRing extends GmlElement {
*
* @return the normal as a normalized vector
*/
public
Vector3d
calculateNormalNormalized
()
{
double
[]
coords
=
new
double
[
3
];
for
(
int
i
=
0
;
i
<
vertices
.
size
()
-
1
;
i
++)
{
Vertex
current
=
vertices
.
get
(
i
+
0
);
Vertex
next
=
vertices
.
get
(
i
+
1
);
coords
[
0
]
+=
(
current
.
getZ
()
+
next
.
getZ
())
*
(
current
.
getY
()
-
next
.
getY
());
coords
[
1
]
+=
(
current
.
getX
()
+
next
.
getX
())
*
(
current
.
getZ
()
-
next
.
getZ
());
coords
[
2
]
+=
(
current
.
getY
()
+
next
.
getY
())
*
(
current
.
getX
()
-
next
.
getX
());
}
if
(
coords
[
0
]
==
0
&&
coords
[
1
]
==
0
&&
coords
[
2
]
==
0
)
{
// no valid normal vector found
if
(
vertices
.
size
()
<
3
)
{
// no three points, return x-axis
return
new
Vector3d
(
1
,
0
,
0
);
}
Vertex
v1
=
vertices
.
get
(
0
);
Vertex
v2
=
vertices
.
get
(
1
);
Vertex
v3
=
vertices
.
get
(
2
);
return
calculateNormalWithCross
(
v1
,
v2
,
v3
);
}
Vector3d
v
=
new
Vector3d
(
coords
);
v
.
normalize
();
return
v
;
public
UnitVector3d
calculateNormalNormalized
()
{
return
calculateNormal
().
normalize
();
}
/**
...
...
@@ -183,7 +139,7 @@ public class LinearRing extends GmlElement {
// no valid normal vector found
if
(
vertices
.
size
()
<
3
)
{
// no three points, return x-axis
return
new
Vector3d
(
1
,
0
,
0
)
;
return
Unit
Vector3d
.
X_AXIS
;
}
Vertex
v1
=
vertices
.
get
(
0
);
...
...
@@ -194,7 +150,7 @@ public class LinearRing extends GmlElement {
return
new
Vector3d
(
coords
);
}
private
Vector3d
calculateNormalWithCross
(
Vertex
v1
,
Vertex
v2
,
Vertex
v3
)
{
private
Unit
Vector3d
calculateNormalWithCross
(
Vertex
v1
,
Vertex
v2
,
Vertex
v3
)
{
Vector3d
dir1
=
v2
.
minus
(
v1
);
Vector3d
dir2
=
v3
.
minus
(
v1
);
Vector3d
cross
=
dir1
.
cross
(
dir2
);
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/CovarianceMatrix.java
View file @
a138df4b
...
...
@@ -33,22 +33,18 @@ public class CovarianceMatrix {
}
/**
* Calculates the covariance matrix of the given points, with the given expected
* values.
* see {@link CovarianceMatrix#calculateCovarianceMatrix(List, double[])}
*
* @param vertices the vertices for which the matrix is calculated
* @param expected the expected values
* @param expected the expected values
as a vector
* @return the covariance 3 x 3 matrix
*/
public
static
double
[][]
calculateCovarianceMatrix
(
List
<?
extends
Vector3d
>
vertices
,
double
[]
expected
)
{
if
(
expected
.
length
!=
3
)
{
throw
new
IllegalArgumentException
(
"for 3D points 3 expected values have to be provided"
);
}
public
static
double
[][]
calculateCovarianceMatrix
(
List
<?
extends
Vector3d
>
vertices
,
Vector3d
expected
)
{
double
[][]
covValues
=
new
double
[
3
][
3
];
for
(
Vector3d
v
:
vertices
)
{
double
xdiff
=
v
.
getX
()
-
expected
[
0
]
;
double
ydiff
=
v
.
getY
()
-
expected
[
1
]
;
double
zdiff
=
v
.
getZ
()
-
expected
[
2
]
;
double
xdiff
=
v
.
getX
()
-
expected
.
getX
()
;
double
ydiff
=
v
.
getY
()
-
expected
.
getY
()
;
double
zdiff
=
v
.
getZ
()
-
expected
.
getZ
()
;
covValues
[
0
][
0
]
+=
xdiff
*
xdiff
;
covValues
[
0
][
1
]
+=
xdiff
*
ydiff
;
covValues
[
0
][
2
]
+=
xdiff
*
zdiff
;
...
...
@@ -69,17 +65,6 @@ public class CovarianceMatrix {
return
covValues
;
}
/**
* see {@link CovarianceMatrix#calculateCovarianceMatrix(List, double[])}
*
* @param vertices the vertices for which the matrix is calculated
* @param expected the expected values as a vector
* @return the covariance 3 x 3 matrix
*/
public
static
double
[][]
calculateCovarianceMatrix
(
List
<?
extends
Vector3d
>
vertices
,
Vector3d
expected
)
{
return
calculateCovarianceMatrix
(
vertices
,
expected
.
getCoordinates
());
}
public
static
Vector3d
getCentroid
(
List
<?
extends
Vector3d
>
vertices
)
{
if
(
vertices
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"Vertices may not be empty to calculate centroid"
);
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/MovedRing.java
View file @
a138df4b
...
...
@@ -45,16 +45,16 @@ public class MovedRing {
}
return
indRing
;
}
private
MovedRing
()
{
vertices
=
new
ArrayList
<>();
}
public
LinearRing
getOriginal
()
{
return
original
;
}
public
MovedRing
()
{
vertices
=
new
ArrayList
<>();
}
public
void
addVertex
(
Vector3d
v
)
{
private
void
addVertex
(
Vector3d
v
)
{
vertices
.
add
(
v
);
}
...
...
@@ -71,75 +71,10 @@ public class MovedRing {
*/
public
boolean
isPointInside
(
Vector3d
v
)
{
// project to 2d ring
List
<
Vector2d
>
projectedRing
=
new
ArrayList
<>();
Vector2d
point
;
Vector3d
normal
=
calculateNormal
();
double
x
=
Math
.
abs
(
normal
.
getX
());
double
y
=
Math
.
abs
(
normal
.
getY
());
double
z
=
Math
.
abs
(
normal
.
getZ
());
if
(
x
>=
y
&&
x
>=
z
)
{
for
(
Vector3d
vert
:
vertices
)
{
Vector2d
projCoords
=
new
Vector2d
(
vert
.
getY
(),
vert
.
getZ
());
projectedRing
.
add
(
projCoords
);
}
point
=
new
Vector2d
(
v
.
getY
(),
v
.
getZ
());
}
else
if
(
y
>=
x
&&
y
>=
z
)
{
for
(
Vector3d
vert
:
vertices
)
{
Vector2d
projCoords
=
new
Vector2d
(
vert
.
getX
(),
vert
.
getZ
());
projectedRing
.
add
(
projCoords
);
}
point
=
new
Vector2d
(
v
.
getX
(),
v
.
getZ
());
}
else
{
for
(
Vector3d
vert
:
vertices
)
{
Vector2d
projCoords
=
new
Vector2d
(
vert
.
getX
(),
vert
.
getY
());
projectedRing
.
add
(
projCoords
);
}
point
=
new
Vector2d
(
v
.
getX
(),
v
.
getY
());
}
int
t
=
-
1
;
for
(
int
i
=
0
;
i
<
projectedRing
.
size
()
-
1
;
i
++)
{
t
=
t
*
crossProdTest
(
point
,
projectedRing
.
get
(
i
),
projectedRing
.
get
(
i
+
1
));
if
(
t
==
0
)
{
return
true
;
}
}
return
t
>=
0
;
}
private
int
crossProdTest
(
Vector2d
a
,
Vector2d
b
,
Vector2d
c
)
{
if
(
a
.
getY
()
==
b
.
getY
()
&&
a
.
getY
()
==
c
.
getY
())
{
if
((
b
.
getX
()
<=
a
.
getX
()
&&
a
.
getX
()
<=
c
.
getX
())
||
(
c
.
getX
()
<=
a
.
getX
()
&&
a
.
getX
()
<=
b
.
getX
()))
{
return
0
;
}
else
{
return
1
;
}
}
if
(
a
.
getY
()
==
b
.
getY
()
&&
a
.
getX
()
==
b
.
getX
())
{
return
0
;
}
if
(
b
.
getY
()
>
c
.
getY
())
{
Vector2d
temp
=
b
;
b
=
c
;
c
=
temp
;
}
if
(
a
.
getY
()
<=
b
.
getY
()
||
a
.
getY
()
>
c
.
getY
())
{
return
1
;
}
return
calculateDelta
(
a
,
b
,
c
);
}
private
int
calculateDelta
(
Vector2d
a
,
Vector2d
b
,
Vector2d
c
)
{
double
delta
=
(
b
.
getX
()
-
a
.
getX
())
*
(
c
.
getY
()
-
a
.
getY
())
-
(
b
.
getY
()
-
a
.
getY
())
*
(
c
.
getX
()
-
a
.
getX
());
if
(
delta
>
0
)
{
return
-
1
;
}
else
if
(
delta
<
0
)
{
return
1
;
}
else
{
return
0
;
}
ProjectionAxis
axis
=
ProjectionAxis
.
of
(
this
);
Ring2d
projectedRing
=
Ring2d
.
of
(
this
,
axis
);
Vector2d
point
=
axis
.
project
(
v
);
return
projectedRing
.
containsPoint
(
point
);
}
/**
...
...
@@ -149,37 +84,7 @@ public class MovedRing {
*
* @return the normal as a normalized vector
*/
public
Vector3d
calculateNormal
()
{
double
[]
coords
=
new
double
[
3
];
for
(
int
i
=
0
;
i
<
vertices
.
size
()
-
1
;
i
++)
{
Vector3d
current
=
vertices
.
get
(
i
+
0
);
Vector3d
next
=
vertices
.
get
(
i
+
1
);
coords
[
0
]
+=
(
current
.
getZ
()
+
next
.
getZ
())
*
(
current
.
getY
()
-
next
.
getY
());
coords
[
1
]
+=
(
current
.
getX
()
+
next
.
getX
())
*
(
current
.
getZ
()
-
next
.
getZ
());
coords
[
2
]
+=
(
current
.
getY
()
+
next
.
getY
())
*
(
current
.
getX
()
-
next
.
getX
());
}
if
(
coords
[
0
]
==
0
&&
coords
[
1
]
==
0
&&
coords
[
2
]
==
0
)
{
// no valid normal vector found
if
(
vertices
.
size
()
<
3
)
{
// no three points, return x-axis
return
new
Vector3d
(
1
,
0
,
0
);
}
Vector3d
v1
=
vertices
.
get
(
0
);
Vector3d
v2
=
vertices
.
get
(
1
);
Vector3d
v3
=
vertices
.
get
(
2
);
return
calculateNormalWithCross
(
v1
,
v2
,
v3
);
}
Vector3d
v
=
new
Vector3d
(
coords
);
v
.
normalize
();
return
v
;
}
private
Vector3d
calculateNormalWithCross
(
Vector3d
v1
,
Vector3d
v2
,
Vector3d
v3
)
{
Vector3d
dir1
=
v2
.
minus
(
v1
);
Vector3d
dir2
=
v3
.
minus
(
v1
);
Vector3d
cross
=
dir1
.
cross
(
dir2
);
return
cross
.
normalize
();
public
UnitVector3d
calculateNormalNormalized
()
{
return
original
.
calculateNormalNormalized
();
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Plane.java
View file @
a138df4b
...
...
@@ -39,7 +39,7 @@ public class Plane implements Serializable {
private
static
final
double
EPSILON
=
0.0001
;
private
Vector3d
normal
;
private
Unit
Vector3d
normal
;
private
Vector3d
point
;
private
double
d
;
...
...
@@ -51,11 +51,10 @@ public class Plane implements Serializable {
*/
public
Plane
(
Vector3d
normal
,
Vector3d
p
)
{
point
=
p
;
this
.
normal
=
normal
.
copy
();
this
.
normal
.
normalize
();
this
.
normal
=
normal
.
normalize
();
d
=
this
.
normal
.
dot
(
point
);
if
(
d
<
0
)
{
this
.
normal
=
this
.
normal
.
mult
(-
1
);
this
.
normal
=
this
.
normal
.
invert
(
);
d
=
-
d
;
}
}
...
...
@@ -138,7 +137,7 @@ public class Plane implements Serializable {
*
* @return the normal vector of the plane
*/
public
Vector3d
getNormal
()
{
public
Unit
Vector3d
getNormal
()
{
return
normal
;
}
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Polygon2d.java
View file @
a138df4b
...
...
@@ -24,7 +24,6 @@ import java.util.List;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
/**
* A two dimensional polygon. Has an 2d exterior ring and interior rings
...
...
@@ -38,81 +37,36 @@ public class Polygon2d {
private
List
<
Ring2d
>
innerRings
;
public
static
Polygon2d
withProjection
(
Polygon
poly
)
{
Vector3d
normal
=
poly
.
calculateNormalNormalized
();
int
[]
axis
=
getProjectionAxis
(
normal
);
ProjectionAxis
axis
=
ProjectionAxis
.
of
(
poly
);
return
projectTo2D
(
poly
,
axis
);
}
public
static
Polygon2d
withProjection
(
MovedPolygon
poly
,
int
[]
projectionAxis
)
{
public
static
Polygon2d
withProjection
(
MovedPolygon
poly
,
ProjectionAxis
projectionAxis
)
{
return
projectTo2D
(
poly
,
projectionAxis
);
}
public
static
Polygon2d
withProjection
(
Polygon
poly
,
int
[]
projectionAxis
)
{
public
static
Polygon2d
withProjection
(
Polygon
poly
,
ProjectionAxis
projectionAxis
)
{
return
projectTo2D
(
poly
,
projectionAxis
);
}
private
static
Polygon2d
projectTo2D
(
Polygon
p
,
int
[]
axis
)
{
private
static
Polygon2d
projectTo2D
(
Polygon
p
,
ProjectionAxis
axis
)
{
List
<
Ring2d
>
interior
=
new
ArrayList
<>();
Ring2d
exterior
=
projectRing
(
p
.
getExteriorRing
(),
axis
);
Ring2d
exterior
=
Ring2d
.
of
(
p
.
getExteriorRing
(),
axis
);
for
(
LinearRing
innerRing
:
p
.
getInnerRings
())
{
interior
.
add
(
projectRing
(
innerRing
,
axis
));
interior
.
add
(
Ring2d
.
of
(
innerRing
,
axis
));
}
return
new
Polygon2d
(
exterior
,
interior
);
}
private
static
Polygon2d
projectTo2D
(
MovedPolygon
p
,
int
[]
axis
)
{
private
static
Polygon2d
projectTo2D
(
MovedPolygon
p
,
ProjectionAxis
axis
)
{
List
<
Ring2d
>
interior
=
new
ArrayList
<>();
Ring2d
exterior
=
projectRing
(
p
.
getExteriorRing
(),
axis
);
Ring2d
exterior
=
Ring2d
.
of
(
p
.
getExteriorRing
(),
axis
);
for
(
MovedRing
innerRing
:
p
.
getInnerRings
())
{
interior
.
add
(
projectRing
(
innerRing
,
axis
));
interior
.
add
(
Ring2d
.
of
(
innerRing
,
axis
));
}
return
new
Polygon2d
(
exterior
,
interior
);
}
public
static
int
[]
getProjectionAxis
(
Vector3d
normal
)
{
double
nx
=
Math
.
abs
(
normal
.
getX
());
double
ny
=
Math
.
abs
(
normal
.
getY
());
double
nz
=
Math
.
abs
(
normal
.
getZ
());
int
[]
axis
;
if
(
nx
>=
ny
&&
nx
>=
nz
)
{
axis
=
new
int
[]
{
1
,
2
};
}
else
if
(
ny
>=
nx
&&
ny
>=
nz
)
{
axis
=
new
int
[]
{
0
,
2
};
}
else
{
axis
=
new
int
[]
{
0
,
1
};
}
return
axis
;
}
private
static
Ring2d
projectRing
(
LinearRing
r
,
int
[]
axis
)
{
List
<
Vector2d
>
projectedVertices
=
new
ArrayList
<>();
for
(
Vertex
v
:
r
.
getVertices
())
{
projectedVertices
.
add
(
new
Vector2d
(
v
.
getCoordinate
(
axis
[
0
]),
v
.
getCoordinate
(
axis
[
1
])));
}
return
new
Ring2d
(
projectedVertices
,
r
);
}
private
static
Ring2d
projectRing
(
MovedRing
r
,
int
[]
axis
)
{
List
<
Vector2d
>
projectedVertices
=
new
ArrayList
<>();
for
(
Vector3d
v
:
r
.
getVertices
())
{
projectedVertices
.
add
(
new
Vector2d
(
v
.
getCoordinate
(
axis
[
0
]),
v
.
getCoordinate
(
axis
[
1
])));
}
return
new
Ring2d
(
projectedVertices
,
r
.
getOriginal
());
}
public
static
Polygon2d
withRotationMatrix
(
Polygon
poly
)
{
Matrix3x3d
rotMatrix
=
PolygonUtils
.
calculateRotationMatrix
(
poly
);
LinearRing
lr
=
poly
.
getExteriorRing
();
Ring2d
exterior
=
createRing2d
(
rotMatrix
,
lr
);
List
<
Ring2d
>
innerRings
=
new
ArrayList
<>();
for
(
LinearRing
innerRing
:
poly
.
getInnerRings
())
{
innerRings
.
add
(
createRing2d
(
rotMatrix
,
innerRing
));
}
return
new
Polygon2d
(
exterior
,
innerRings
);
}
/**
* Converts a Polygon to a 2d polygon. This will change the area of the polygon.
*
...
...
@@ -126,16 +80,6 @@ public class Polygon2d {
this
.
innerRings
=
interior
;
}
private
static
Ring2d
createRing2d
(
Matrix3x3d
rotMatrix
,
LinearRing
lr
)
{
List
<
Vector2d
>
ringVertices
=
new
ArrayList
<>();
for
(
Vertex
v
:
lr
.
getVertices
())
{
Vector3d
rotated
=
rotMatrix
.
mult
(
v
);
Vector2d
v2d
=
new
Vector2d
(
rotated
.
getX
(),
rotated
.
getY
());
ringVertices
.
add
(
v2d
);
}
return
new
Ring2d
(
ringVertices
,
lr
);
}
public
Ring2d
getExterior
()
{
return
exterior
;
}
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/ProjectionAxis.java
0 → 100644
View file @
a138df4b
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.math
;
import
java.util.Arrays
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
/**
* This class is needed for projecting rings or polygons to a 2D axis plane. It
* uses the longest component of the normal vector to determine which plane is
* the best plane to project the ring or polygon on while conserving the most
* area of the original polygon.
*
* @author Matthias Betz
*
*/
public
class
ProjectionAxis
{
private
static
final
String
DIVISOR_IS_0
=
"Divisor is 0"
;
private
int
[]
axis
;
public
static
ProjectionAxis
of
(
Polygon
p
)
{
return
getProjectionAxis
(
p
.
calculateNormal
());
}
public
static
ProjectionAxis
of
(
MovedRing
movedRing
)
{
// the normal should be the same even if the ring has moved
return
of
(
movedRing
.
getOriginal
());
}
public
static
ProjectionAxis
of
(
LinearRing
lr
)
{
return
getProjectionAxis
(
lr
.
calculateNormal
());
}
public
static
ProjectionAxis
of
(
Plane
plane
)
{
return
getProjectionAxis
(
plane
.
getNormal
());
}
/**
* Calculates the indices of the two lowest coordinate values of this vector.
* This is used to determine on which axis plane a ring or polygon should be
* projected.
*
* @param normal the normal vector, does not need to be normalized
* @return an array with the indices of the coordinate array which should be
* used in a 2d environment.
*/
private
static
ProjectionAxis
getProjectionAxis
(
Vector3d
normal
)
{
double
nx
=
Math
.
abs
(
normal
.
getX
());
double
ny
=
Math
.
abs
(
normal
.
getY
());
double
nz
=
Math
.
abs
(
normal
.
getZ
());
double
biggestValue
=
nx
;
int
[]
axis
=
new
int
[]
{
1
,
2
};
if
(
ny
>
biggestValue
)
{
biggestValue
=
ny
;
axis
[
0
]
=
0
;
axis
[
1
]
=
2
;
}
if
(
nz
>
biggestValue
)
{
axis
[
0
]
=
0
;
axis
[
1
]
=
1
;
}
return
new
ProjectionAxis
(
axis
);
}
private
ProjectionAxis
(
int
[]
axis
)
{
this
.
axis
=
axis
;
}
public
Vector2d
project
(
Vector3d
v
)
{
return
new
Vector2d
(
v
.
getCoordinate
(
axis
[
0
]),
v
.
getCoordinate
(
axis
[
1
]));
}
/**
* calculates the missing coordinate for 3d vector from the plane and this axis.
* @return the projected 3d point.
*/
public
Vector3d
projectToPlane
(
Plane
plane
,
Vector2d
v
)
{
return
projectToPlane
(
plane
,
v
.
getX
(),
v
.
getY
());
}
/**
* calculates the missing coordinate for 3d vector from the plane and this axis.