Last active
August 21, 2018 14:34
-
-
Save MisterRager/7cb190d4e11c92cd7e5fa3bdf7c4b08c to your computer and use it in GitHub Desktop.
OSWG Profile Generation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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