Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C#] шарик на нитке


Автор: m412 4.4.2007, 07:21
Здравствуйте!
тут такая проблема... 
на C#2005 нужно сделать курсовую....

а задание такое:
На нити болтается шарик... нужно чтобы после нажатия кнопки он болтался и постепенно затухал....

этот вопрос я уже задавал http://forum.vingrad.ru/topic-127569/kw-%D1%88%D0%B0%D1%80%D0%B8%D0%BA/view-all.html

много получил полезного... но вот затухнуть он всетаки не смог...
там даже приводили формулу затухания... но я чесно говоря понятия не имею как ее правильно использовать...!

вот имеющийся код
Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace шарик_на_ните
{
    public partial class Form1 : Form
    {
     
        private Point _centerOfBall;
    
        public Form1()
        {
            InitializeComponent();
            
            calculateBallCenter();
            timer1.Tick += new EventHandler(timer1_Tick);
           
        }
        void timer1_Tick(object sender, EventArgs e)
        {
            calculateBallCenter();
            this.Invalidate();
        }
        void calculateBallCenter()
        {
            double k = 0.05F;
            int x = (int)(200 + 100 * Math.Sin(k * DateTime.Now.Ticks / 1000000));
            int y = (int)(10 + 100 * Math.Abs(Math.Cos(k * DateTime.Now.Ticks / 1000000)));
            _centerOfBall = new Point(x, y);
           
        }
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            
            Graphics g = e.Graphics;
            Graphics gr = e.Graphics;

            Rectangle noname = new Rectangle(0,0,410,250);
            gr.FillRectangle(Brushes.AliceBlue, noname);

            Rectangle noname1 = new Rectangle(0,260,410,160);
            gr.FillRectangle(Brushes.YellowGreen,noname1);

            Rectangle noname2 = new Rectangle(190, 0, 20, 10);
            gr.FillRectangle(Brushes.Black, noname2);

           
             Point beginOfLine = new Point(200, 10);
            g.DrawLine(Pens.Black, beginOfLine, _centerOfBall);
          
            Rectangle ballRectangle = new Rectangle(_centerOfBall - new Size(10, 10), new Size(20, 20));
            g.FillEllipse(Brushes.Black, ballRectangle);

        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Start();

        } 
    }
}


Заранее спасибо

Автор: ivashkanet 12.4.2007, 11:25
m412, лови свой код, разбирайся:
Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace BallOnTheThread
{
    public partial class BallOnTheThreadScreen : UserControl
    {
        public BallOnTheThreadScreen()
        {
            recalculateParameters();
            InitializeComponent();
            _timer = new Timer();
            _timer.Interval = 100; // Каждые 0,1 секунды будет срабатывать таймер
            _timer.Tick += new EventHandler(_timer_Tick);
        }
        #region Interface
        [DefaultValue(100)]
        public int ThreadLength
        {
            get { return _threadLength; }
            set
            { _threadLength = value; recalculateParameters(); }
        }
        [DefaultValue(100)]
        public int BallMass
        {
            get { return _ballMass; }
            set
            { _ballMass = value; recalculateParameters(); }
        }
        [DefaultValue(60)]
        public int StartAngle
        {
            get { return _startAngle; }
            set { _startAngle = value; recalculateParameters(); }
        }
        public void StartBall()
        {
            _startTime = DateTime.Now;
            _isBallMoving = true;
            _timer.Start();
        }
        public void StopBall()
        {
            _isBallMoving = false;
            _timer.Stop();
        }
        #endregion

        #region PrivateMembers
        private DateTime _startTime;
        private int _threadLength = 100; // длинна в "пикселях"
        private int _ballMass = 100;    // масса шарика в граммах
        private int _startAngle = 60;   // угол в градусах

        private double _alpha0 = Math.PI / 2;  // угол в радианах
        private double _m = 0.1;               // масса шарика в килограммах
        private double _g = 9.81F;
        private double _betta = 100;
        private double _gamma;
        private double _omega;

        private Timer _timer;
        private bool _isBallMoving = false;
        #endregion

        #region BackgroundLogic
        void _timer_Tick(object sender, EventArgs e)
        {
            this.Invalidate();
        }
        private void recalculateParameters()
        {
            _alpha0 = _startAngle * Math.PI / 180;
            _m = _ballMass * 0.001;
            _gamma = 0.5 * _betta / (_ballMass * _threadLength);
            _omega = Math.Sqrt(_g / _threadLength);
        }
        private double getBallAngle()
        {
            if (_isBallMoving)
            {
                double dt = ((TimeSpan)(DateTime.Now - _startTime)).TotalSeconds;

                // коэффициент затухания
                double fadingParametr = Math.Exp(-_gamma * dt);   

                if (Math.Abs(fadingParametr * _alpha0) < 0.001)
                {
                    // Останавливаем шарик, так как он уже не движется
                    StopBall();
                }

                return _alpha0 * fadingParametr * Math.Cos(_omega * dt);
            }
            else { return _alpha0; }
        }
        private void BallOnTheThreadScreen_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            // Запоминаем размеры картинки
            int width = this.Width;
            int height = this.Height;

            // Берем кисти и краски :) (ручки),
            // которые понадобятся нам для рисования
            Pen pen = Pens.Black;
            Brush brush = Brushes.Black;

            // Рисуем место крепления шарика
            g.FillRectangle(brush, new Rectangle((int)(0.5 * width - 5), 0, 10, 5));

            // Получаем текущий угол нити
            double currentAngle = getBallAngle();

            // Считаем координаты шарика
            int x = (int)(0.5 * width + _threadLength * Math.Sin(currentAngle));
            int y = (int)(_threadLength * Math.Cos(currentAngle));

            // Рисуем нитку и сам шарик
            g.DrawLine(pen, (int)(0.5 * width), 0, x, y);
            g.FillEllipse(brush, new Rectangle(x - 5, y - 5, 10, 10));
        }
        #endregion
    }
}


Ниже находится готовый проект:

Автор: m412 12.4.2007, 18:50
ААААААААААААААААААА

ТЫ ГЕНИЙ!!!!

у меня просто нет слово чтобы выразить свои эмоции!!!!
ОГРОМНОЕ ТЕБЕ СПАСИБО!!!! smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)