Пример #1
0
        public void ComputeFaces()
        {
            for (int i = 0; i < Faces.Count; ++i)
            {
                Winding winding = new Winding(Faces[i].GetPlane());

                for (int j = 0; j < Faces.Count; ++j)
                {
                    if (j == i)
                        continue;
                    Winding result = winding.Clip(Faces[j].GetPlane());
                    if (result != null)
                        winding.Set(result);
                }
                if (winding.Fix())
                {
                    foreach (Vector3 v in winding)
                    {
                        Faces[i].Vertices.Add(v);
                    }
                    Faces[i].CalculateIndices();
                }
                else
                {
                    throw new Exception("Unable to fix winding");
                }
            }
        }
Пример #2
0
    void HandleDrawing()
    {
        TimeTillReload -= Time.deltaTime;
        if (TimeTillReload <= 0)
        {
            loopState = LoopState.TERMINATED;
            //Play The "empty gun" sound
            loopManager.PlayEmpty();
            return;
        }

        loopTimer         = Time.time + loopDuration;
        currMousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        if (Vector2.Distance(currMousePosition, prevMousePosition) > minDistanceMoved)
        {
            segments = CalculateSegments();
            winding  = LoopUtils.CalculateWinding(segments);

            if (Time.time > mouseDetectionTimer)
            {
                mouseDetectionTimer = Time.time + mouseDetectionInterval;
                if (points.Count >= maxSegments && points.Count > 0)
                {
                    points.RemoveAt(0);
                }
                points.Add(currMousePosition);
            }
            prevMousePosition = currMousePosition;
        }
    }
Пример #3
0
    public override int[] getMeshTris(int vertexCount, Winding winding, Vector2 completion, bool closed = false)
    {
        List <int> tris = new List <int>();

        for (int i = 0; i < vertexCount / 2; i++)
        {
            if (i != vertexCount / 2 - 1 || (closed && completion.magnitude == 1.0f))
            {
                //First Triangle
                tris.Add(i * 2);
                tris.Add(((i + 1) * 2) % vertexCount);
                tris.Add((i * 2) + 1);
                //Second Triangle
                tris.Add((i * 2) + 1);
                tris.Add(((i + 1) * 2) % vertexCount);
                tris.Add(((i + 1) * 2 + 1) % vertexCount);
            }
        }
        if (winding == Winding.INVERTED)
        {
            tris.Reverse();
        }
        else if (winding == Winding.TWOFACING)
        {
            int[] reverseTris = new int[tris.Count];
            tris.CopyTo(reverseTris);
            tris.AddRange(reverseTris);
        }
        return(tris.ToArray());
    }
 public void ForceWinding(Winding wind)
 {
     if (Winding() != wind)
     {
         vertices.Reverse();
     }
 }
Пример #5
0
        internal Path(Winding winding, PixelRatio pixelRatio)
        {
            Winding     = winding;
            _pixelRatio = pixelRatio;

            _bounds = new Box2D <float>(new Vector2D <float>(1e6f, 1e6f), new Vector2D <float>(-1e6f, -1e6f));
        }
Пример #6
0
        /// <summary>
        /// Extension method for a Winding to get the losses at the lowest tap. Optional parameter to set the operating temperature to get the losses at.
        /// </summary>
        /// <param name="winding">Winding to operate on.</param>
        /// <param name="operatingTemperature">Optional; temperature at which the losses should be calculated at.</param>
        /// <returns>Value of the losses at the windings lowest tap.</returns>
        public static double LowestTapLosses(this Winding winding, double operatingTemperature = 20)
        {
            // This is assuming that TapVoltages is in ascending order; currently I dont think there is any enforcement on this though.
            double lowestVoltage = winding.TapVoltages.First();
            // The lowest voltage/tap must be in the first section, either inside or at the end.
            // Resistance would be lowestVoltage / Section Ending Voltage * Section Resistance.
            double resistance = lowestVoltage / winding.Sections.First().EndingVoltage *winding.Sections.First().Resistance;
            double current    = winding.CalcedVA / winding.PhaseVoltage;

            double wireConst = winding.Sections.First().Wire.TemperatureChangeFactor;

            return(Math.Pow(current, 2) * resistance * ((wireConst + operatingTemperature) / (wireConst + 20)));
        }
