def FuselageOML(NoseLengthRatio=0.182, TailLengthRatio=0.293, Scaling=[55.902, 55.902, 55.902], NoseCoordinates=[0, 0, 0], CylindricalMidSection=False, SimplificationReqd=False): # Instantiates a parametric fuselage outer mould line (OML) geometry for a given # set of design variables. FuselageOMLSurf, SternPoint = _BuildFuselageOML(NoseLengthRatio, TailLengthRatio, CylindricalMidSection, SimplificationReqd) if not (FuselageOMLSurf) or FuselageOMLSurf is None: return ScalingF = [0, 0, 0] ScalingF[0] = Scaling[0] / 55.902 ScalingF[1] = Scaling[1] / 55.902 ScalingF[2] = Scaling[2] / 55.902 # Overall scaling FuselageOMLSurf = act.ScaleObjectWorld000(FuselageOMLSurf, ScalingF) # A few other ways of performing the scaling... # Variant one: this depends on the current CPlane! # FuselageOMLSurf = rs.ScaleObject(FuselageOMLSurf, (0,0,0), Scaling) # Variant two: define plane in World coordinates #P = rs.PlaneFromFrame((0,0,0),(1,0,0),(0,1,0)) #TransfMatrix = Rhino.Geometry.Transform.Scale(P, Scaling[0], Scaling[1], Scaling[2]) #FuselageOMLSurf = rs.TransformObjects(FuselageOMLSurf, TransfMatrix) # Variant three: World coordinate system based scaling #xform = rs.XformScale(Scaling) #FuselageOMLSurf = rs.TransformObjects(FuselageOMLSurf, xform) SternPoint[0] = SternPoint[0] * ScalingF[0] SternPoint[1] = SternPoint[1] * ScalingF[1] SternPoint[2] = SternPoint[2] * ScalingF[2] # Positioning MoveVec = rs.VectorCreate(NoseCoordinates, [0, 0, 0]) FuselageOMLSurf = rs.MoveObject(FuselageOMLSurf, MoveVec) SternPoint[0] = SternPoint[0] + NoseCoordinates[0] SternPoint[1] = SternPoint[1] + NoseCoordinates[1] SternPoint[2] = SternPoint[2] + NoseCoordinates[2] return FuselageOMLSurf, SternPoint
def _TransformAirfoil(self, C): # Internal function. Given a normal airfoil, unit chord, nose in origin, # chord along x axis, applies scaling, rotations, positioning and smoothing # Smoothing for i in range(1, self.SmoothingIterations + 1): rs.FairCurve(C) # Find the actual leading edge point - the airfoil may have stretched as # as a result of the smoothing or it may have been incorrectly defined # through a series of coordinates RefLine = rs.AddLine((-100, 0, -100), (-100, 0, 100)) ClosestPoints = rs.CurveClosestObject(RefLine, C) P = rs.AddPoint(ClosestPoints[1]) MoveVec = rs.VectorCreate((0, 0, 0), P) rs.MoveObject(C, MoveVec) # Garbage collection rs.DeleteObjects((RefLine, P)) # Now find the trailing edge points PUpper = rs.CurveStartPoint(C) PLower = rs.CurveEndPoint(C) TECentre = ((PUpper[0] + PLower[0]) / 2, (PUpper[1] + PLower[1]) / 2, (PUpper[2] + PLower[2]) / 2) if PUpper[2] < PLower[2]: print "Warning: the upper and lower surface intersect at the TE." TECentrePoint = rs.AddPoint(TECentre) AxisOfRotation = rs.VectorCreate((0, 0, 0), (0, 1, 0)) L1 = rs.AddLine((0, 0, 0), (1, 0, 0)) L2 = rs.AddLine((0, 0, 0), TECentrePoint) AngRot = rs.Angle2(L1, L2) # The angle returned by Angle2 is always positive so: if TECentre[2] < 0: rs.RotateObject(C, (0, 0, 0), AngRot[0], AxisOfRotation) else: rs.RotateObject(C, (0, 0, 0), -AngRot[0], AxisOfRotation) # Garbage collection rs.DeleteObjects((TECentrePoint, L1, L2)) # Find the trailing edge point again after rotating it onto the x axis PUpper = rs.CurveStartPoint(C) PLower = rs.CurveEndPoint(C) TECentre = [(PUpper[0] + PLower[0]) / 2, (PUpper[1] + PLower[1]) / 2, (PUpper[2] + PLower[2]) / 2] ActualChordLength = TECentre[0] # Scale the airfoil to unit chord #rs.ScaleObject(C, (0,0,0), (1/ActualChordLength, 1, 1/ActualChordLength)) act.ScaleObjectWorld000( C, (1 / ActualChordLength, 1, 1 / ActualChordLength)) # Now we can assume that airfoil is normalised to the unit chord, with # its leading edge in the origin, trailing edge in (1,0,0) Chrd = rs.AddLine((0, 0, 0), (1, 0, 0)) # Scaling ScaleFact = (self.ChordLength, self.ChordLength, self.ChordLength) # same as rs.ScaleObject(C, (0,0,0), ScaleFact) act.ScaleObjectWorld000(C, ScaleFact) # same as rs.ScaleObject(Chrd, (0,0,0), ScaleFact) act.ScaleObjectWorld000(Chrd, ScaleFact) # Twist rs.RotateObject(C, (0, 0, 0), self.Twist, rs.VectorCreate((0, 0, 0), (0, 1, 0))) rs.RotateObject(Chrd, (0, 0, 0), self.Twist, rs.VectorCreate((0, 0, 0), (0, 1, 0))) # Dihedral rs.RotateObject(C, (0, 0, 0), -self.Rotation, rs.VectorCreate((0, 0, 0), (1, 0, 0))) rs.RotateObject(Chrd, (0, 0, 0), -self.Rotation, rs.VectorCreate((0, 0, 0), (1, 0, 0))) # 3d positioning MoveVec = rs.VectorCreate(self.LeadingEdgePoint, (0, 0, 0)) rs.MoveObject(C, MoveVec) rs.MoveObject(Chrd, MoveVec) return C, Chrd