Skip to content

Commit 8b48cd0

Browse files
committed
added Circle3, point/circle 2d/3d distances
1 parent ea98fad commit 8b48cd0

File tree

4 files changed

+253
-0
lines changed

4 files changed

+253
-0
lines changed

distance/DistPoint2Circle2.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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's DistPoint3Circle3 (didn't have point2circle2)
9+
// https://www.geometrictools.com/Downloads/Downloads.html
10+
11+
public class DistPoint2Circle2
12+
{
13+
Vector2d point;
14+
public Vector2d Point
15+
{
16+
get { return point; }
17+
set { point = value; DistanceSquared = -1.0; }
18+
}
19+
20+
Circle2d circle;
21+
public Circle2d Circle
22+
{
23+
get { return circle; }
24+
set { circle = value; DistanceSquared = -1.0; }
25+
}
26+
27+
public double DistanceSquared = -1.0;
28+
29+
public Vector2d CircleClosest;
30+
public bool AllCirclePointsEquidistant;
31+
32+
33+
public DistPoint2Circle2(Vector2d PointIn, Circle2d circleIn )
34+
{
35+
point = PointIn; circle = circleIn;
36+
}
37+
38+
public DistPoint2Circle2 Compute()
39+
{
40+
GetSquared();
41+
return this;
42+
}
43+
44+
public double Get()
45+
{
46+
return Math.Sqrt(GetSquared());
47+
}
48+
49+
50+
public double GetSquared()
51+
{
52+
if (DistanceSquared >= 0)
53+
return DistanceSquared;
54+
55+
// Projection of P-C onto plane is Q-C = P-C - Dot(N,P-C)*N.
56+
Vector2d PmC = point - circle.Center;
57+
double lengthPmC = PmC.Length;
58+
if (lengthPmC > 0) {
59+
CircleClosest = circle.Center + circle.Radius * PmC / lengthPmC;
60+
AllCirclePointsEquidistant = false;
61+
} else {
62+
// All circle points are equidistant from P. Return one of them.
63+
CircleClosest = circle.Center + circle.Radius;
64+
AllCirclePointsEquidistant = true;
65+
}
66+
67+
Vector2d diff = point - CircleClosest;
68+
double sqrDistance = diff.Dot(diff);
69+
70+
// Account for numerical round-off error.
71+
if (sqrDistance < 0) {
72+
sqrDistance = 0;
73+
}
74+
DistanceSquared = sqrDistance;
75+
return sqrDistance;
76+
}
77+
}
78+
}

distance/DistPoint3Circle3.cs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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 DistPoint3Circle3
12+
{
13+
Vector3d point;
14+
public Vector3d Point
15+
{
16+
get { return point; }
17+
set { point = value; DistanceSquared = -1.0; }
18+
}
19+
20+
Circle3d circle;
21+
public Circle3d Circle
22+
{
23+
get { return circle; }
24+
set { circle = value; DistanceSquared = -1.0; }
25+
}
26+
27+
public double DistanceSquared = -1.0;
28+
29+
public Vector3d CircleClosest;
30+
public bool AllCirclePointsEquidistant;
31+
32+
33+
public DistPoint3Circle3(Vector3d PointIn, Circle3d circleIn )
34+
{
35+
point = PointIn; circle = circleIn;
36+
}
37+
38+
public DistPoint3Circle3 Compute()
39+
{
40+
GetSquared();
41+
return this;
42+
}
43+
44+
public double Get()
45+
{
46+
return Math.Sqrt(GetSquared());
47+
}
48+
49+
50+
public double GetSquared()
51+
{
52+
if (DistanceSquared >= 0)
53+
return DistanceSquared;
54+
55+
// Projection of P-C onto plane is Q-C = P-C - Dot(N,P-C)*N.
56+
Vector3d PmC = point - circle.Center;
57+
Vector3d QmC = PmC - circle.Normal.Dot(PmC) * circle.Normal;
58+
double lengthQmC = QmC.Length;
59+
if (lengthQmC > 0) {
60+
CircleClosest = circle.Center + circle.Radius * QmC / lengthQmC;
61+
AllCirclePointsEquidistant = false;
62+
} else {
63+
// All circle points are equidistant from P. Return one of them.
64+
CircleClosest = circle.Center + circle.Radius * circle.AxisX;
65+
AllCirclePointsEquidistant = true;
66+
}
67+
68+
Vector3d diff = point - CircleClosest;
69+
double sqrDistance = diff.Dot(diff);
70+
71+
// Account for numerical round-off error.
72+
if (sqrDistance < 0) {
73+
sqrDistance = 0;
74+
}
75+
DistanceSquared = sqrDistance;
76+
return sqrDistance;
77+
}
78+
}
79+
}

