| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2556 人关注过本帖
标题:抛体运动2
取消只看楼主 加入收藏
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
结帖率:100%
收藏
已结贴  问题点数:100 回复次数:9 
抛体运动2
呵呵,抄袭了Tony的标题。这算是凑热闹也做个抛物线的动画演示。
这种东西我从来不认为有多少技术含量,这些都是基本功。比如这里用到的鼠标事件响应,图形输出双缓存等等。
各位喜欢大概还是因为好看,比算法分析更形象吧。

程序是用C#写的,需要.net 2.0及以上的支持。win7系统不必考虑这一问题。
这里是C论坛,我就不发C#代码了。想要的可以留个信息。

顺便散个分吧,最近工作很忙,来论坛不如以前勤快了。
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册
Parabola.rar (5.4 KB)

搜索更多相关主题的帖子: win7系统 凑热闹 抛物线 基本功 
2012-04-18 13:11
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
是吧,我猜你的操作系统是XP吧?

呵呵,我发的程序(不是指代码)几乎全是C#写的。每次我都会加句“需要.net 2.0及以上的支持”。我用C#比用C更顺手。
先开始我是用.net 4.0框架完成的,后来考虑到兼容性降到了2.0。
建议你去微软官网下一个.net framework。
还有一个方法就是安装VS2010,安装完后你的电脑上从2.0到4.0就全有了。也可以感受一下VS2010的乐趣。
其实我对VS2010最喜欢的是对UML的支持。建议偿试这个开发工具。

重剑无锋,大巧不工
2012-04-18 13:36
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复有容
    你先确认一下你的电脑有没有装.net 2.0。也许如hellovfp所说。我还真没注意过这个问题。没想过有4.0的机器上会没有2.0。

重剑无锋,大巧不工
2012-04-18 13:51
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 9楼 有容就大
Parabola.rar (5.41 KB)
试试这个,我将目标框架改成了4.0

重剑无锋,大巧不工
2012-04-18 14:18
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
完整解决方案发到有容和不吭声的邮箱了。

重剑无锋,大巧不工
2012-04-20 16:52
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
呵呵,我对注释的看法是,如果能用类名、变量名、函数名表达清楚的东西,就不加注释。注释多了未必是件好事。所以我的意见是尽量选用有意义的名称。

代码中,对抛物线的计算是用一个单独的类来完成的,显示则是由窗体的一个独立的成员函数来实现。分工很明确。

代码写的比较随意,两位见谅,不过从中应该还是可以感受到一点面向对象的思维方式吧。

重剑无锋,大巧不工
2012-04-20 18:21
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
this是一个关键字,表示当前类的一个实例(对象)。在C++中也有这个this对象。

重剑无锋,大巧不工
2012-04-20 18:37
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
嗯,该结贴了。如果大家喜欢这类程序,以后我可以多写一点。图形编程的相关书籍市面上一抓一把,我不想讲重复的东西。

关于如何学编程,我有个建议——仿制别人的程序。根据自己的水平挑些你大概可以理解的程序(包括游戏),偿试仿制。

重剑无锋,大巧不工
2012-04-21 21:11
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
picture control?是MFC里的控件吧?

很不好意思有容。我用的是C#,这里的图片控件叫picture box。也从没遇到过这类问题。更很多年没用过MFC了,对新版中它的控件也不是很了解。

所以还是请学用MFC的朋友回答吧。报歉了。

重剑无锋,大巧不工
2012-04-21 21:42
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
1、抛物线本来就是一个二次函数
2、图形用GDI+写的。随手写着玩的东西,并不涉及很深的图形算法。
3、当采样点越多矩齿现象就越小,图像越精致。GDI+中本身也带有消除矩齿的函数,不过这里并不很需要。
4、使用计时器来写的,这个小东西不需要多线程。在图像绘制过程中我不允许鼠标按键再响应绘制新图。

本不想发C#代码在C论坛里。不过没有代码算法交流起来很不方便,这里把程序的主要部分发上来吧。其实有C++底子的话,C#代码并不难看懂。