Пример #7
0
    /// <summary>
    /// Finish adding vertices to this JeloClosedShape, and choose whether to convert into local space.
    /// JelloClosedShape.winding and JelloClosedShape.Triangles will be set.
    /// Make sure there are no duplicate points before calling this. use JelloShapeTools.RemoveDuplicatePoints().
    /// </summary>
    /// <param name="recenter">whether to convert the positions of the JelloClosedShape into local space.</param>
    ///
    /// <dl class="example"><dt>Example</dt></dl>
    /// ~~~{.c}
    /// //Create a closed shape square
    /// JelloClosedShape shape = new JelloClosedShape();
    ///
    /// shape.begin();
    ///
    /// shape.addPoint(new Vector2(-1,1));	//top left
    /// shape.addPoint(new Vector2(-1,1));	//top right
    /// shape.addPoint(new Vector2(-1,1));	//bottom right
    /// shape.addPoint(new Vector2(-1,1));	//bottom left
    ///
    /// shape.finish();
    /// ~~~
    public void finish(bool recenter = true)
    {
        if (mInternalVertices != null && mInternalVertices.Length > 0)
        {
            //dont allow duplicate points
            mInternalVertices = JelloShapeTools.RemoveDuplicatePoints(mInternalVertices);

            //dont allow points outside of the perimiter
            for (int i = 0; i < mInternalVertices.Length; i++)
            {
                if (!JelloShapeTools.Contains(mEdgeVertices, mInternalVertices[i]))
                {
                    mInternalVertices[i] = Vector2.one * Mathf.Infinity;
                }
            }
            //dont allow points on the perimiter. (this will also remove any null points)
            mInternalVertices = JelloShapeTools.RemovePointsOnPerimeter(mEdgeVertices, mInternalVertices);
        }

        mCenter = JelloShapeTools.FindCenter(mEdgeVertices);

        if (recenter)
        {
            // now subtract this from each element, to get proper "local" coordinates.
            for (int i = 0; i < mEdgeVertices.Length; i++)
            {
                mEdgeVertices[i] -= mCenter;
            }
            if (mInternalVertices != null)
            {
                for (int i = 0; i < mInternalVertices.Length; i++)
                {
                    mInternalVertices[i] -= mCenter;
                }
            }
        }

        if (JelloShapeTools.HasClockwiseWinding(mEdgeVertices))
        {
            winding = Winding.Clockwise;
        }
        else
        {
            winding = Winding.CounterClockwise;
        }



        Triangulate();
    }
Пример #8
0
        private void FillBasinReq(SweepContext tcx, Node node)
        {
            // if shallow stop filling
            if (IsShallow(tcx, node))
            {
                return;
            }

            Fill(tcx, node);

            if (node.Prev == tcx.Basin.LeftNode && node.Next == tcx.Basin.RightNode)
            {
                return;
            }
            else if (node.Prev == tcx.Basin.LeftNode)
            {
                Winding o = TriUtil.Orient2d(node.Point, node.Next.Point, node.Next.Next.Point);
                if (o == Winding.CW)
                {
                    return;
                }

                node = node.Next;
            }
            else if (node.Next == tcx.Basin.RightNode)
            {
                Winding o = TriUtil.Orient2d(node.Point, node.Prev.Point, node.Prev.Prev.Point);
                if (o == Winding.CCW)
                {
                    return;
                }

                node = node.Prev;
            }
            else
            {
                // Continue with the neighbor node with lowest Y value
                if (node.Prev.Point.Y < node.Next.Point.Y)
                {
                    node = node.Prev;
                }
                else
                {
                    node = node.Next;
                }
            }

            FillBasinReq(tcx, node);
        }
Пример #9
0
 private Winding ApplyInvert(bool invertNext, Winding direction)
 {
     if (invertNext)
     {
         if (direction == Winding.CCW)
         {
             direction = Winding.CW;
         }
         else if (direction == Winding.CW)
         {
             direction = Winding.CCW;
         }
     }
     return(direction);
 }
Пример #10
0
    void HandleEffect()
    {
        segments = CalculateSegments();
        winding  = LoopUtils.CalculateWinding(segments);

        if (Time.time > loopTimer)
        {
            if (points.Count > 0)
            {
                points.RemoveAt(0);
            }
            if (points.Count == 0)
            {
                loopState = LoopState.TERMINATED;
            }
        }
    }
Пример #11
0
        private TriPoint NextFlipPoint(TriPoint ep, TriPoint eq, Triangle ot, TriPoint op)
        {
            Winding o2d = TriUtil.Orient2d(eq, op, ep);

            if (o2d == Winding.CW)
            {
                // Right
                return(ot.PointCCW(op));
            }
            else if (o2d == Winding.CCW)
            {
                // Left
                return(ot.PointCW(op));
            }

            throw new NotSupportedException("[Unsupported] Opposing point on constrained edge");
        }
Пример #12
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="specification">Specification for the design, used to get operating frequency.</param>
 /// <param name="core">Core to be used in this design.</param>
 /// <param name="rotatedTube">Whether or not the tube to be used is rotated or not.</param>
 /// <param name="tube">Tube to be placed over core legs.</param>
 /// <param name="windings">Windings that will be used in this design.</param>
 /// <param name="uiStyle">Optional, how the windings will be connected if a UI core is used.</param>
 protected internal Design(Specification specification, Core core, bool rotatedTube, Tube tube, List <Winding> windings, UIStyle uiStyle = UIStyle.NA)
 {
     this.CompensationFactor = 1.02;
     this.Specification      = specification;
     this.Core        = core;
     this.RotatedTube = rotatedTube;
     this.Tube        = tube;
     this.Windings    = new List <Winding>();
     foreach (var w in windings)
     {
         Winding wind = new Winding(w);
         this.Windings.Add(wind);
     }
     Nulled  = false;
     Passed  = false;
     UIStyle = uiStyle;
 }
