public IntermediateMeshGenerator Generate()
        {
            var crossingX  = Context.Config.halfPanelWidth / Context.Config.halfSegmentSin;
            var innerBendX = crossingX + Context.Config.bendRadius / Context.Config.halfSegmentSin;

            var innerBendCenter = new Vector2d(innerBendX, 0);

            InnerBendCorner = new Vector2d(crossingX, 0);

            var rot = Vector2d.AxisX.rotate2d(Context.Config.halfSegmentAngle);

            var distToIntersection = Context.Config.bendRadius / Context.Config.halfSegmentSin * Context.Config.halfSegmentCos;

            InnerBendUpTouchPoint   = InnerBendCorner + rot * distToIntersection;
            InnerBendDownTouchPoint = new Vector2d(InnerBendUpTouchPoint.x, -InnerBendUpTouchPoint.y);

            InnerBendPoints = Generators.counterClockwiseCircleSegments(Context.Config.pointsInBend, innerBendCenter, InnerBendUpTouchPoint, InnerBendDownTouchPoint);

            for (int i = 0; i < InnerBendPoints.Count - 1; i++)
            {
                Intermediate.counterClockwiseSingleSidedFromFront(
                    InnerBendCorner.to3d(),
                    InnerBendPoints[i + 1].to3d(),
                    InnerBendPoints[i].to3d()
                    );
            }

            // outer corners
            var itxUp = Intersector.CircelLineIntersection(Vector2d.Zero, Context.Config.plateRadius - Context.Config.outerWidth, InnerBendCorner, InnerBendCorner + Vector2d.AxisX.rotate2d(Context.Config.halfSegmentAngle));

            OuterUpCornerPoint = itxUp.Single(p => p.y > 0);

            var itxDown = Intersector.CircelLineIntersection(Vector2d.Zero, Context.Config.plateRadius - Context.Config.outerWidth, InnerBendCorner, InnerBendCorner + Vector2d.AxisX.rotate2d(-Context.Config.halfSegmentAngle));

            OuterDownCornerPoint = itxDown.Single(p => p.y < 0);

            // outer bend
            var outerWidth = new Vector2d(Context.Config.plateRadius - Context.Config.outerWidth, 0);

            var outerBendCenter = new Vector2d(Context.Config.plateRadius - Context.Config.outerWidth - Context.Config.bendRadius, 0);

            // outer up bend
            var outerBendUpRay    = Vector2d.AxisX.rotate2d(Context.Config.halfSegmentAngle);
            var outerBendUpCenter = Intersector.CircelLineIntersection(Vector2d.Zero, outerBendCenter.x, innerBendCenter, innerBendCenter + outerBendUpRay).Single(p => p.y > 0);
            var outerBendUpCenterRelToInnerBendCorner = outerBendUpCenter - InnerBendCorner;

            OuterBendUpCenterTouchPoint = Intersector.CircelLineIntersection(Vector2d.Zero, outerWidth.x, Vector2d.Zero, outerBendUpCenter).Single(p => p.y > 0);
            OuterBendUpTouchPoint       = InnerBendCorner + outerBendUpRay * Math.Sqrt(outerBendUpCenterRelToInnerBendCorner.Length * outerBendUpCenterRelToInnerBendCorner.Length - Context.Config.bendRadius * Context.Config.bendRadius);
            OuterUpBendPoints           = Generators.counterClockwiseCircleSegments(Context.Config.pointsInBend, outerBendUpCenter, OuterBendUpCenterTouchPoint, OuterBendUpTouchPoint);

            for (int i = 0; i < OuterUpBendPoints.Count - 1; i++)
            {
                Intermediate.counterClockwiseSingleSidedFromFront(
                    OuterUpCornerPoint.to3d(),
                    OuterUpBendPoints[i + 1].to3d(),
                    OuterUpBendPoints[i].to3d()
                    );
            }

            // outer down bend
            var outerBendDownRay    = Vector2d.AxisX.rotate2d(-Context.Config.halfSegmentAngle);
            var outerBendDownCenter = Intersector.CircelLineIntersection(Vector2d.Zero, outerBendCenter.x, innerBendCenter, innerBendCenter + outerBendDownRay).Single(p => p.y < 0);
            var outerBendDownCenterRelToInnerBendCorner = outerBendDownCenter - InnerBendCorner;

            OuterBendDownCenterTouchPoint = Intersector.CircelLineIntersection(Vector2d.Zero, outerWidth.x, Vector2d.Zero, outerBendDownCenter).Single(p => p.y < 0);
            OuterBendDownTouchPoint       = InnerBendCorner + outerBendDownRay * Math.Sqrt(outerBendDownCenterRelToInnerBendCorner.Length * outerBendDownCenterRelToInnerBendCorner.Length - Context.Config.bendRadius * Context.Config.bendRadius);
            OuterDownBendPoints           = Generators.counterClockwiseCircleSegments(Context.Config.pointsInBend, outerBendDownCenter, OuterBendDownTouchPoint, OuterBendDownCenterTouchPoint);

            for (int i = 0; i < OuterDownBendPoints.Count - 1; i++)
            {
                Intermediate.counterClockwiseSingleSidedFromFront(
                    OuterDownCornerPoint.to3d(),
                    OuterDownBendPoints[i + 1].to3d(),
                    OuterDownBendPoints[i].to3d()
                    );
            }



            // outer serment surface
            OuterSurfaceNearPoints = Generators.counterClockwiseCircleSegments(
                Context.Config.segmentOuterSurfacePoints,
                Vector2d.Zero,
                OuterBendDownCenterTouchPoint,
                OuterBendUpCenterTouchPoint
                );

            var startPoint = Intersector.CircelLineIntersection(Vector2d.Zero, Context.Config.plateRadius, Vector2d.Zero, OuterBendDownCenterTouchPoint).Single(p => p.y < 0);
            var endPoint   = Intersector.CircelLineIntersection(Vector2d.Zero, Context.Config.plateRadius, Vector2d.Zero, OuterBendUpCenterTouchPoint).Single(p => p.y > 0);

            OuterSurfaceFarPoints = Generators.counterClockwiseCircleSegments(
                Context.Config.segmentOuterSurfacePoints,
                Vector2d.Zero,
                startPoint,
                endPoint);

            return(Intermediate);
        }
Exemple #2
0
        public IntermediateMeshGenerator Generate()
        {
            var plateSegmentGenerator = Context.Plate2d;

            for (var segIdx = 0; segIdx < Context.Config.segments; segIdx++)
            {
                var angle     = Context.Config.SegmentAngle(segIdx);
                var nextAngle = Context.Config.SegmentAngle(segIdx + 1);

                Intermediate.counterClockwiseSingleSidedFromFront(
                    plateSegmentGenerator.InnerBendCorner.rotate2d(angle).to3d(),
                    plateSegmentGenerator.OuterDownCornerPoint.rotate2d(nextAngle).to3d(),
                    plateSegmentGenerator.InnerBendCorner.rotate2d(nextAngle).to3d()
                    );

                Intermediate.counterClockwiseSingleSidedFromFront(
                    plateSegmentGenerator.InnerBendCorner.rotate2d(angle).to3d(),
                    plateSegmentGenerator.OuterUpCornerPoint.rotate2d(angle).to3d(),
                    plateSegmentGenerator.OuterDownCornerPoint.rotate2d(nextAngle).to3d()
                    );

                for (var pointIdx = 0; pointIdx < plateSegmentGenerator.OuterSurfaceNearPoints.Count - 1; pointIdx++)
                {
                    Intermediate.counterClockwiseSingleSidedFromFront(
                        plateSegmentGenerator.OuterSurfaceNearPoints[pointIdx].rotate2d(angle).to3d(),
                        plateSegmentGenerator.OuterSurfaceFarPoints[pointIdx + 1].rotate2d(angle).to3d(),
                        plateSegmentGenerator.OuterSurfaceNearPoints[pointIdx + 1].rotate2d(angle).to3d()
                        );

                    Intermediate.counterClockwiseSingleSidedFromFront(
                        plateSegmentGenerator.OuterSurfaceNearPoints[pointIdx].rotate2d(angle).to3d(),
                        plateSegmentGenerator.OuterSurfaceFarPoints[pointIdx].rotate2d(angle).to3d(),
                        plateSegmentGenerator.OuterSurfaceFarPoints[pointIdx + 1].rotate2d(angle).to3d()
                        );
                }

                // inner segment joint
                var jointCenterPoint = Vector2d.AxisX.rotate2d(angle + Context.Config.halfSegmentAngle) * (Context.Config.plateRadius - Context.Config.halfPanelWidth);
                var jointPoints      = new[]
                {
                    plateSegmentGenerator.OuterSurfaceFarPoints.First().rotate2d(nextAngle),
                    plateSegmentGenerator.OuterBendDownCenterTouchPoint.rotate2d(nextAngle),
                    plateSegmentGenerator.OuterDownCornerPoint.rotate2d(nextAngle),
                    plateSegmentGenerator.OuterUpCornerPoint.rotate2d(angle),
                    plateSegmentGenerator.OuterBendUpCenterTouchPoint.rotate2d(angle),
                    plateSegmentGenerator.OuterSurfaceFarPoints.Last().rotate2d(angle)
                };

                // outer segment joint
                for (var idx = 0; idx < jointPoints.Count() - 1; idx++)
                {
                    Intermediate.counterClockwiseSingleSidedFromFront(
                        jointCenterPoint.to3d(),
                        jointPoints[idx].to3d(),
                        jointPoints[idx + 1].to3d()
                        );
                }

                var theta0 = plateSegmentGenerator.OuterSurfaceNearPoints[0].toPolar(Vector2d.Zero).Theta;
                var theta1 = plateSegmentGenerator.OuterSurfaceNearPoints[1].toPolar(Vector2d.Zero).Theta;
                var surfaceSegmentAngle = theta1 - theta0;

                var farTheta0     = plateSegmentGenerator.OuterSurfaceNearPoints.Last().rotate2d(angle).toPolar(Vector2d.Zero).Theta;
                var farTheta1     = plateSegmentGenerator.OuterSurfaceNearPoints.First().rotate2d(nextAngle).toPolar(Vector2d.Zero).Theta;
                var farJointAngle = farTheta1 - farTheta0;
                if (farJointAngle < 0)
                {
                    farJointAngle += 2 * Math.PI;
                }

                var farSegmentPoints = Generators.counterClockwiseCircleSegments(
                    (int)Math.Ceiling(farJointAngle / surfaceSegmentAngle),
                    Vector2d.Zero,
                    plateSegmentGenerator.OuterSurfaceFarPoints.Last().rotate2d(angle),
                    plateSegmentGenerator.OuterSurfaceFarPoints.First().rotate2d(nextAngle)
                    );

                for (var idx = 0; idx < farSegmentPoints.Count() - 1; idx++)
                {
                    Intermediate.counterClockwiseSingleSidedFromFront(
                        jointCenterPoint.to3d(),
                        farSegmentPoints[idx].to3d(),
                        farSegmentPoints[idx + 1].to3d()
                        );
                }

                OuterJointPoints.Add(farSegmentPoints);
            }

            return(Intermediate);
        }
        public IntermediateMeshGenerator Generate()
        {
            var plateSegmentGenerator = Context.Plate2d;

            var cornerPoints = Context
                               .SegmentIndexes
                               .Select(idx => plateSegmentGenerator.InnerBendCorner.rotate2d(Context.Config.SegmentAngle(idx)))
                               .ToList();

            if (Context.Config.spindelRadius == 0)
            {
                for (var idx = 0; idx < cornerPoints.Count; idx++)
                {
                    var nextIdx = (idx + 1) % cornerPoints.Count;

                    Intermediate.counterClockwiseSingleSidedFromFront(
                        Vector2d.Zero.to3d(Context.halfPlateHeight),
                        cornerPoints[idx].to3d(Context.halfPlateHeight),
                        cornerPoints[nextIdx].to3d(Context.halfPlateHeight)
                        );

                    Intermediate.counterClockwiseSingleSidedFromFront(
                        Vector2d.Zero.to3d(-Context.halfPlateHeight),
                        cornerPoints[nextIdx].to3d(-Context.halfPlateHeight),
                        cornerPoints[idx].to3d(-Context.halfPlateHeight)
                        );
                }

                return(Intermediate);
            }

            List <Vector2d> spindelPoints = new List <Vector2d>();

            if (Context.Config.spindelCut == 0)
            {
                spindelPoints = Generators.counterClockwiseCirclePoints(
                    Context.Config.spindelPoints,
                    Vector2d.Zero,
                    Context.Config.spindelRadius
                    );

                /*
                 * Intermediate.Extrude(spindelPoints, Context.Config.plateHeight, true);
                 *
                 * var nearestDistanceIndexes = cornerPoints.Select(point =>
                 * {
                 *  var distances = spindelPoints.Select(p => p.Distance(point)).ToList();
                 *  var nearestPointIndex = distances.FindIndex(d => d == distances.Min());
                 *  return nearestPointIndex;
                 * }).ToList();
                 *
                 * for (var idx = 0; idx < cornerPoints.Count; idx++)
                 * {
                 *  var nearestPointIndex = nearestDistanceIndexes[idx];
                 *
                 *  var nextIdx = (idx + 1) % cornerPoints.Count;
                 *  var nextNearestPointIndex = nearestDistanceIndexes[nextIdx];
                 *
                 *  var polygonPoints = new List<Vector2d>();
                 *  polygonPoints.AddRange(
                 *      new []
                 *      {
                 *          cornerPoints[idx],
                 *          cornerPoints[nextIdx]
                 *      });
                 *
                 *  var spindelPart = new List<Vector2d>();
                 *  var pointsToTake = nextNearestPointIndex < nearestPointIndex
                 *      ? nextNearestPointIndex + spindelPoints.Count - nearestPointIndex + 1
                 *      : nextNearestPointIndex - nearestPointIndex + 1;
                 *
                 *  spindelPart = Enumerable.Range(nearestPointIndex, pointsToTake)
                 *      .Select(i => spindelPoints[i % spindelPoints.Count])
                 *      .Reverse()
                 *      .ToList();
                 *
                 *  polygonPoints.AddRange(spindelPart);
                 *
                 *  var polygonizer = new TriangulatedPolygonGenerator()
                 *  {
                 *      Polygon = new GeneralPolygon2d( new Polygon2d(polygonPoints) )
                 *  };
                 *  polygonizer.Generate();
                 *
                 *  var polygonMesh = new IntermediateMeshGenerator();
                 *  polygonMesh.Append(polygonizer);
                 *
                 *  Intermediate.Append(new IntermediateMeshGenerator().Append(polygonMesh).Offset(new Vector3d(0, 0, Context.halfPlateHeight)));
                 *  Intermediate.Append(new IntermediateMeshGenerator().Append(polygonMesh).Offset(new Vector3d(0, 0, -Context.halfPlateHeight)).ReverseTriagles());
                 * }
                 */
            }
            else
            {
                var spindelCutX = Context.Config.spindelRadius - Context.Config.spindelCut;
                var cutItx      = Intersector.CircelLineIntersection(
                    Vector2d.Zero,
                    Context.Config.spindelRadius,
                    new Vector2d(spindelCutX, 0),
                    new Vector2d(spindelCutX, 1)
                    );

                spindelPoints = Generators.counterClockwiseCircleSegments(
                    Context.Config.spindelPoints,
                    Vector2d.Zero,
                    cutItx.Single(p => p.y > 0),
                    cutItx.Single(p => p.y < 0)
                    );

                //Intermediate.Extrude(spindelSegments, Context.Config.plateHeight, true);
            }


            Intermediate.Extrude(spindelPoints, Context.Config.plateHeight, true);

            var nearestDistanceIndexes = cornerPoints.Select(point =>
            {
                var distances         = spindelPoints.Select(p => p.Distance(point)).ToList();
                var nearestPointIndex = distances.FindIndex(d => d == distances.Min());
                return(nearestPointIndex);
            }).ToList();

            for (var idx = 0; idx < cornerPoints.Count; idx++)
            {
                var nearestPointIndex = nearestDistanceIndexes[idx];

                var nextIdx = (idx + 1) % cornerPoints.Count;
                var nextNearestPointIndex = nearestDistanceIndexes[nextIdx];

                var polygonPoints = new List <Vector2d>();
                polygonPoints.AddRange(
                    new[]
                {
                    cornerPoints[idx],
                    cornerPoints[nextIdx]
                });

                var spindelPart  = new List <Vector2d>();
                var pointsToTake = nextNearestPointIndex < nearestPointIndex
                    ? nextNearestPointIndex + spindelPoints.Count - nearestPointIndex + 1
                    : nextNearestPointIndex - nearestPointIndex + 1;

                spindelPart = Enumerable.Range(nearestPointIndex, pointsToTake)
                              .Select(i => spindelPoints[i % spindelPoints.Count])
                              .Reverse()
                              .ToList();

                polygonPoints.AddRange(spindelPart);

                var polygonizer = new TriangulatedPolygonGenerator()
                {
                    Polygon = new GeneralPolygon2d(new Polygon2d(polygonPoints))
                };
                polygonizer.Generate();

                var polygonMesh = new IntermediateMeshGenerator();
                polygonMesh.Append(polygonizer);

                Intermediate.Append(new IntermediateMeshGenerator().Append(polygonMesh).Offset(new Vector3d(0, 0, Context.halfPlateHeight)));
                Intermediate.Append(new IntermediateMeshGenerator().Append(polygonMesh).Offset(new Vector3d(0, 0, -Context.halfPlateHeight)).ReverseTriagles());
            }

            return(Intermediate);
        }