Ejemplo n.º 1
0
        public BallsModel.State getActualState(double time)
        {
            bool currentStateIsOutdated()
            {
                if (statesBuffer.Count == 0)
                {
                    calcNextState();
                }

                if (solved)
                {
                    return(false);
                }

                double currentEndTime = statesBuffer.First().timeStamp;

                return(time > currentEndTime);
            }

            bool currentStateOutdated = currentStateIsOutdated();

            if (solved)
            {
                return(currentState);
            }

            if (!currentStateOutdated)
            {
                return(currentState);
            }

            do
            {
                if (statesBuffer.Count == 0)
                {
                    currentState = calcNextState();
                }
                else
                {
                    currentState = statesBuffer[0];
                    statesBuffer = statesBuffer.Skip(1).ToList();
                }
            } while (!solved && currentStateIsOutdated());

            return(currentState);
        }
Ejemplo n.º 2
0
        public BallsModel.State calcNextState()
        {
            BallsModel.State latestState =
                statesBuffer.Count > 0 ? statesBuffer.Last() : currentState;

            FSharpOption <BallsModel.State> state =
                latestState.nextState(bounceGate);

            solved = FSharpOption <BallsModel.State> .get_IsNone(state);

            if (!solved)
            {
                statesBuffer.Add(state.Value);
                return(state.Value);
            }
            else
            {
                return(latestState);
            }
        }
Ejemplo n.º 3
0
 public void addWall(BallsModel.Wall wall)
 {
     BallsModel.State newState = statesBuffer.Last().addWall(wall);
     statesBuffer.Add(newState);
 }
Ejemplo n.º 4
0
 public Room(BallsModel.State initialState, double bounceGate = 0.1)
 {
     currentState    = initialState;
     this.bounceGate = bounceGate;
 }
Ejemplo n.º 5
0
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            float scaleGraphics = this.scaleGraphics * Math.Min(ClientSize.Width, ClientSize.Height) / 1000f;

            scaleFinal = scaleGraphics * scaleModel;

            //float translateX = this.translateX + ClientSize.Width / 2;
            //float translateY = this.translateY + ClientSize.Height / 2;
            float translateX = this.translateX;
            float translateY = this.translateY;

            // scale to 10 and translate to the center
            g.TranslateTransform(translateX, translateY);
            g.ScaleTransform(scaleGraphics, scaleGraphics);

            // draw axises
            //Pen axisPen = new Pen(Color.Black, 1f);
            //g.DrawLine(axisPen, -ClientSize.Width, 0, ClientSize.Width, 0);
            //g.DrawLine(axisPen, 0, -ClientSize.Height, 0, ClientSize.Height);

            // draw temp polygon
            if (newWallBuffer.Count > 1)
            {
                Pen      newWallPen = new Pen(Color.DarkCyan, 2);
                PointF[] points     =
                    newWallBuffer
                    .Select(p => new PointF((float)p.x * scaleModel, (float)p.y * scaleModel))
                    .ToArray();

                HatchBrush hBrush = new HatchBrush(
                    HatchStyle.ForwardDiagonal,
                    Color.White,
                    Color.DarkCyan
                    );

                g.FillPolygon(
                    hBrush,
                    points
                    );

                g.DrawPolygon(
                    newWallPen,
                    points
                    );
            }

            if (room == null)
            {
                return;
            }

            // draw current state
            double time           = (double)stopWatch.ElapsedMilliseconds / 1000;
            double frameDeltaReal = time - lastRealTime;

            double simTime = lastSimTime + frameDeltaReal * timeScale;

            //double scaledTime = time;
            lastRealTime = time;
            lastSimTime  = simTime;

            BallsModel.State currentState = room.getActualState(simTime);

            double cpu = myAppCpu.NextValue();

            cpuUsageBuffer.Add(cpu);
            if (cpuUsageBuffer.Count > 55)
            {
                cpuUsageBuffer.RemoveAt(0);
            }

            frameDurationBuffer.Add(frameDeltaReal);
            if (frameDurationBuffer.Count > 55)
            {
                frameDurationBuffer.RemoveAt(0);
            }

            StateDrawer.Draw(
                g,
                currentState,
                simTime,
                scaleModel,
                scaleVectors,
                showCenter,
                showFrame,
                showVector
                );
        }