Пример #13
0
    /// <summary>
    /// Flip the JelloClosedShape verticaly.
    /// </summary>
    ///
    /// <dl class="example"><dt>Example</dt></dl>
    /// ~~~{.c}
    /// //turn a body around when it hits a ceiling
    ///
    /// JelloBody body;
    /// void handleCollisionEnter(JelloCollisionManifold manifold)
    /// {
    ///     if(manifold.GetOtherBody(body).gameObject.tag == "ceiling")
    ///     {
    ///         body.flipY();
    ///         //also reverse movement direction
    ///     }
    /// }
    /// ~~~
    public void flipY()     //TODO check into this --> will i need to retriangulate? because mesh triangles may need to always be wound in a certain direction.
    {
        Vector2[] tempVertices = new  Vector2[mEdgeVertices.Length];

        for (int i = 0; i < mEdgeVertices.Length; i++)
        {
            mEdgeVertices[i] = new Vector2(mEdgeVertices[i].x, mEdgeVertices[i].y + 2 * (Center.x - mEdgeVertices[i].x));
            tempVertices[mEdgeVertices.Length - i - 1] = mEdgeVertices[i];
        }

        mEdgeVertices = tempVertices;


        tempVertices = new  Vector2[mInternalVertices.Length];

        for (int i = 0; i < mInternalVertices.Length; i++)
        {
            mInternalVertices[i] = new Vector2(mInternalVertices[i].x, mInternalVertices[i].y + 2 * (Center.x - mInternalVertices[i].x));
            tempVertices[mInternalVertices.Length - i - 1] = mInternalVertices[i];
        }

        mInternalVertices = tempVertices;

        if (winding == Winding.Clockwise)
        {
            winding = Winding.CounterClockwise;
        }
        else if (winding == Winding.CounterClockwise)
        {
            winding = Winding.Clockwise;
        }
        else
        {
            if (JelloShapeTools.HasClockwiseWinding(mEdgeVertices))
            {
                winding = Winding.Clockwise;
            }
            else
            {
                winding = Winding.CounterClockwise;
            }
        }

        //finish ();
    }
Пример #14
0
        private void CreateTriangle(bool invertNext, Winding direction, string line, Matrix3D matrix, MeshGeometry3D mesh)
        {
            TriangleCommand cmd = new TriangleCommand(line);

            Winding dir = ApplyInvert(invertNext, direction);

            MatrixTransform3D mt = new MatrixTransform3D(matrix);

            mt.Transform(cmd.Points);

            if (dir == Winding.CCW)
            {
                CreateTriangle(cmd.Points[0], cmd.Points[2], cmd.Points[1], mesh);
            }
            else
            {
                CreateTriangle(cmd.Points[0], cmd.Points[1], cmd.Points[2], mesh);
            }
        }
Пример #15
0
        /// <summary>
        /// Check if a polygon has a specified winding.
        /// </summary>
        public static bool HasWinding(
            this Polygon2d polygon, Winding winding)
        {
            var winFun      = winding == Winding.CCW ? c_ccwFun : c_cwFun;
            var ef          = polygon.Edge(0);
            var e0          = polygon.Edge(1);
            var orientation = winFun(ef, e0);

            for (int i = 2; i < polygon.PointCount; i++)
            {
                var e1 = polygon.Edge(i);
                if (winFun(e0, e1) != orientation)
                {
                    return(false);
                }
                e0 = e1;
            }
            return(winFun(e0, ef) == orientation);
        }
Пример #16
0
        public Plane(List <Vertex> _points, Winding _winding)
        {
            Winding = _winding;

            Points = _points;

            Vector3 a = Points[2] - Points[0];
            Vector3 b = Points[1] - Points[0];

            if (Winding == Winding.Ccw)
            {
                Vector3 c = a;
                a = b;
                b = c;
            }

            Normal = Vector3.Normalize(Vector3.Cross(a, b));

            DistanceFromOrigin = Vector3.Dot(Points[0].Position, Normal);
        }
