Ejemplo n.º 1
0
        protected override void OnExecute(Command command, ExecutionContext context, System.Drawing.Rectangle buttonRect)
        {
            int numGears = 11;

            Debug.Assert(MainPart.Components.Count == numGears);
            var chain = new List <Component>();

            List <AlignCondition> aligns = MainPart.MatingConditions.Where(c => c is AlignCondition).Cast <AlignCondition>().ToList();

            chain.Add(aligns.First().GeometricA.GetAncestor <Component>());
            while (chain.Count != numGears)
            {
                foreach (AlignCondition align in aligns)
                {
                    Component component = align.GeometricA.GetAncestor <Component>();
                    if (!chain.Contains(component))
                    {
                        chain.Add(component);
                        break;
                    }

                    component = align.GeometricB.GetAncestor <Component>();
                    if (!chain.Contains(component))
                    {
                        chain.Add(component);
                        break;
                    }
                }
            }

            for (int iter = 0; iter < 100; iter++)
            {
                //		foreach (AlignCondition align in aligns)
                //			align.IsEnabled = false;

                Random random = new Random();
                var    angles = new List <double>();
                for (int i = 0; i < numGears; i++)
                {
                    angles.Add(AngleBetween(chain, i));
                }

                double averageAngle = angles.Average();

                //		double scale = 0.002;
                for (int i = 0; i < numGears; i++)
                {
                    //Vector noise = Vector.Create(random.NextDouble() - 0.5, random.NextDouble() - 0.5, random.NextDouble() - 0.5) * scale;
                    Vector spring = -SpringDistance(chain, i) * (angles[i] - averageAngle) / 10;
                    Matrix trans  = Matrix.CreateTranslation(spring);
                    Matrix rot    = Matrix.CreateRotation(Line.Create(chain[i].Placement * Point.Origin, Vector.Create(random.NextDouble() - 0.5, random.NextDouble() - 0.5, random.NextDouble() - 0.5).Direction), (random.NextDouble() - 0.5) * 0.001);
                    chain[i].Transform(trans * rot);
                }

                //		int offset = random.Next(numGears);
                //		for (int i = 0; i < numGears; i++)
                //			aligns[(i+offset)%numGears].IsEnabled = true;
            }
#if false
            Frame  frame      = Frame.World;
            Circle baseCircle = Circle.Create(frame, 0.05);
            baseCircle.Print();

            int gearCount      = 5;        // odd
            var controlCircles = new Circle[gearCount];
            var controlAxes    = new Line[gearCount];

            double spacing        = Math.PI * 2 / gearCount;
            double spacingOffset  = -spacing / 2;
            double angleIncrement = spacing / 2;

            for (int i = 0; i < gearCount; i++)
            {
                Point p0 = baseCircle.Evaluate(spacingOffset + spacing * i).Point;
                Point p1 = baseCircle.Evaluate(spacingOffset + spacing * (i + 1)).Point;
                Point midPoint = new Point[] { p0, p1 }.Average();
                controlAxes[i] = Line.Create(midPoint, (p1 - p0).Direction);

                controlCircles[i] = Circle.Create(Frame.Create(midPoint, (baseCircle.Frame.Origin - midPoint).Direction), (p1 - p0).Magnitude / 2).
                                    CreateTransformedCopy(Matrix.CreateRotation(controlAxes[i], angleIncrement * i));
            }

            controlCircles.Print();

            int counter = 10000;
            while (counter-- >= 0)
            {
                var    angles       = ComputeAngles(controlCircles);
                double averageAngle = angles.Average();

                for (int i = 1; i < gearCount; i++)
                {
                    controlCircles[i] = controlCircles[i].CreateTransformedCopy(Matrix.CreateRotation(controlAxes[i], (averageAngle - angles[i - 1])));
                }

                string op = string.Empty;
                for (int i = 0; i < gearCount; i++)
                {
                    op += angles[i].ToString() + "  ";
                }

                if (counter % 1000 == 0)
                {
                    Application.ReportStatus(op, StatusMessageType.Information, null);
                }
            }

            controlCircles.Print();

            ActiveWindow.InteractionMode = InteractionMode.Solid;
            ActiveWindow.ZoomExtents();
#endif
        }