Ejemplo n.º 6
0
        private void start()
        {
            //BallsModel.Ball[] balls = new BallsModel.Ball[]
            //{
            //    new BallsModel.Ball(
            //        new BallsModel.Vector(20.0, 50.0),
            //        1.0,
            //        new BallsModel.Circle(5.0, 5.0, 1.0),
            //        FSharpOption<Guid>.None
            //    ),
            //    new BallsModel.Ball(
            //        new BallsModel.Vector(-20.0, 60.0),
            //        2.0,
            //        new BallsModel.Circle(5.0, 5.0, 2.0),
            //        FSharpOption<Guid>.None
            //    )
            //};

            Random rnd = new Random();

            BallsModel.Ball[] balls = new BallsModel.Ball[ballsCount].Select(_ =>
            {
                const double speed = 3;
                double dx          = rnd.NextDouble() * 5 * speed;
                double dy          = rnd.NextDouble() * 5 * speed;
                double r           = rnd.NextDouble() * 2 + 0.1;
                //double dx = 3;
                //double dy = 0.1;

                return(new BallsModel.Ball(
                           new BallsModel.Vector(dx, dy),
                           1.0,
                           new BallsModel.Circle(8.0, 5.0, r),
                           FSharpOption <Guid> .None
                           ));
            }).ToArray();

            double wallWeight = Math.Pow(10, 5);

            BallsModel.Wall[] walls = new BallsModel.Wall[] {
                //new BallsModel.Wall(
                //    new BallsModel.Point[]
                //    {
                //        new BallsModel.Point(20.0, 10.0),
                //        new BallsModel.Point(20.0, 45.0),
                //        new BallsModel.Point(25.0, 45.0),
                //        new BallsModel.Point(25.0, 10.0),
                //    },
                //    wallWeight,
                //    FSharpOption<Guid>.None
                //),
                //new BallsModel.Wall(
                //    new BallsModel.Point[]
                //    {
                //        new BallsModel.Point(20.0, 6.0),
                //        new BallsModel.Point(20.0, 7.0),
                //        new BallsModel.Point(25.0, 7.0),
                //        new BallsModel.Point(25.0, 6.0),
                //    },
                //    wallWeight,
                //    FSharpOption<Guid>.None
                //),

                // anchors
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(2.0, 0.0),
                    new BallsModel.Point(-1.0, 3.0),
                    new BallsModel.Point(-1.0, 0.0),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(boxWidth - 2, 0.0),
                    new BallsModel.Point(boxWidth + 1, 3.0),
                    new BallsModel.Point(boxWidth + 1, 0.0),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(boxWidth + 1, boxHeight - 2),
                    new BallsModel.Point(boxWidth - 2, boxHeight + 1),
                    new BallsModel.Point(boxWidth - 2, boxHeight + 1),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(-1.0, boxHeight - 2),
                    new BallsModel.Point(2.0, boxHeight + 1),
                    new BallsModel.Point(-1.0, boxHeight + 1),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),

                // square walls
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(boxWidth - 2, 0.0),
                    //new BallsModel.Point(39.0, 3.0),
                    new BallsModel.Point(boxWidth + 1, 3.0),
                    new BallsModel.Point(boxWidth + 1, 0.0),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(-1.0, 0.0),
                    new BallsModel.Point(boxWidth + 1, 0.0),
                    new BallsModel.Point(boxWidth + 1, 1.0),
                    new BallsModel.Point(-1.0, 1.0),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(boxWidth, 0.0),
                    new BallsModel.Point(boxWidth, boxHeight + 1),
                    new BallsModel.Point(boxWidth + 1, boxHeight + 1),
                    new BallsModel.Point(boxWidth + 1, 0.0),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(boxWidth + 1, boxHeight),
                    new BallsModel.Point(-1.0, boxHeight),
                    new BallsModel.Point(-1.0, boxHeight + 1),
                    new BallsModel.Point(boxWidth + 1, boxHeight + 1),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(0.0, 0.0),
                    new BallsModel.Point(0.0, boxHeight + 1),
                    new BallsModel.Point(-1.0, boxHeight + 1),
                    new BallsModel.Point(-1.0, 0.0),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),

                // other walls
                new BallsModel.Wall(
                    new BallsModel.Point[]
                {
                    new BallsModel.Point(20.0, 20.0),
                    new BallsModel.Point(30.0, 15.0),
                    new BallsModel.Point(35.0, 30.0),
                    new BallsModel.Point(25.0, 33.0),
                },
                    wallWeight,
                    FSharpOption <Guid> .None
                    ),
            };

            BallsModel.State initialState =
                new BallsModel.State(
                    balls,
                    walls,
                    (double)stopWatch.ElapsedMilliseconds / 1000,
                    FSharpOption <
                        Microsoft.FSharp.Collections.FSharpMap <
                            Guid,
                            BallsModel.Collision
                            >
                        > .None
                    );
            room = new Room(initialState);

            renderTimer.Interval = 4;
            renderTimer.Tick    += (s, a) =>
            {
                Invalidate();
            };

            textStateTimer.Interval = 100;
            textStateTimer.Tick    += (s, a) =>
            {
                printState();
            };

            textStateTimer.Start();
            renderTimer.Start();
            stopWatch.Start();

            lastRealTime = (double)stopWatch.ElapsedMilliseconds / 1000;
            lastSimTime  = lastRealTime;
        }
