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
Example #2
0
    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