Пример #17
0
        private void FlipEdgeEvent(SweepContext tcx, TriPoint ep, TriPoint eq, Triangle t, TriPoint p)
        {
            Triangle ot = t.NeighborAcross(p);
            TriPoint op = ot.OppositePoint(t, p);

            if (TriUtil.InScanArea(p, t.PointCCW(p), t.PointCW(p), op))
            {
                // Lets rotate shared edge one vertex CW
                RotateTrianglePair(t, p, ot, op);
                tcx.MapTriangleToNodes(t);
                tcx.MapTriangleToNodes(ot);

                if (p == eq && op == ep)
                {
                    if (eq == tcx.EdgeEvent.ConstrainedEdge.Q && ep == tcx.EdgeEvent.ConstrainedEdge.P)
                    {
                        t.MarkConstrainedEdge(ep, eq);
                        ot.MarkConstrainedEdge(ep, eq);
                        Legalize(tcx, t);
                        Legalize(tcx, ot);
                    }
                    else
                    {
                        // XXX: I think one of the triangles should be legalized here?
                    }
                }
                else
                {
                    Winding o = TriUtil.Orient2d(eq, op, ep);
                    t = NextFlipTriangle(tcx, o, t, ot, p, op);
                    FlipEdgeEvent(tcx, ep, eq, t, p);
                }
            }
            else
            {
                TriPoint newP = NextFlipPoint(ep, eq, ot, op);
                FlipScanEdgeEvent(tcx, ep, eq, t, ot, newP);
                EdgeEvent(tcx, ep, eq, t, p);
            }
        }
Пример #18
0
        private Triangle NextFlipTriangle(SweepContext tcx, Winding o, Triangle t, Triangle ot, TriPoint p, TriPoint op)
        {
            int edge_index;

            if (o == Winding.CCW)
            {
                // ot is not crossing edge after flip
                edge_index = ot.EdgeIndex(p, op);
                ot.DelaunayEdge[edge_index] = true;
                Legalize(tcx, ot);
                ot.ClearDelaunayEdges();
                return(t);
            }

            // t is not crossing edge after flip
            edge_index = t.EdgeIndex(p, op);

            t.DelaunayEdge[edge_index] = true;
            Legalize(tcx, t);
            t.ClearDelaunayEdges();
            return(ot);
        }
Пример #19
0
    public override int[] getMeshTris(int vertexCount, Winding winding, Vector2 completion, bool closed = false)
    {
        List <int> tris = new List <int>();

        int[] leftWallTris = leftWall.getMeshTris(vertexCount / 4, winding, completion, closed);
        tris.AddRange(leftWallTris);
        int[] roofTris = roof.getMeshTris(vertexCount / 4, winding, completion, closed);
        for (int i = 0; i < roofTris.Length; i++)
        {
            roofTris[i] += vertexCount / 4;
        }
        tris.AddRange(roofTris);
        int[] rightWallTris = rightWall.getMeshTris(vertexCount / 4, winding == Winding.FORWARD ? Winding.INVERTED : winding, completion, closed);
        for (int i = 0; i < rightWallTris.Length; i++)
        {
            rightWallTris[i] += vertexCount / 4 * 2;
        }
        tris.AddRange(rightWallTris);
        int[] floorTris = floor.getMeshTris(vertexCount / 4, winding == Winding.FORWARD ? Winding.INVERTED : winding, completion, closed);
        for (int i = 0; i < floorTris.Length; i++)
        {
            floorTris[i] += vertexCount / 4 * 3;
        }
        tris.AddRange(floorTris);

        if (!closed || completion.magnitude != 1.0f)
        {
            tris.AddRange(new int[] { rightWallTris[rightWallTris.Length - 1], leftWallTris[2], rightWallTris[rightWallTris.Length - 3] });
            tris.AddRange(new int[] { leftWallTris[0], leftWallTris[2], rightWallTris[rightWallTris.Length - 1] });

            tris.AddRange(new int[] { rightWallTris[1], rightWallTris[0], leftWallTris[leftWallTris.Length - 1] });
            tris.AddRange(new int[] { leftWallTris[leftWallTris.Length - 1], leftWallTris[leftWallTris.Length - 2], rightWallTris[1] });
        }

        return(tris.ToArray());
    }
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="src">Source render state to copy</param>
 public OpenGlRenderState( OpenGlRenderState src )
 {
     Arguments.CheckNotNull( src, "src" );
     m_Lighting				= src.m_Lighting;
     m_DepthOffset			= src.m_DepthOffset;
     m_DepthBias				= src.m_DepthBias;
     m_PassDepthTest			= src.m_PassDepthTest;
     m_DepthTest				= src.m_DepthTest;
     m_DepthWrite			= src.m_DepthWrite;
     m_CullBackFaces			= src.m_CullBackFaces;
     m_CullFrontFaces		= src.m_CullFrontFaces;
     m_FaceWinding			= src.m_FaceWinding;
     m_FrontFaceRenderMode	= src.m_FrontFaceRenderMode;
     m_BackFaceRenderMode	= src.m_BackFaceRenderMode;
     m_Colour				= src.m_Colour;
     m_ShadeMode				= src.m_ShadeMode;
     m_Enable2dTextures		= src.m_Enable2dTextures;
     m_Blend					= src.m_Blend;
     m_SourceBlend			= src.m_SourceBlend;
     m_DestinationBlend		= src.m_DestinationBlend;
     m_PointSize				= src.m_PointSize;
     m_LineWidth				= src.m_LineWidth;
     m_TextureUnits			= src.m_TextureUnits;
 }
