Distances and clearances

Distance measures how far an object is from points, edges, wires, faces, shapes and OpenCASCADE shapes, for clearances and wall thicknesses. Inside a face, the distance is 0. components returns the shortest connection itself instead of its length, in the plane with "hv" or in 3D with "xyz", and ClosestPoint returns where it starts. All examples on this page use the link from Tangents, two bosses of radius r1 = 1.5 and r2 = 1 with their centers d = 6 apart, with a hole of radius 0.6 and 0.4 in each.

[1]:
import math
import planex as px

link = px.QuickSketch()
link.Circle(0, 0, 1.5, id="boss1", construction=True)
link.Circle(6, 0, 1.0, id="boss2", construction=True)
link.Line(tangent=("boss1", "boss2"), id="upper")
link.Line(tangent=("boss1", "boss2"), reverse=True, id="lower")
link.Arc("lower", "upper", congruent="boss2", id="end2")
link.Arc("upper", "lower", congruent="boss1", id="end1")
link.Circle(0, 0, 0.6, id="hole1").Circle(6, 0, 0.4, id="hole2")
face = link.Face()
r1, r2, d = 1.5, 1.0, 6.0

Wall thickness around the holes

The distance from each hole to the outline is the wall around it, r2 − 0.4 at the small boss and r1 − 0.6 at the large one:

[3]:
print(sorted(h.Distance(face.outer) for h in face.inner), "exact", [r2 - 0.4, r1 - 0.6])
[0.5999999999999995, 0.9] exact [0.6, 0.9]

Signed distances

With signed=True, a point inside a face gets a negative distance, as in a level set. The example is the middle of the web, at (3, 0). Its nearest boundary is the two tangent lines, r1 − 3 sin α away, with sin α = (r1 − r2) / d:

[4]:
print(face.Distance((3, 0), signed=True), "exact", -(r1 - 3 * (r1 - r2) / d))
print(face.Distance((3, 0)), "unsigned, inside the face")
-1.25 exact -1.25
0.0 unsigned, inside the face

Clearance and a pin

The example has two shortest connections. Of two links stacked 4 apart, the large bosses come closest, 4 − 2 r1 = 1 apart, dashed in Figure 1a. The shortest connection from the link to a pin at (8, 0.5) runs radially from the small boss, and ClosestPoint returns where it starts, marked together with the pin in Figure 1b.

[5]:
upper = face.Translated((0, 4))
pin = (8, 0.5)
start = face.ClosestPoint(pin)
Two links 4 apart
(a) Two links 4 apart
A pin at (8, 0.5)
(b) A pin at (8, 0.5)
Figure 1: Shortest connections: between two links, and to a pin
[7]:
print("links", face.Distance(upper), face.Distance(upper, components="hv"), "exact 1")
r = math.hypot(8 - d, 0.5)
print("pin", face.Distance(pin), "exact", r - r2)
print("connection", face.Distance(pin, components="hv"), "exact", ((8 - d) * (1 - r2 / r), 0.5 * (1 - r2 / r)))
print("closest point", start)
links 1.0 (0.0, 1.0) exact 1
pin 1.0615528128088307 exact 1.0615528128088303
connection (1.0298574998546686, 0.25746437496366703) exact (1.0298574998546681, 0.25746437496366703)
closest point (6.970142500145331, 0.24253562503633294)

In 3D and projected

A point 5 above the part is 5 away. The example measures a circle of radius 1 about (10, 0), 5 above the part and to the right of the small boss, once in 3D, where it is √(2² + 5²) away, and once projected into the plane with project=True, where it is 2 away.

[8]:
import netgen.occ as occ

hoop = occ.Circle(occ.Pnt(10, 0, 5), occ.Z, 1)
print("point", face.Distance((3, 0, 5)), "exact 5")
print("circle", face.Distance(hoop), "exact", math.sqrt(2**2 + 5**2))
print("circle projected", face.Distance(hoop, project=True), "exact 2")
point 5.0 exact 5
circle 5.385164807134504 exact 5.385164807134504
circle projected 2.0 exact 2