Ejemplo n.º 7
0
        public static void Draw(
            Graphics g,
            BallsModel.State state,
            double time,
            float scale        = 1,
            float scaleVectors = 1,
            bool showCenter    = true,
            bool showFrame     = false,
            bool showVector    = true
            )
        {
            Pen wallPen = new Pen(Color.Black, 3f);

            foreach (BallsModel.Wall wall in state.walls)
            {
                PointF[] points =
                    wall.frame.points
                    .Select(p => new PointF((float)p.x * scale, (float)p.y * scale))
                    .ToArray();

                HatchBrush hBrush = new HatchBrush(
                    HatchStyle.ForwardDiagonal,
                    Color.White,
                    Color.Gray
                    );

                g.FillPolygon(
                    hBrush,
                    points
                    );

                g.DrawPolygon(
                    wallPen,
                    points
                    );
            }



            Pen   ballPen         = new Pen(Color.DarkRed, 2f);
            Brush ballCenterBrush = Brushes.Red;
            Pen   ballVectorPen   = new Pen(Color.DarkGreen, 3f);

            ballVectorPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;

            double timeDelta = time - state.timeStamp;

            foreach (BallsModel.Ball ball in state.balls)
            {
                double currentX = ball.frame.x + ball.ph.speed.dx * timeDelta;
                double currentY = ball.frame.y + ball.ph.speed.dy * timeDelta;

                float r = (float)ball.frame.radius * scale * 2;
                float x = (float)(currentX * scale);
                float y = (float)(currentY * scale);

                if (showCenter)
                {
                    float cr = scale / 2;
                    g.DrawRectangle(ballPen, x - cr / 2, y - cr / 2, cr, cr);
                }

                if (showFrame)
                {
                    // draw circle
                    g.DrawEllipse(ballPen, x - r / 2, y - r / 2, r, r);
                }

                if (showVector)
                {
                    // draw speed vector
                    float dx = (float)ball.ph.speed.dx * scaleVectors;
                    float dy = (float)ball.ph.speed.dy * scaleVectors;
                    g.DrawLine(ballVectorPen, x, y, x + dx, y + dy);

                    // draw center circle
                    g.FillEllipse(
                        ballCenterBrush,
                        x - 5,
                        y - 5,
                        10,
                        10
                        );
                }
            }
        }