Пример #21
0
 public static FrontFaceDirection FrontFace(Winding bWinding)
 {
     switch (bWinding)
     {
         case Winding.Clockwise: return FrontFaceDirection.Cw;
         case Winding.CounterClockwise: return FrontFaceDirection.Ccw;
         default: throw new ArgumentOutOfRangeException("bWinding");
     }
 }
Пример #22
0
    //TODO check into this --> will i need to retriangulate? because mesh triangles may need to always be wound in a certain direction.
    /// <summary>
    /// Flip the JelloClosedShape verticaly.
    /// </summary>
    /// 
    /// <dl class="example"><dt>Example</dt></dl>
    /// ~~~{.c}
    /// //turn a body around when it hits a ceiling
    /// 
    /// JelloBody body;
    /// void handleCollisionEnter(JelloCollisionManifold manifold)
    /// {
    /// 	if(manifold.GetOtherBody(body).gameObject.tag == "ceiling")
    /// 	{
    /// 		body.flipY();
    /// 		//also reverse movement direction
    /// 	}
    /// }
    /// ~~~
    public void flipY()
    {
        Vector2[] tempVertices = new  Vector2[mEdgeVertices.Length];

        for(int i = 0; i < mEdgeVertices.Length; i++)
        {
            mEdgeVertices[i] = new Vector2(mEdgeVertices[i].x, mEdgeVertices[i].y + 2 * (Center.x - mEdgeVertices[i].x));
            tempVertices[mEdgeVertices.Length - i - 1] = mEdgeVertices[i];
        }

        mEdgeVertices = tempVertices;

        tempVertices = new  Vector2[mInternalVertices.Length];

        for(int i = 0; i < mInternalVertices.Length; i++)
        {
            mInternalVertices[i] = new Vector2(mInternalVertices[i].x, mInternalVertices[i].y + 2 * (Center.x - mInternalVertices[i].x));
            tempVertices[mInternalVertices.Length - i - 1] = mInternalVertices[i];
        }

        mInternalVertices = tempVertices;

        if(winding == Winding.Clockwise)
        {
            winding = Winding.CounterClockwise;
        }
        else if(winding == Winding.CounterClockwise)
        {
            winding = Winding.Clockwise;
        }
        else
        {
            if(JelloShapeTools.HasClockwiseWinding(mEdgeVertices))
                winding = Winding.Clockwise;
            else
                winding = Winding.CounterClockwise;
        }

        //finish ();
    }
Пример #23
0
 /// <summary>
 /// Sets the current sub-path winding, <see cref="Winding"/> and <see cref="Solidity"/>
 /// </summary>
 public static void PathWinding(this Nvg nvg, Winding dir)
 {
     nvg.instructionQueue.AddWinding(dir);
 }
Пример #24
0
 public abstract int[] getMeshTris(int vertexCount, Winding winding, Vector2 completion, bool closed = false);
Пример #25
0
    /// <summary>
    /// Finish adding vertices to this JeloClosedShape, and choose whether to convert into local space.
    /// JelloClosedShape.winding and JelloClosedShape.Triangles will be set.
    /// Make sure there are no duplicate points before calling this. use JelloShapeTools.RemoveDuplicatePoints().
    /// </summary>
    /// <param name="recenter">whether to convert the positions of the JelloClosedShape into local space.</param>
    /// 
    /// <dl class="example"><dt>Example</dt></dl>
    /// ~~~{.c}
    /// //Create a closed shape square
    /// JelloClosedShape shape = new JelloClosedShape();
    /// 
    /// shape.begin();
    /// 
    /// shape.addPoint(new Vector2(-1,1));	//top left
    /// shape.addPoint(new Vector2(-1,1));	//top right
    /// shape.addPoint(new Vector2(-1,1));	//bottom right
    /// shape.addPoint(new Vector2(-1,1));	//bottom left
    /// 	
    /// shape.finish();
    /// ~~~
    public void finish(bool recenter = true)
    {
        if(mInternalVertices != null && mInternalVertices.Length > 0)
        {
            //dont allow duplicate points
            mInternalVertices = JelloShapeTools.RemoveDuplicatePoints(mInternalVertices);

            //dont allow points outside of the perimiter
            for(int i = 0;  i < mInternalVertices.Length; i++)
            {
                if(!JelloShapeTools.Contains(mEdgeVertices, mInternalVertices[i]))
                {
                    mInternalVertices[i] = Vector2.one * Mathf.Infinity;
                }
            }
            //dont allow points on the perimiter. (this will also remove any null points)
            mInternalVertices = JelloShapeTools.RemovePointsOnPerimeter(mEdgeVertices, mInternalVertices);
        }

        mCenter = JelloShapeTools.FindCenter(mEdgeVertices);

        if (recenter)
        {
            // now subtract this from each element, to get proper "local" coordinates.
            for (int i = 0; i < mEdgeVertices.Length; i++)
                mEdgeVertices[i] -= mCenter;
            if(mInternalVertices != null)
                for (int i = 0; i < mInternalVertices.Length; i++)
                    mInternalVertices[i] -= mCenter;
        }

        if(JelloShapeTools.HasClockwiseWinding(mEdgeVertices))
            winding = Winding.Clockwise;
        else
            winding = Winding.CounterClockwise;

        Triangulate();
    }
Пример #26
0
        /// <summary>
        /// Creates new circle arc shaped sub-path.
        /// The arc is drawn from angle a0 to a1.
        /// </summary>
        /// <param name="c">The arc center.</param>
        /// <param name="r">The arc radius.</param>
        /// <param name="dir">The direction the arc is swept in.</param>
        public static void Arc(this Nvg nvg, Vector2D <float> c, float r, float a0, float a1, Winding dir)
        {
            Vector2D <float> pPos = default;
            Vector2D <float> pTan = default;

            InstructionQueue queue = nvg.instructionQueue;

            bool line = queue.Count > 0;

            float da = a1 - a0;

            if (dir == Winding.Cw)
            {
                if (MathF.Abs(da) >= MathF.PI * 2.0f)
                {
                    da = MathF.PI * 2.0f;
                }
                else
                {
                    while (da < 0.0f)
                    {
                        da += MathF.PI * 2.0f;
                    }
                }
            }
            else
            {
                if (MathF.Abs(da) >= MathF.PI * 2.0f)
                {
                    da = -MathF.PI * 2.0f;
                }
                else
                {
                    while (da > 0.0f)
                    {
                        da -= MathF.PI * 2.0f;
                    }
                }
            }

            int   ndivs = Math.Max(1, Math.Min((int)(MathF.Abs(da) / (MathF.PI * 0.5f) + 0.5f), 5));
            float hda   = (da / (float)ndivs) / 2.0f;
            float kappa = MathF.Abs(4.0f / 3.0f * (1.0f - MathF.Cos(hda)) / MathF.Sin(hda));

            if (dir == Winding.Ccw)
            {
                kappa *= -1.0f;
            }

            for (int i = 0; i <= ndivs; i++)
            {
                float            alpha = a0 + da * ((float)i / (float)ndivs);
                Vector2D <float> d     = new(MathF.Cos(alpha), MathF.Sin(alpha));
                Vector2D <float> pos   = new(c.X + d.X * r, c.Y + d.Y * r);
                Vector2D <float> tan   = new(-d.Y * r * kappa, d.X *r *kappa);

                if (i == 0)
                {
                    if (line)
                    {
                        queue.AddLineTo(pos);
                    }
                    else
                    {
                        queue.AddMoveTo(pos);
                    }
                }
                else
                {
                    queue.AddBezierTo(pPos + pTan, pos - tan, pos);
                }

                pPos = pos;
                pTan = tan;
            }
        }
Пример #27
0
 public abstract Vector3[] getNormals(Point[] points, Vector3[] normals, Vector3 up, Winding winding, Vector2 completion, bool closed = false);
Пример #28
0
 public Plane(Vector3 _a, Vector3 _b, Vector3 _c, Winding _winding) : this(new Vertex(_a), new Vertex(_b), new Vertex(_c), _winding)
 {
 }
Пример #29
0
 public Plane(Vertex _a, Vertex _b, Vertex _c, Winding _winding) : this(new List <Vertex>() { _a, _b, _c }, _winding)
 {
 }
Пример #30
0
 public int[] getMeshTris(int vertexCount, Shape shape, Winding winding, Vector2 completion, bool closed)
 {
     return(shape.getMeshTris(vertexCount, winding, completion, closed));
 }
Пример #31
0
 public Vector3[] pointToMeshNormals(Point[] points, Shape shape, Vector3 up, Winding winding, Vector2 completion, bool closed = false)
 {
     Vector3[] normals = getPointsNormal(points, up, completion, closed);
     return(shape.getNormals(points, normals, up, winding, completion, closed));
 }
Пример #32
0
    public override Vector3[] getNormals(Point[] points, Vector3[] normals, Vector3 up, Winding winding, Vector2 completion, bool closed = false)
    {
        Vector3[] meshNormals = new Vector3[normals.Length * 2];
        for (int i = 0; i < meshNormals.Length; i++)
        {
            meshNormals[i] = normals[i / 2];
            if (winding == Winding.INVERTED)
            {
                meshNormals[i] *= -1;
            }
        }

        return(meshNormals);
    }
Пример #33
0
 /// <summary>
 /// Creates new circle arc shaped sub-path.
 /// The arc is drawn from angle a0 to a1.
 /// </summary>
 /// <param name="cx">The arc center X-Choordinate.</param>
 /// <param name="cy">The arc center Y-Choordinate.</param>
 /// <param name="r">The arc radius.</param>
 /// <param name="dir">The direction the arc is swept in.</param>
 public static void Arc(this Nvg nvg, float cx, float cy, float r, float a0, float a1, Winding dir)
 => Arc(nvg, new Vector2D <float>(cx, cy), r, a0, a1, dir);
Пример #34
0
        /// <summary>
        /// When called, the design will calculate its' values.
        /// </summary>
        public void PerformCalculations()
        {
            //Give each winding a reference to the designs' core & tube and the prevous winding and the design.
            for (int i = 0; i < Windings.Count; i++)
            {
                Windings[i].Design       = this;
                Windings[i].Core         = Core;
                Windings[i].Tube         = Tube;
                Windings[i].RotatedTube  = RotatedTube;
                Windings[i].WindingOrder = i + 1;
                if (i > 0)
                {
                    Windings[i].PreviousWinding = Windings[i - 1];
                }
            }

            if (IsUI)
            {
                //Get primary turns
                foreach (Winding w in Windings.Where(w => w.IsPrimary))
                {
                    foreach (Section s in w.Sections)
                    {
                        //Remember Flux = Volts per Turn / (4.44 * Frequency) = Volts / (4.44 * Frequency * Turns)
                        //Therefore Turns = Volts / (4.44 * Frequency * Flux)
                        //Technically 4.44 should be 4 * Waveform Factor; but as of 04/03/2019 all inputs are assumed to be perfect sine/cosine waves with a Waveform Factor = 1.11
                        s.Turns = (int)Math.Ceiling(s.PhaseVoltageRange / (4.44 * Specification.Frequency * Flux));
                        if (UIStyle == UIStyle.SERIES) //If the windings are to be connected in series divide the turns by two.
                        {
                            s.Turns = (int)Math.Floor((double)s.Turns / 2);
                        }
                    }
                }
                double primaryNominalVoltage = Windings.Where(w => w.IsPrimary).First().NominalVoltage / (UIStyle == UIStyle.SERIES ? 2 : 1);
                int    primaryNominalTurns   = (int)Math.Ceiling(primaryNominalVoltage / (4.44 * Specification.Frequency * Flux));
                AdjustedFlux = primaryNominalVoltage / (4.44 * Specification.Frequency * primaryNominalTurns);
                foreach (var w in Windings.Where(w => !w.IsPrimary))
                {
                    foreach (Section s in w.Sections)
                    {
                        //Determine the turns for each secondary section.
                        s.Turns = (int)Math.Ceiling((s.PhaseVoltageRange * CompensationFactor / primaryNominalVoltage) * primaryNominalTurns);
                        if (UIStyle == UIStyle.SERIES)
                        {
                            s.Turns = (int)Math.Ceiling((double)s.Turns / 2);
                        }
                    }
                }
            }
            else //See above except no possibily of dividing turns by two. Could probably be made with inline ifs to make it simplier to read/modifiy.
            {
                foreach (Winding w in Windings.Where(w => w.IsPrimary))
                {
                    foreach (Section s in w.Sections)
                    {
                        s.Turns = (int)Math.Ceiling(s.PhaseVoltageRange / (4.44 * Specification.Frequency * Flux));
                    }
                }
                double primaryNominalVoltage = Windings.Where(w => w.IsPrimary).First().NominalVoltage;
                int    primaryNominalTurns   = (int)Math.Ceiling(primaryNominalVoltage / (4.44 * Specification.Frequency * Flux));
                AdjustedFlux = primaryNominalVoltage / (4.44 * Specification.Frequency * primaryNominalTurns);
                foreach (var w in Windings.Where(w => !w.IsPrimary))
                {
                    foreach (Section s in w.Sections)
                    {
                        s.Turns = (int)Math.Ceiling((s.PhaseVoltageRange * CompensationFactor / primaryNominalVoltage) * primaryNominalTurns);
                    }
                }
            }

            //Get the first primary winding, as primary windings as either 1 isolated or series/parallel it honeslty doesn't matter which one we pick, but we are guaranteed the first.
            Winding primaryWinding = Windings.Where(x => x.IsPrimary).First();
            //Get the first secondary winding, there can be multiple secondry windings but only one needs to used, as we get the first as we are guaranteed to have at least one. (Except in the case of reactors/autotransformers, as of 04/03/2019 they would have to be entered as two isolation and connected after but this may change in the future)
            Winding secondaryWinding = Windings.Where(x => !x.IsPrimary).First();
            //Determine a new primary current that also feeds the losses of the design, as of 04/03/2019 this needs to be looked at in depth to determine its effectiveness.
            double primaryCurrent = ((((double)secondaryWinding.TotalTurns / primaryWinding.TotalTurns) * primaryWinding.PhaseVoltage * secondaryWinding.LowestPhaseCurrent * (RatedPhasekVA / (secondaryWinding.RatedVA / 1000)) + Windings.Select(w => w.WorstCaseLosses).Sum() + Core.Losses(AdjustedFluxDensity, (int)Specification.Frequency)) / (primaryWinding.PhaseVoltage)) * Core.ExcitationFactor * Core.Lamination.ExcitationFactor;

            //Set the primary VA to a new value based on the calculated current to feed the losses.
            foreach (Winding w in Windings.Where(x => x.IsPrimary))
            {
                w.CalcedVA = primaryCurrent * w.TapVoltages.Last();
            }

            //Get the build of the coils
            BuildUp = (RotatedTube ? Tube.Thickness + Tube.Wrap + (Tube.Depth - Core.Lamination.Tongue) / 2 : Tube.Thickness + Tube.Wrap + (Tube.Width - Core.Lamination.Tongue) / 2) +
                      Windings.Select(w => w.Build).Sum();
            //Determine the actual build percent, as in UI and 3 phase there are two coils in each window. so the BuildFactor just divides by 2 in those cases, etc.
            Build = BuildUp / (Core.Lamination.WindowWidth * Core.Lamination.BuildFactor) * 100;

            //Calculate the temperature rise according to reuben lee's equation
            TemperatureRise = (Core.Losses(AdjustedFluxDensity, (int)Specification.Frequency, true) + Core.NumberOfCoils * Windings.Select(w => w.WorstCaseLosses).Sum() + StrayLosses) / (0.1 * Math.Pow((Core.Weight + Core.NumberOfCoils * Windings.Select(w => w.Weight).Sum()) / 1.073, 0.6666));
            //UI - take 70% of temperature rise, needs to be analyzed
            if (IsUI)
            {
                TemperatureRise = 0.7 * TemperatureRise;
            }
        }
Пример #35
0
        // Slice the brush by a plane
        // If divided by the plane, results will be placed into the lists based on which side of th eplane they're on
        public SplitResult Slice(Plane3 plane, List<Brush> front, List<Brush> back)
        {
            List<Face> frontFaces = new List<Face>();
            List<Face> backFaces = new List<Face>();
            List<Winding> frontWinding = new List<Winding>();
            List<Winding> backWinding = new List<Winding>();

            foreach (Face f in Faces)
            {
                frontFaces.Clear();
                backFaces.Clear();

                Winding winding = new Winding(f.GetPlane());
                winding.Clip(plane, frontWinding, backWinding);

                for (int i = 0; i < frontWinding.Count; ++i)
                {
                    if (frontWinding[i].Count == 0)
                    {
                        frontWinding.RemoveAt(i);
                        --i;
                    }
                }
                for (int i = 0; i < backWinding.Count; ++i)
                {
                    if (backWinding[i].Count == 0)
                    {
                        backWinding.RemoveAt(i);
                        --i;
                    }
                }

                // Brush needs to be split
                if (frontWinding.Count > 0 && backWinding.Count > 0)
                {
                    Brush frontBrush = new Brush();
                    Brush backBrush = new Brush();

                    if (front != null)
                    {
                        foreach (Winding w in frontWinding)
                            if (w.Count > 0)
                                frontBrush.Faces.Add(new Face(f, w));
                        if (frontBrush.Faces.Count > 0)
                            front.Add(frontBrush);
                    }
                    if (back != null)
                    {
                        foreach (Winding w in backWinding)
                        {
                            if (w.Count > 0)
                                backBrush.Faces.Add(new Face(f, w));
                        }
                        if (backBrush.Faces.Count > 0)
                            back.Add(backBrush);
                    }

                    return SplitResult.Split;
                }
                // Brush is whole
                else if (frontWinding.Count > 0)
                {
                    if (front != null)
                        front.Add(this);
                    return SplitResult.Front;
                }
                else if (backWinding.Count > 0)
                {
                    if (back != null)
                        back.Add(this);
                    return SplitResult.Back;
                }
                else
                    throw new Exception("Unexpected failure with brush neither on nor on a side of a plane");
            }
            return SplitResult.None;
        }
Пример #36
0
 /// <summary>
 /// Processes a sequence of sections and returns an IEnumerable of all the sections that are for a given winding.
 /// </summary>
 /// <param name="sections">IEnumerable{Section} Sequence to be processed.</param>
 /// <param name="winding">Winding to which sections should be matched to.</param>
 /// <returns>An IEnumerable{Section} of all the sections in the sequence that are for the given winding.</returns>
 public static IEnumerable <Components.Base.Section> GetSectionsForWinding(this IEnumerable <Section> sections, Winding winding)
 {
     return(sections.Where(s => s.WindingName == winding.Name).OrderBy(s => s.SectionOrder));
 }