Пример #1
0
        public void Transfer(float radians, Gear target)
        {
            var ratio         = this.NumberOfTeeth / (float)target.NumberOfTeeth;
            var targetRadians = radians * ratio;

            target.Spin(targetRadians * target.Direction);

            // Solve colisions due to small inaccuracies

            // 1. Find tooth closest to target gear
            var targetPosition2D = new Vector2(target.Position.X, target.Position.Z);

            var myClosestTooth = GetToothClosestToPoint(targetPosition2D);


            // 2. Find tooth from target gear to us
            var myClosestToothCom  = myClosestTooth.CenterOfMassTransformed();
            var targetClosestTooth = target.GetToothClosestToPoint(myClosestToothCom);

            // 3. Check if they overlap
            if (Direction == 1)
            {
                if (LineMath.PenetrationOfAIntoB(myClosestTooth.CounterClockwiseLine.OutlineTransformed, targetClosestTooth.ClockwiseLine.OutlineTransformed, out var point))
                {
                    var adjustment = (MathHelper.TwoPi / target.NumberOfTeeth) / 300.0f;
                    target.Spin(adjustment * target.Direction);
                }
                else if (LineMath.PenetrationOfAIntoB(myClosestTooth.ClockwiseLine.OutlineTransformed, targetClosestTooth.CounterClockwiseLine.OutlineTransformed, out var point2))
                {
                    var adjustment = -(MathHelper.TwoPi / target.NumberOfTeeth) / 300.0f;
                    target.Spin(adjustment * target.Direction);
                }
            }
            // TODO: code path for when we rotate in the other direction
        }
Пример #2
0
        public void Update(GameTime gameTime, KeyboardState keyboard)
        {
            if (keyboard.IsKeyDown(Keys.Space))
            {
                LineList[0].Spin(0.75);
                //LineList[1].Spin(-0.75);
            }
            else
            {
                //LineList[0].Spin(0);
                //LineList[1].Spin(0);
            }

            for (var i = 0; i < LineList.Count; i++)
            {
                LineList[i].Update(gameTime);
            }

            var shortest     = LineMath.ShortestDistance(LineList[0].OutlineTransformed[0], LineList[0].OutlineTransformed[1], LineList[1].OutlineTransformed[0]);
            var shortestLine = LineMath.ShortestDistance(LineList[0].OutlineTransformed.ToArray(), LineList[1].OutlineTransformed.ToArray());

            Indicators.Clear();

            //Indicators.Add(new Shape(Device, Color.Green, PointToCross(LineList[1].OutlineTransformed[0], 0.2f), false));
            //Indicators.Add(new Shape(Device, Color.Pink, PointToCross(LineList[0].OutlineTransformed[0], 0.2f), false));
            //Indicators.Add(new Shape(Device, Color.Purple, PointToCross(LineList[0].OutlineTransformed[1], 0.2f), false));
            //Indicators.Add(new Shape(Device, Color.Orange, PointToCross(shortest, 0.4f), false));


            //Indicators.Add(new Shape(Device, Color.Yellow, PointToCross(shortestLine[0], 0.04f), false));
            //Indicators.Add(new Shape(Device, Color.Yellow, PointToCross(shortestLine[1], 0.04f), false));

            if (LineMath.Intersection(LineList[0].OutlineTransformed.ToArray(), LineList[1].OutlineTransformed.ToArray(), out var intersectionPoint))
            {
                Indicators.Add(new Shape(Device, Color.Yellow, PointToCross(intersectionPoint, 0.1f), false));

                // Proportional increase in angular velocity so that things get unstuck
                var d      = LineMath.PenetrationOfAIntoB(LineList[0].OutlineTransformed.ToArray(), intersectionPoint);
                var dRatio = d / LineList[0].Length;

                LineList[1].Spin(-LineList[0].AngularVelocity * (1.0 + dRatio));

                Console.WriteLine($"Penetration {d:F4}, L0: {LineList[0].AngularVelocity:F4}, L1: {LineList[1].AngularVelocity:F4}");

                // TODO: what if things intersect and the velocity of line 0 is 0, or quickly decreases?
            }
        }
Пример #3
0
        private double?Gear(Line a, Line b, float amount)
        {
            // TODO leading on leading should add speed, while trailing on trailing should reduce speed
            if (LineMath.Intersection(a.OutlineTransformed.ToArray(), b.OutlineTransformed.ToArray(), out var intersectionPoint))
            {
                Indicators.Add(new Shape(Device, Color.Yellow, PointToCross(intersectionPoint, 0.1f), false));

                // Proportional increase in angular velocity so that things get unstuck
                var d      = LineMath.PenetrationOfAIntoB(a.OutlineTransformed.ToArray(), intersectionPoint);
                var dRatio = d / a.Length;

                var spin = -a.AngularVelocity * (1.0 + dRatio);

                return(amount);
            }

            return(null);
        }