程序代码:
namespace Beyondyf
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            ox = 100;
            oy = 500;

            bgColor = Color.Black;

            brushArrow = new SolidBrush(Color.Red);
            brushBall = new SolidBrush(Color.Pink);
            brushLine = new SolidBrush(Color.Yellow);
            penLine = new Pen(brushLine);
            map = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            gMap = Graphics.FromImage(map);
            gMap.Clear(bgColor);
            DrawBall(gMap, ox, oy);
            gShow = this.CreateGraphics();

            timer = new Timer();
            timer.Tick += new EventHandler(DrawPath);
            timer.Interval = 20;
            setting = false;
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            gShow.DrawImage(map, 0, 0);
        }

        private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {
            if (setting) return;

            int dx = e.X - ox;
            int dy = e.Y - oy;
            double length = Math.Sqrt(dx * dx + dy * dy);
            double angle = length < 1 ? 0 : Math.Asin(dy / length);
            if (dx < 0) angle = Math.PI - angle;
            if (length < 1) velocity = 0;
            else if (length > 300) velocity = 300;
            else velocity = length;
            initAngle = -angle;

            gMap.Clear(bgColor);
            DrawArrow(gMap, ox, oy, velocity, angle);
            DrawBall(gMap, ox, oy);
            gShow.DrawImage(map, 0, 0);

        }

        private void MainForm_MouseMove(object sender, MouseEventArgs e)
        {
            if (!setting && (e.Button & System.Windows.Forms.MouseButtons.Left) != 0)
            {
                int dx = e.X - ox;
                int dy = e.Y - oy;
                double length = Math.Sqrt(dx * dx + dy * dy);
                double angle = length < 1 ? 0 : Math.Asin(dy / length);
                if (dx < 0) angle = Math.PI - angle;
                if (length < 1) velocity = 0;
                else if (length > 300) velocity = 300;
                else velocity = length;
                initAngle = -angle;

                gMap.Clear(bgColor);
                DrawArrow(gMap, ox, oy, velocity, angle);
                DrawBall(gMap, ox, oy);
                gShow.DrawImage(map, 0, 0);
            }
        }

        private void MainForm_MouseUp(object sender, MouseEventArgs e)
        {
            if (!setting)
            {
                setting = true;
                prb = new Parabola(velocity, initAngle, 1, 1000);
                timer.Start();
            }
        }

        private void DrawBall(Graphics g, float x, float y)
        {
            g.FillEllipse(brushBall, x - 10, y - 10, 20, 20);
        }

        private void DrawArrow(Graphics g, float x, float y, double length, double angle)
        {
            Point[] ps = new Point[3];
            ps[0].X = (int)(8 * Math.Cos(angle - Math.PI / 2) + x + 0.5);
            ps[0].Y = (int)(8 * Math.Sin(angle - Math.PI / 2) + y + 0.5);
            ps[1].X = (int)(8 * Math.Cos(angle + Math.PI / 2) + x + 0.5);
            ps[1].Y = (int)(8 * Math.Sin(angle + Math.PI / 2) + y + 0.5);
            ps[2].X = (int)(length * Math.Cos(angle) + x + 0.5);
            ps[2].Y = (int)(length * Math.Sin(angle) + y + 0.5);
            g.FillPolygon(brushArrow, ps);
        }

        private void DrawLine(Graphics g, Parabola p, int count)
        {
            for (int i = 1; i <= count; i++)
                g.DrawLine(penLine, p.X(i - 1, rate) + ox, oy - p.Y(i - 1, rate), p.X(i, rate) + ox, oy - p.Y(i, rate));
        }

        private void DrawPath(object sender, EventArgs e)
        {
            gMap.Clear(bgColor);
            DrawLine(gMap, prb, count);
            DrawBall(gMap, prb.X(count, rate) + ox, oy - prb.Y(count, rate));
            gShow.DrawImage(map, 0, 0);
            if (prb.Y(count, rate) < oy - 700)
            {
                timer.Stop();
                count = 0;
                setting = false;
            }
            else count++;
        }

        private Timer timer;

        private Parabola prb;

        private bool setting;
        private double velocity;
        private double initAngle;
        private int count;

        private const double rate = 10;

        private Bitmap map;
        private Graphics gMap;
        private Graphics gShow;
        private int ox;
        private int oy;
        private Color bgColor;
        private Brush brushArrow;
        private Brush brushBall;
        private Brush brushLine;
        private Pen penLine;
    }

    public class Parabola
    {
        public Parabola(double velocity, double angle, double timeStep, int stepCount)
        {
            x = new double[stepCount + 1];
            y = new double[stepCount + 1];
            double vx = velocity * Math.Cos(angle) * timeStep;
            double vy = velocity * Math.Sin(angle) * timeStep;
            double a = -9.8 / 2 * timeStep * timeStep;
            for (int i = 0; i <= stepCount; i++)
            {
                x[i] = vx * i;
                y[i] = vy * i + a * i * i;
            }
        }

        public float X(int index, double rate)
        {
            if (index < 0 && index >= x.Length) return 0;
            return (float)(x[index] / rate);
        }

        public float Y(int index, double rate)
        {
            if (index < 0 && index >= y.Length) return 0;
            return (float)(y[index] / rate);
        }

        private double[] x;
        private double[] y;
    }
}


重剑无锋,大巧不工
2012-05-02 18:54
快速回复:抛体运动2
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029637 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved