Пример #1
0
        // Calculates a gear with perfect equilateral triangles as teeth teeth
        // TODO: position it properly!
        public static GearDescription DescribeGear(float toothSideLength, int teeth)
        {
            Assert(toothSideLength > float.Epsilon);
            Assert(teeth > 0);

            var halfToothSideLength = toothSideLength / 2.0f;

            //var diameter = Diameter(toothSideLength, teeth);
            var rootDiameter = GetRootDiameter(toothSideLength, teeth);
            var toothHeight  = (float)(halfToothSideLength * Math.Sqrt(3.0f));


            var angleStep = MathHelper.TwoPi / teeth;

            var description = new GearDescription(rootDiameter + (toothHeight * 2), rootDiameter, teeth);

            var center = new Vector2(0, 0);

            var lastPosition = new Vector2(rootDiameter / 2, -halfToothSideLength);
            var lastAngle    = 0.0f;

            for (var i = 0; i < teeth; i++)
            {
                var min     = lastPosition;
                var forward = Vector2.TransformNormal(Vector2.UnitY, Matrix.CreateRotationZ(lastAngle));
                var max     = min + (forward * toothSideLength);

                var tipBase = (min + max) / 2.0f;
                var normal  = Vector2.Normalize(tipBase - center);
                var tipTop  = tipBase + (normal * toothHeight);


                description.ClockwiseEdges.Add(new LineDescription(tipTop, min));
                description.CounterClockwiseEdges.Add(new LineDescription(tipTop, max));
                description.Edges.Add(new LineDescription(min, max));

                //description.ClockwiseEdges.Add(new LineDescription(tipTop, min));
                //description.CounterClockwiseEdges.Add(new LineDescription(tipTop, max));


                //description.ClockwiseEdges.Add(new LineDescription(center, tipBase));
                //description.CounterClockwiseEdges.Add(new LineDescription(min, max));

                lastPosition = max;
                lastAngle   += angleStep;
            }


            return(description);

            //var rootDiameter = (toothSideLength * teeth) / MathHelper.Pi;

            //// The height of an equilateral triangle is the length of a side divided by 2 time sqrt(3)

            //var diameterDifference = (float)(toothSideLength * Math.Sqrt(3.0f));
            //var outsideDiameter = rootDiameter + diameterDifference;

            //return DescribeGear(outsideDiameter, rootDiameter, teeth, 0.0f);
        }
Пример #2
0
        public static GearDescription DescribeGear(float outsideDiameter, float rootDiameter, int teeth, float profileRatio)
        {
            Assert(outsideDiameter > rootDiameter);
            Assert(teeth > 0);
            Assert(profileRatio >= 0.0f && profileRatio < 1.0f);

            var outsideRadius = outsideDiameter / 2.0f;
            var rootRadius    = rootDiameter / 2.0f;

            var description  = new GearDescription(outsideDiameter, rootDiameter, teeth);
            var stepSize     = MathHelper.TwoPi / teeth;
            var tipStepSize  = stepSize / 2.0f * profileRatio;
            var riseStepSize = (stepSize - (tipStepSize * 2.0f)) / 2.0f;
            var fallStepSize = riseStepSize;

            // We're traversing the outline of the gear in a counter clockwise fashion
            // starting at the three on the clock
            for (var i = 0; i < teeth; i++)
            {
                var position = stepSize * i;

                var riseStart = Vertex(position, rootRadius);
                position += riseStepSize;

                var riseEnd = Vertex(position, outsideRadius);
                position += tipStepSize;

                var fallStart = Vertex(position, outsideRadius);
                position += fallStepSize;

                var fallEnd = Vertex(position, rootRadius);
                position = stepSize * (i + 1);

                var next = Vertex(position, rootRadius);

                var rise = new LineDescription(riseStart, riseEnd);
                description.ClockwiseEdges.Add(rise);
                description.Edges.Add(rise);

                if (profileRatio > 0.0f)
                {
                    var tip = new LineDescription(riseEnd, fallStart);
                    description.Edges.Add(tip);
                }

                var fall = new LineDescription(fallStart, fallEnd);
                description.CounterClockwiseEdges.Add(fall);
                description.Edges.Add(fall);

                var connection = new LineDescription(fallEnd, next);
                description.Edges.Add(connection);
            }

            return(description);
        }
Пример #3
0
        private List <Line> CreateGear(GraphicsDevice device, Vector3 position, float outsideDiameter, float rootDiameter, int teeth, float profileRatio)
        {
            var gear        = new List <Line>();
            var description = GearDescription.DescribeGear(outsideDiameter, rootDiameter, teeth, profileRatio);


            for (var i = 0; i < description.ClockwiseEdges.Count; i++)
            {
                var edge = description.ClockwiseEdges[i];
                var line = new Line(device, Color.Blue, edge.A, edge.B);
                line.Position = position;
                gear.Add(line);
            }

            for (var i = 0; i < description.CounterClockwiseEdges.Count; i++)
            {
                var edge = description.CounterClockwiseEdges[i];
                var line = new Line(device, Color.Red, edge.A, edge.B);
                line.Position = position;
                gear.Add(line);
            }

            return(gear);
        }