geometry3Sharp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
<Compile Include="curve\Circle2.cs" />
5353
<Compile Include="curve\Ellipse2.cs" />
5454
<Compile Include="curve\NURBSCurve2.cs" />
55+
<Compile Include="distance\DistPoint3Circle3.cs" />
5556
<Compile Include="implicit\ImplicitField.cs" />
5657
<Compile Include="implicit\ImplicitOperators.cs" />
5758
<Compile Include="implicit\MarchingQuads.cs" />
@@ -145,6 +146,7 @@
145146
<Compile Include="intersection\IntrLine3Box3.cs" />
146147
<Compile Include="intersection\IntrSegment3Box3.cs" />
147148
<Compile Include="intersection\IntrRay3Box3.cs" />
149+
<Compile Include="shapes3\Circle3.cs" />
148150
<Compile Include="spatial\DMeshAABBTree.cs" />
149151
<Compile Include="spatial\MeshProjectionTarget.cs" />
150152
<Compile Include="spatial\SpatialInterfaces.cs" />

shapes3/Circle3.cs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using System;
2+
3+
namespace g3
4+
{
5+
public class Circle3d
6+
{
7+
// The plane containing the circle is Dot(N,X-C) = 0, where X is any point
8+
// in the plane. Vectors U, V, and N form an orthonormal right-handed set
9+
// (matrix [U V N] is orthonormal and has determinant 1). The circle
10+
// within the plane is parameterized by X = C + R*(cos(t)*U + sin(t)*V),
11+
// where t is an angle in [-pi,pi).
12+
13+
public Vector3d Center;
14+
public Vector3d Normal;
15+
public Vector3d AxisX, AxisY;
16+
public double Radius;
17+
public bool IsReversed; // use ccw orientation instead of cw
18+
19+
public Circle3d(Vector3d center, Vector3d axis0, Vector3d axis1, Vector3d normal, double radius)
20+
{
21+
IsReversed = false;
22+
Center = center;
23+
Normal = normal;
24+
AxisX = axis0;
25+
AxisY = axis1;
26+
Radius = radius;
27+
}
28+
29+
30+
public bool IsClosed {
31+
get { return true; }
32+
}
33+
34+
public void Reverse() {
35+
IsReversed = ! IsReversed;
36+
}
37+
38+
39+
// angle in range [0,360] (but works for any value, obviously)
40+
public Vector3d SampleDeg(double degrees)
41+
{
42+
double theta = degrees * MathUtil.Deg2Rad;
43+
double c = Math.Cos(theta), s = Math.Sin(theta);
44+
return Center + c * Radius * AxisX + s * Radius * AxisY;
45+
}
46+
47+
// angle in range [0,2pi] (but works for any value, obviously)
48+
public Vector3d SampleRad(double radians)
49+
{
50+
double c = Math.Cos(radians), s = Math.Sin(radians);
51+
return Center + c * Radius * AxisX + s * Radius * AxisY;
52+
}
53+
54+
55+
56+
public double ParamLength {
57+
get { return 1.0f; }
58+
}
59+
60+
// t in range[0,1] spans circle [0,2pi]
61+
public Vector3d SampleT(double t) {
62+
double theta = (IsReversed) ? -t*MathUtil.TwoPI : t*MathUtil.TwoPI;
63+
double c = Math.Cos(theta), s = Math.Sin(theta);
64+
return Center + c * Radius * AxisX + s * Radius * AxisY;
65+
}
66+
67+
public bool HasArcLength { get {return true;} }
68+
69+
public double ArcLength {
70+
get {
71+
return MathUtil.TwoPI * Radius;
72+
}
73+
}
74+
75+
public Vector3d SampleArcLength(double a) {
76+
double t = a / ArcLength;
77+
double theta = (IsReversed) ? -t*MathUtil.TwoPI : t*MathUtil.TwoPI;
78+
double c = Math.Cos(theta), s = Math.Sin(theta);
79+
return Center + c * Radius * AxisX + s * Radius * AxisY;
80+
}
81+
82+
83+
public double Circumference {
84+
get { return MathUtil.TwoPI * Radius; }
85+
}
86+
public double Diameter {
87+
get { return 2 * Radius; }
88+
}
89+
public double Area {
90+
get { return Math.PI * Radius * Radius; }
91+
}
92+
93+
}
94+
}

0 commit comments

Comments
 (0)