Skip to content

Instantly share code, notes, and snippets.

@MisterRager
Last active August 21, 2018 14:34
Show Gist options
  • Save MisterRager/7cb190d4e11c92cd7e5fa3bdf7c4b08c to your computer and use it in GitHub Desktop.
Save MisterRager/7cb190d4e11c92cd7e5fa3bdf7c4b08c to your computer and use it in GitHub Desktop.
OSWG Profile Generation
import math
import FreeCAD, FreeCADGui, Part
# R(x) = sqrt(R0^2 + 2*R0*tan(F)*x + (tan(A)*x)^2)
#
# x .. distance from the throat along the WG axis
# R(x) .. radius of the WG at x
# R0 .. radius of the WG at the throat
# A .. coverage angle
# F .. initial angle
#
class OSWGProfile:
def __init__(self, throatRadius, throatAngleDegrees, coverageAngleDegreesVertical, coverageAngleDegreesHorizontal, depth, resolution = 32):
self.throatRadius= throatRadius
self.throatAngle = math.radians(throatAngleDegrees)
self.coverageAngleVertical = math.radians(coverageAngleDegreesVertical)
self.coverageAngleHorizontal = math.radians(coverageAngleDegreesHorizontal)
self.depth = depth
self.resolution = resolution
def _radius_at(self, coverageAngle, distance):
return math.sqrt(
math.pow(self.throatRadius, 2) +
(2 * self.throatRadius * math.tan(self.throatAngle) * distance) +
math.pow(math.tan(coverageAngle) * distance, 2)
)
def _gen_profile(self, angle):
return map(
lambda distance: (distance, self._radius_at(angle, distance)),
map(
lambda step: float(step) / self.resolution,
range(self.depth * self.resolution + 1))
)
def _profile_vectors(self, angle, (direction_x, direction_y)):
return map(
lambda (distance, radius): (direction_x * radius, direction_y * radius, distance),
self._gen_profile(angle)
)
def top_profile(self):
return self._profile_vectors(self.coverageAngleVertical, (0, 1))
def bottom_profile(self):
return self._profile_vectors(self.coverageAngleVertical, (0, -1))
def left_profile(self):
return self._profile_vectors(self.coverageAngleHorizontal, (-1, 0))
def right_profile(self):
return self._profile_vectors(self.coverageAngleHorizontal, (1, 0))
def horizontal_mouth_size(self):
return self._radius_at(self.coverageAngleHorizontal, self.depth)
def vertical_mouth_size(self):
return self._radius_at(self.coverageAngleVertical, self.depth)
def buildPolygon(pointList):
curve = Part.BSplineCurve()
curve.interpolate(map(
lambda (x,y,z): FreeCAD.Vector(x,y,z),
pointList
))
return Part.Wire(curve.toShape())
'''
return Part.makePolygon(
map(
lambda (x,y,z): FreeCAD.Vector(x,y,z),
pointList
)
)
'''
# curve = Part.BezierCurve()
# print pointList
# vectors = map(
# lambda (x, y, z): FreeCAD.Vector(x, y, z),
# pointList)
# curve.setPoles(vectors)
# return curve.toShape()
waveguide = OSWGProfile(
12.7,
5,
40,
60,
100,
50
)
FreeCAD.ActiveDocument.addObject('Part::Feature', 'OSWG-curve-top').Shape = buildPolygon(waveguide.top_profile())
FreeCAD.ActiveDocument.addObject('Part::Feature', 'OSWG-curve-bottom').Shape = buildPolygon(waveguide.bottom_profile())
FreeCAD.ActiveDocument.addObject('Part::Feature', 'OSWG-curve-left').Shape = buildPolygon(waveguide.left_profile())
FreeCAD.ActiveDocument.addObject('Part::Feature', 'OSWG-curve-right').Shape = buildPolygon(waveguide.right_profile())
throat = FreeCAD.ActiveDocument.addObject('Part::Circle', 'OSWG-throat')
throat.Radius = waveguide.throatRadius
mouth = FreeCAD.ActiveDocument.addObject('Part::Ellipse', 'OSWG-mouth')
mouth.MinorRadius = waveguide.vertical_mouth_size()
mouth.MajorRadius = waveguide.horizontal_mouth_size()
mouth.Placement.move(FreeCAD.Vector(0, 0, waveguide.depth))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment