Added arcToHelix.

This commit is contained in:
Markus Lampert 2016-12-05 04:30:49 -08:00
parent 198ab6db2e
commit a3ae53a82b
3 changed files with 111 additions and 9 deletions

View File

@ -267,7 +267,20 @@ class Tag:
# if we have no core the tip is the origin of the Tag
line = Part.Edge(self.tag.centerLine())
debugEdge(line, "------- center line", 'P0')
i = DraftGeomUtils.findIntersection(line, edge, True)
if type(edge.Curve) != Part.Circle and type(edge.Curve) != Part.Line:
p1 = edge.valueAt(edge.FirstParameter)
p2 = edge.valueAt((edge.FirstParameter + edge.LastParameter)/2)
p3 = edge.valueAt(edge.LastParameter)
p1.z = 0
p2.z = 0
p3.z = 0
arc = Part.Edge(Part.Arc(p1, p2, p3))
aps = DraftGeomUtils.findIntersection(line, arc)
for p in aps:
print("%s - p=%.2f" % (p, arc.Curve.parameter(p)))
i = [edge.valueAt(arc.Curve.parameter(p)) for p in aps]
else:
i = DraftGeomUtils.findIntersection(line, edge)
#i = line.Curve.intersect(edge)
if i:
debugPrint('P0', '------- P0 split @ (%.2f, %.2f, %.2f)' % (i[0].x, i[0].y, i[0].z))
@ -371,16 +384,53 @@ class Tag:
def splitEdgeAt(self, edge, pt):
p = edge.Curve.parameter(pt)
# I'm getting rather tired of this interface, so I decided to implement this myself.
# How hard can it be?
# There are only 3 types of edges passing through here, Line, Circle and Helix ...
if False:
p = edge.Curve.parameter(pt)
#p = edge.parameterAt(Part.Vertex(pt.x, pt.y, pt.z))
pf = edge.valueAt(edge.FirstParameter)
pl = edge.valueAt(edge.LastParameter)
print("-------- splitAt((%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f): (%.2f, %.2f, %.2f)) -> param[%.2f -> %.2f]: %.2f" % (pf.x, pf.y, pf.z, pl.x, pl.y, pl.z, pt.x, pt.y, pt.z, edge.FirstParameter, edge.LastParameter, p))
pf = edge.valueAt(edge.FirstParameter)
pl = edge.valueAt(edge.LastParameter)
print("-------- splitAt((%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f): (%.2f, %.2f, %.2f)) -> param[%.2f -> %.2f]: %.2f" % (pf.x, pf.y, pf.z, pl.x, pl.y, pl.z, pt.x, pt.y, pt.z, edge.FirstParameter, edge.LastParameter, p))
wire = edge.split(p)
# split does not carry the Placement of the original curve foward ...
wire.transformShape(edge.Placement.toMatrix())
return wire.Edges
print("-------- splitAt(%.2f <= %.2f <= %.2f" % (edge.FirstParameter, p, edge.LastParameter))
wire = edge.split(p)
# split does not carry the Placement of the original curve foward ...
wire.transformShape(edge.Placement.toMatrix())
return wire.Edges
p1 = edge.valueAt(edge.FirstParameter)
p2 = pt
p3 = edge.valueAt(edge.LastParameter)
edges = []
if type(edge.Curve) == Part.Line or type(edge.Curve) == Part.LineSegment:
edges.append(Part.LineSegment(p1, p2))
edges.append(Part.LineSegment(p2, p3))
elif type(edge.Curve) == Part.Circle:
# it's an arc
p = edge.Curve.parameterAt(p2)
p12 = edge.Curve.value((edge.Curve.FirstParameter + p)/2)
p23 = edge.Curve.value((p + edge.Curve.LastParameter)/2)
edges.append(Part.Edge(Part.Arc(p1, p12, p2)))
edges.append(Part.Edge(Part.Arc(p2, p23, p3)))
else:
# it's a helix
# convert to arc
p01 = FreeCAD.Vector(p1.x, p1.y, 0)
p02 = FreeCAD.Vector(p2.x, p2.y, 0)
p03 = FreeCAD.Vector(p3.x, p3.y, 0)
e0 = Part.Edge(Part.Arc(p01, p02, p03))
# split arc
p0 = e0.Curve.parameterAt(p02)
p012 = e0.Curve.value((e0.Curve.FirstParameter + p0)/2)
p023 = e0.Curve.value((p0 + e0.Curve.LastParameter)/2)
e01 = Part.Edge(Part.Arc(p01, p012, p02))
e02 = Part.Edge(Part.Arc(p02, p023, p03))
# transform arcs into helical form
edges.append(self.arcToHelix(e01, p1.z, p2.z))
edges.append(self.arcToHelix(e02, p2.z, p3.z))
return edges
def mapEdgeToSolid(self, edge, label):
pf = edge.valueAt(edge.FirstParameter)

View File

@ -213,3 +213,28 @@ class PathGeom:
wires.append(Part.Wire(edges))
return wires
@classmethod
def arcToHelix(cls, edge, z0, z1):
m = FreeCAD.Matrix()
m.unity()
p1 = edge.valueAt(edge.FirstParameter)
p2 = edge.valueAt(edge.LastParameter)
z = p1.z
pd = p2 - p1
dz = z1 - z0
#print("arcToHelix(%.2f, %.2f): dz=%.2f, dy=%.2f, z=%.2f" % (z0 ,z1, dz, pd.y, z))
m.A32 = dz / pd.y
m.A34 = - m.A32
if dz < 0:
m.A34 *= p2.y
m.A34 += z1 - z
else:
m.A34 *= p1.y
m.A34 += z0 - z
e = edge.transformGeometry(m).Edges[0]
return e

View File

@ -145,3 +145,30 @@ class TestPathGeom(PathTestBase):
self.assertEqual(len(wires[1].Edges), 1)
self.assertLine(wires[1].Edges[0], Vector(0,1,0), Vector(0,0,0))
def test60(self):
"""Verify arcToHelix returns proper helix."""
p1 = Vector(10,-10,0)
p2 = Vector(0,0,0)
p3 = Vector(10,10,0)
e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 0, 2)
self.assertCurve(e, p1, p2 + Vector(0,0,1), p3 + Vector(0,0,2))
e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 3, 7)
self.assertCurve(e, p1 + Vector(0,0,3), p2 + Vector(0,0,5), p3 + Vector(0,0,7))
e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 9, 1)
self.assertCurve(e, p1 + Vector(0,0,9), p2 + Vector(0,0,5), p3 + Vector(0,0,1))
dz = Vector(0,0,3)
p11 = p1 + dz
p12 = p2 + dz
p13 = p3 + dz
e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p11, p12, p13)), 0, 8)
self.assertCurve(e, p1, p2 + Vector(0,0,4), p3 + Vector(0,0,8))
e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p11, p12, p13)), 2, -2)
self.assertCurve(e, p1 + Vector(0,0,2), p2, p3 + Vector(0,0,-2))