注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

信息 灵感 创新

I? =Information,Inspiration,Innovation

 
 
 

日志

 
 
关于我

we are 5. Mathematics, Computation, Programming, Engineering, and Making fun of life.

网易考拉推荐

GDI+绘制Lissajous图形  

2014-01-08 11:18:15|  分类: C# & .NET |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

为了能让PropertyGrid配置其属性(Property),加上了一些特性(Attribute)。该类主要的方法是DrawLissajousImage,返回一个给定宽度的正方形位图。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace Lissajous
{
    class LissajousGenerator
    {
        Color backGroundColor;
        Color circleColor;
        Color lissajousColor;
        Color axisColor;
        Color lineColor;
        Color crossLineColor;
        Color fontColor;
        float ratio;
        int omega = 2;
        GraphicsPath gp;
        int AX, AY;
        int p, q;
        double phi1, phi2;
        Font font;
        public LissajousGenerator()
        {
            backGroundColor = Color.FromArgb(240, 240, 240);
            circleColor = Color.Green;
            lissajousColor = Color.Red;
            axisColor = Color.Black;
            lineColor = Color.Blue;
            crossLineColor = Color.Yellow;
            ratio = 0.8f;
            AX = 30;
            AY = 40;
            phi1 = 0;
            phi2 = 0;
            p = 2;
            q = 3;
            font = new Font("Times New Roman", 10);
            fontColor = Color.Black;
            gp = new GraphicsPath();
        }

        public void ClearGraphicsPath()
        {
            gp = new GraphicsPath();
        }

        public Bitmap DrawLissajousImage(int length, int t)
        {
            try
            {
                double PI = Math.PI;
                Bitmap bmp = new Bitmap(length, length);
                SolidBrush sb = new SolidBrush(FontColor);
                Graphics gr = Graphics.FromImage(bmp);
                gr.Clear(backGroundColor);
                //draw axises
                gr.DrawLine(new Pen(axisColor), new PointF(length / 4f, length / 2f), new PointF(length / 4f, length));
                gr.DrawLine(new Pen(axisColor), new PointF(0, length * 3 / 4f), new PointF(length, length * 3 / 4f));
                gr.DrawLine(new Pen(axisColor), new PointF(length * 3 / 4f, 0), new PointF(length * 3 / 4f, length));
                gr.DrawLine(new Pen(axisColor), new PointF(length / 2f, length / 4f), new PointF(length, length / 4f));

                //draw two basic circles,with phase line
                int little = Math.Min(AX, AY);
                double theta1 = (phi1 + p * t * omega) * PI / 180;
                double theta2 = (phi2 + q * t * omega) * PI / 180;

                float RX, RY;
                if (AX == little)
                {
                    RY = length / 4f * ratio;
                    RX = RY * AX / AY;
                }
                else
                {
                    RX = length / 4f * ratio;
                    RY = RX * AY / AX;
                }
                gr.DrawArc(new Pen(circleColor), new RectangleF(length / 4f - RX, length * 3 / 4f - RX, 2 * RX, 2 * RX), 0, 360);
                gr.DrawLine(new Pen(lineColor),
                    new PointF(length / 4f, length * 3 / 4f),
                    new PointF(length / 4f + RX * (float)Math.Cos(theta1), length * 3 / 4f - RX * (float)Math.Sin(theta1))
                    );
                gr.DrawArc(new Pen(circleColor), new RectangleF(length * 3 / 4f - RY, length / 4f - RY, 2 * RY, 2 * RY), 0, 360);
                gr.DrawLine(new Pen(lineColor),
                    new PointF(length * 3 / 4f, length / 4f),
                    new PointF(length * 3 / 4f + RY * (float)Math.Cos(theta2), length / 4f - RY * (float)Math.Sin(theta2))
                    );
                //draw crossline
                gr.DrawLine(new Pen(crossLineColor),
                    new PointF(length / 4f + RX * (float)Math.Cos(theta1), length * 3 / 4f - RX * (float)Math.Sin(theta1)),
                    new PointF(length * 3 / 4f + RY * (float)Math.Cos(theta2), length * 3 / 4f - RX * (float)Math.Sin(theta1))
                    );
                gr.DrawLine(new Pen(crossLineColor),
                    new PointF(length * 3 / 4f + RY * (float)Math.Cos(theta2), length / 4f - RY * (float)Math.Sin(theta2)),
                    new PointF(length * 3 / 4f + RY * (float)Math.Cos(theta2), length * 3 / 4f - RX * (float)Math.Sin(theta1))
                    );
                //draw Lissajous
                int r = LCM(p, q);
                int step = 2;
                List<PointF> points = new List<PointF>();
                for (int i = 0; i < 360 * r; i += step)
                {
                    PointF pf = new PointF(length * 3 / 4f + RY * (float)Math.Cos(theta2), length * 3 / 4f - RX * (float)Math.Sin(theta1));
                    points.Add(pf);
                }
                gp.AddLines(points.ToArray());
                gr.DrawPath(new Pen(lissajousColor), gp);

                //infos
                gr.DrawString("Programmed by Lemniscate", font, sb, new Point(0, 0));
                gr.DrawString(DateTime.Now.ToLongTimeString(), font, sb, new Point(0, 15));
                string s = string.Format("A1={0},p={1}, θè1={2}", AX, p, theta1 * 180 / PI);
                gr.DrawString(s, font, sb, new Point(0, 30));
                s = string.Format("A2={0},q={1}, θè2={2}", AY, q, theta2 * 180 / PI);
                gr.DrawString(s, font, sb, new Point(0, 45));
                gr.DrawString(string.Format("Current Point:({0},{1})", RY * (float)Math.Cos(theta2), -RX * (float)Math.Sin(theta1)), font, sb, new Point(0, 60));

                return bmp;
            }
            catch
            {
                //just omit
            }
            return null;
        }

        //get the least common multiple
        private int LCM(int a, int b)
        {
            return a * b / GCD(a, b);
        }
        //get the greatest common denominator
        private int GCD(int a, int b)
        {
            int k = 0;
            do
            {
                k = a % b;
                a = b;
                b = k;
            } while (k != 0);
            return a;
        }

        /***************************************************************/
        [Category("几何参数"), Description("基圆转速"), DisplayName("基圆转速")]
        public int Omega
        {
            get
            {
                return omega;
            }
            set
            {
                if (omega < 0 || omega > 30)
                    throw new Exception("基圆转速必须介于0到30之间");
                omega = value;
            }
        }

        [Category("几何参数"), Description("X基圆半径"), DisplayName("X基圆半径")]
        public int R1
        {
            get
            {
                return AX;
            }
            set
            {
                if (AX < 0)
                    throw new Exception("半径必须大于0");
                AX = value;
            }
        }

        [Category("几何参数"), Description("X基圆转速倍率"), DisplayName("X基圆转速倍率")]
        public int P
        {
            get
            {
                return p;
            }
            set
            {
                if (p < 0)
                    throw new Exception("基圆转速倍率必须大于0");
                p = value;
            }
        }

        [Category("几何参数"), Description("X基圆初始相位"), DisplayName("X基圆初始相位")]
        public double PHI1
        {
            get
            {
                return phi1;
            }
            set
            {
                phi1 = value;
            }
        }

        [Category("几何参数"), Description("Y基圆半径"), DisplayName("Y基圆半径")]
        public int R2
        {
            get
            {
                return AY;
            }
            set
            {
                if (AY < 0)
                    throw new Exception("半径必须大于0");
                ratio = value;
            }
        }

        [Category("几何参数"), Description("Y基圆转速倍率"), DisplayName("Y基圆转速倍率")]
        public int Q
        {
            get
            {
                return q;
            }
            set
            {
                if (q < 0)
                    throw new Exception("基圆转速倍率必须大于0");
                q = value;
            }
        }

        [Category("几何参数"), Description("Y基圆初始相位"), DisplayName("Y基圆初始相位")]
        public double PHI2
        {
            get
            {
                return phi2;
            }
            set
            {
                phi2 = value;
            }
        }

        [Category("绘图参数"), Description("坐标轴颜色"), DisplayName("坐标轴颜色")]
        public Color AxisColor
        {
            get
            {
                return axisColor;
            }
            set
            {
                axisColor = value;
            }
        }

        [Category("绘图参数"), Description("基圆颜色"), DisplayName("基圆颜色")]
        public Color CircleColor
        {
            get
            {
                return circleColor;
            }
            set
            {
                circleColor = value;
            }
        }

        [Category("绘图参数"), Description("相位线颜色"),DisplayName("相位线颜色")]
        public Color LineColor
        {
            get
            {
                return lineColor;
            }
            set
            {
                lineColor = value;
            }
        }

        [Category("绘图参数"), Description("相交线颜色"), DisplayName("相交线颜色")]
        public Color CrossLineColor
        {
            get
            {
                return crossLineColor;
            }
            set
            {
                crossLineColor = value;
            }
        }

        [Category("绘图参数"), Description("李萨如曲线颜色"), DisplayName("李萨如曲线颜色")]
        public Color LissajousColor
        {
            get
            {
                return lissajousColor;
            }
            set
            {
                lissajousColor = value;
            }
        }

        [Category("绘图参数"), Description("基圆显示比率"), DisplayName("基圆显示比率")]
        public float Ratio
        {
            get
            {
                return ratio;
            }
            set
            {
                if (value <= 0 || value > 1)
                    throw new Exception("比率必须介于0-1之间");
                ratio = value;
            }
        }

        [Category("绘图参数"), Description("信息字体"), DisplayName("信息字体")]
        public Font DisplayFont
        {
            get
            {
                return font;
            }
            set
            {
                font = value;
            }
        }

        [Category("绘图参数"), Description("字体颜色"), DisplayName("字体颜色")]
        public Color FontColor
        {
            get
            {
                return fontColor;
            }
            set
            {
                fontColor = value;
            }
        }
    }
}
接下来的工作就是如何调用了,需要提供一个参数t,该参数会指明绘制的时间。
  评论这张
 
阅读(522)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016