Skip to content

Commit 4849951

Browse files
committed
added Cylinder3, DistPoint3Cylinder3
1 parent 085cd5c commit 4849951

File tree

4 files changed

+233
-0
lines changed

4 files changed

+233
-0
lines changed

distance/DistPoint3Cylinder3.cs

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace g3
7+
{
8+
// ported from WildMagic 5
9+
// https://www.geometrictools.com/Downloads/Downloads.html
10+
11+
public class DistPoint3Cylinder3
12+
{
13+
Vector3d point;
14+
public Vector3d Point
15+
{
16+
get { return point; }
17+
set { point = value; DistanceSquared = -1.0; }
18+
}
19+
20+
Cylinder3d cylinder;
21+
public Cylinder3d Cylinder
22+
{
23+
get { return cylinder; }
24+
set { cylinder = value; DistanceSquared = -1.0; }
25+
}
26+
27+
public double DistanceSquared = -1.0;
28+
29+
public double SignedDistance = 0.0f;
30+
public bool IsInside { get { return SignedDistance < 0; } }
31+
32+
public Vector3d CylinderClosest;
33+
34+
35+
public DistPoint3Cylinder3(Vector3d PointIn, Cylinder3d CylinderIn )
36+
{
37+
point = PointIn; cylinder = CylinderIn;
38+
}
39+
40+
public DistPoint3Cylinder3 Compute()
41+
{
42+
GetSquared();
43+
return this;
44+
}
45+
46+
public double Get()
47+
{
48+
return Math.Sqrt(GetSquared());
49+
}
50+
51+
52+
public double GetSquared()
53+
{
54+
if (DistanceSquared >= 0)
55+
return DistanceSquared;
56+
57+
58+
if (cylinder.Height >= double.MaxValue)
59+
return get_squared_infinite();
60+
61+
62+
// Convert the point to the cylinder coordinate system. In this system,
63+
// the point believes (0,0,0) is the cylinder axis origin and (0,0,1) is
64+
// the cylinder axis direction.
65+
Vector3d basis0 = cylinder.Axis.Direction;
66+
Vector3d basis1 = Vector3d.Zero, basis2 = Vector3d.Zero;
67+
Vector3d.ComputeOrthogonalComplement(1, basis0, ref basis1, ref basis2);
68+
double height = Cylinder.Height / 2.0;
69+
70+
Vector3d delta = point - cylinder.Axis.Origin;
71+
Vector3d P = new Vector3d(basis1.Dot(delta), basis2.Dot(delta), basis0.Dot(delta));
72+
73+
double result_distance = 0; // signed!
74+
Vector3d result_closest = Vector3d.Zero;
75+
76+
double sqrRadius = cylinder.Radius * cylinder.Radius;
77+
double sqrDistance = P[0] * P[0] + P[1] * P[1];
78+
79+
// The point is outside the infinite cylinder, or on the cylinder wall.
80+
double distance = Math.Sqrt(sqrDistance);
81+
double inf_distance = distance - Cylinder.Radius;
82+
double temp = Cylinder.Radius / distance;
83+
Vector3d inf_closest = new Vector3d(temp * P.x, temp * P.y, P.z);
84+
bool bOutside = (sqrDistance >= sqrRadius);
85+
86+
result_closest = inf_closest;
87+
result_distance = inf_distance;
88+
89+
if ( inf_closest.z >= height ) {
90+
result_closest = (bOutside) ? inf_closest : P;
91+
result_closest.z = height;
92+
result_distance = result_closest.Distance(P); // TODO: only compute sqr here
93+
bOutside = true;
94+
} else if ( inf_closest.z <= -height ) {
95+
result_closest = (bOutside) ? inf_closest : P;
96+
result_closest.z = -height;
97+
result_distance = result_closest.Distance(P); // TODO: only compute sqr here
98+
bOutside = true;
99+
} else if ( bOutside == false ) {
100+
if (inf_closest.z > 0 && Math.Abs(inf_closest.z - height) < Math.Abs(inf_distance)) {
101+
result_closest = P;
102+
result_closest.z = height;
103+
result_distance = result_closest.Distance(P); // TODO: only compute sqr here
104+
} else if ( inf_closest.z < 0 && Math.Abs(inf_closest.z - -height) < Math.Abs(inf_distance) ) {
105+
result_closest = P;
106+
result_closest.z = -height;
107+
result_distance = result_closest.Distance(P); // TODO: only compute sqr here
108+
}
109+
}
110+
SignedDistance = (bOutside) ? Math.Abs(result_distance) : -Math.Abs(result_distance);
111+
112+
// Convert the closest point from the cylinder coordinate system to the
113+
// original coordinate system.
114+
CylinderClosest = cylinder.Axis.Origin +
115+
result_closest.x * basis1 +
116+
result_closest.y * basis2 +
117+
result_closest.z * basis0;
118+
119+
DistanceSquared = result_distance * result_distance;
120+
121+
return DistanceSquared;
122+
}
123+
124+
125+
126+
public double get_squared_infinite()
127+
{
128+
// Convert the point to the cylinder coordinate system. In this system,
129+
// the point believes (0,0,0) is the cylinder axis origin and (0,0,1) is
130+
// the cylinder axis direction.
131+
Vector3d basis0 = cylinder.Axis.Direction;
132+
Vector3d basis1 = Vector3d.Zero, basis2 = Vector3d.Zero;
133+
Vector3d.ComputeOrthogonalComplement(1, basis0, ref basis1, ref basis2);
134+
135+
Vector3d delta = point - cylinder.Axis.Origin;
136+
Vector3d P = new Vector3d(basis1.Dot(delta), basis2.Dot(delta), basis0.Dot(delta));
137+
138+
double result_distance = 0; // signed!
139+
Vector3d result_closest = Vector3d.Zero;
140+
141+
double sqrRadius = cylinder.Radius * cylinder.Radius;
142+
double sqrDistance = P[0] * P[0] + P[1] * P[1];
143+
144+
// The point is outside the cylinder or on the cylinder wall.
145+
double distance = Math.Sqrt(sqrDistance);
146+
result_distance = distance - Cylinder.Radius;
147+
double temp = Cylinder.Radius / distance;
148+
result_closest = new Vector3d(temp * P.x, temp * P.y, P.z);
149+
150+
151+
// Convert the closest point from the cylinder coordinate system to the
152+
// original coordinate system.
153+
CylinderClosest = cylinder.Axis.Origin +
154+
result_closest.x * basis1 +
155+
result_closest.y * basis2 +
156+
result_closest.z * basis0;
157+
SignedDistance = result_distance;
158+
DistanceSquared = result_distance * result_distance;
159+
return DistanceSquared;
160+
}
161+
162+
}
163+
}

geometry3Sharp.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<Compile Include="curve\Ellipse2.cs" />
5454
<Compile Include="curve\NURBSCurve2.cs" />
5555
<Compile Include="distance\DistPoint2Circle2.cs" />
56+
<Compile Include="distance\DistPoint3Cylinder3.cs" />
5657
<Compile Include="distance\DistPoint3Circle3.cs" />
5758
<Compile Include="implicit\ImplicitField.cs" />
5859
<Compile Include="implicit\ImplicitOperators.cs" />
@@ -89,6 +90,7 @@
8990
<Compile Include="math\Vector3d.cs" />
9091
<Compile Include="math\Vector3i.cs" />
9192
<Compile Include="math\Vector3f.cs" />
93+
<Compile Include="shapes3\Cylinder3.cs" />
9294
<Compile Include="spatial\BasicProjectionTargets.cs" />
9395
<Compile Include="queries\Distance.cs" />
9496
<Compile Include="queries\MeshQueries.cs" />

shapes3/Cylinder3.cs

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System;
2+
3+
namespace g3
4+
{
5+
// ported from GTEngine (WildMagic5 doesn't have cylinder primitive)
6+
public class Cylinder3d
7+
{
8+
// The cylinder axis is a line. The origin of the cylinder is chosen to be
9+
// the line origin. The cylinder wall is at a distance R units from the axis.
10+
// An infinite cylinder has infinite height. A finite cylinder has center C
11+
// at the line origin and has a finite height H. The segment for the finite
12+
// cylinder has endpoints C-(H/2)*D and C+(H/2)*D where D is a unit-length
13+
// direction of the line.
14+
15+
public Line3d Axis;
16+
public double Radius;
17+
public double Height;
18+
19+
public Cylinder3d(Line3d axis, double radius, double height)
20+
{
21+
Axis = axis;
22+
Radius = radius;
23+
Height = height;
24+
}
25+
public Cylinder3d(Vector3d center, Vector3d axis, double radius, double height)
26+
{
27+
Axis = new Line3d(center, axis);
28+
Radius = radius;
29+
Height = height;
30+
}
31+
public Cylinder3d(Frame3f frame, double radius, double height, int nNormalAxis = 1)
32+
{
33+
Axis = new Line3d(frame.Origin, frame.GetAxis(nNormalAxis));
34+
Radius = radius;
35+
Height = height;
36+
}
37+
public Cylinder3d(double radius, double height)
38+
{
39+
Axis = new Line3d(Vector3d.Zero, Vector3d.AxisY);
40+
Radius = radius;
41+
Height = height;
42+
}
43+
44+
45+
public double Circumference {
46+
get { return MathUtil.TwoPI * Radius; }
47+
}
48+
public double Diameter {
49+
get { return 2 * Radius; }
50+
}
51+
public double Volume {
52+
get { return Math.PI * Radius * Radius * Height; }
53+
}
54+
55+
}
56+
}

spatial/BasicProjectionTargets.cs

+12
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,16 @@ public Vector3d Project(Vector3d vPoint, int identifier = -1)
3434

3535

3636

37+
public class CylinderProjectionTarget : IProjectionTarget
38+
{
39+
public Cylinder3d Cylinder;
40+
41+
public Vector3d Project(Vector3d vPoint, int identifer = -1)
42+
{
43+
DistPoint3Cylinder3 d = new DistPoint3Cylinder3(vPoint, Cylinder);
44+
d.GetSquared();
45+
return d.CylinderClosest;
46+
}
47+
}
48+
3749
}

0 commit comments

Comments
 (0)