无理数,用于图案自动生成

           图案的自动生成,不仅能为工艺设计、建筑设计、镭射线条提供资源,还能为加密、结构光设计等方面提供更多的方案。由于研究视觉算法需要,产品中要识别各种曲线,也要在仿真中生成各种曲线。在中学学习阶段,大家都学过无理数,如:π ,e,sinϕ,cosϕ  等等。只知道是无限不循环小数。现在将无理数中的某一段取出来,视作整数,我们可以发现并无规律,如下图:

         接着,用一对无理数(sinϕ,cosϕ ),计算某一范围的函数值,也将某一段取出来,转为整数,在直角坐标系数中的图像如下:

正弦与余弦互为余角的特征,也即相位差,在上图中仍然显现了出来。

接着的算法思路是:对一个大圆,在圆周上取N个点,构成正N边形,正N边形的N个顶点坐标的(X,Y)重新计算,都对某一正整数K取模(相除,取出余数),即:      

//无理数构图算法N67:---编程语言:C#,编程环境:Windows10 + VS2012

private void button67_Click(object sender, EventArgs e)

{

    //绘图参数与工具:

    int xOrg = pictureBox1.Width / 2;

    int yOrg = pictureBox1.Height / 2;

    Bitmap bmp = new Bitmap(boxWidth, boxHeight);

    Graphics g = Graphics.FromImage(bmp);

    g.Clear(Color.Black);

    Brush bhRed = new SolidBrush(Color.Red);

    Brush bhWhite = new SolidBrush(Color.White);

    Pen penYellow = new Pen(Color.Yellow, 2);

    Pen penLightPink = new Pen(Color.LightPink, 2);

    //生成极坐标系下的数据集:

    Random  rd = new Random( (int)DateTime.Now.Ticks);//随机数据类

    int R1 = (int)1E6 + rd.Next( 567);//用作倍数

    int R2 = (int)1E3 + rd.Next( 321);//用作除数

    int stp = 3 +  3*rd.Next(9);//细分程度

    double maxR = 0;//记下最大半径

    List<Point> pt3 = new List<Point>(); //点的集合

    //算法构建---By daode1212,daode3056

    for (float q = -PI; q <= PI; q += PI / stp)

    {

        int x = (int)(R1 * Math.Cos(q) % R2);//X坐标先扩大,再取余数

        int y = (int)(R1 * Math.Sin(q) % R2);//Y坐标先扩大,再取余数

        double R=Math.Sqrt((x * x + y * y));//当前半径

        if ( R>  maxR)maxR = R; //记下最大半径

        pt3.Add(new Point(x, y));//添加到集合中  

    }

    //控制大小,并实现平移:

    var pt4  =  pt3.Select(o => new Point((int)(xOrg + 300 * o.X / maxR), (int)(yOrg + 300 * o.Y / maxR))).ToArray();

    //根据点的数目选择使用光滑曲线还是折线绘制:

    if (pt3.Count % 3 == 1)

    {

        g.DrawBeziers(penYellow, pt4); //光滑Bezier曲线

    }

    else

    {

        g.DrawLines(penLightPink, pt4); //折线绘制

    }

    pt3.Clear(); pt4 = null; //内存回收

    //生成文本与保存图片: ===============================

    string txt = sender.ToString().Split(':')[1] +string.Format("_{0}`{1}`{2}", R1,R2,stp);

    g.DrawString(txt, new Font("", 12), bhWhite, boxWidth / 2 - 150, boxHeight - 100);

    pictureBox1.Image = bmp;

    bmp.Save(txt + ".png"); this.Text = txt + ".png  ---文件已经保存";

    this.pictureBox1.Refresh();

}

用这个程序,并按各图片中的参数(R1`R2`stp),可以一一再现相应的图片。

对新的一系列坐标(Xnew,Ynew)画多边形,或画平滑的Bezier曲线,就得到下列各图:

         奇迹就从这里开始,我们用极坐标来绘制与展示,如下图:

用Bezier平滑插值(需要3N+1个点)来描绘,就更美了:

以下为多边形配上了背景

 

下是各图片的缩略图(局部):

现在取PI小数点后1000位,自用它的无限不循环特性,进行序列化也可生成各种花式的图案:

//取自PI的图案,算法第N70: ---编程语言:C#,编程环境:Windows10 + VS2012

private void button70_Click(object sender, EventArgs e)

{

            /*

             要计算PI小数点后3000位的,链接: https://math.tools/numbers/pi/3000

             */

            string strPI = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989";

            //string s13=  strPI.Substring(1, 3);//.14

            //string s23=  strPI.Substring(2, 3); //141

            //string s999_3=  strPI.Substring(999, 3);//898

           

            //====================================

            int[] sPI = new int[1000]; //可用范围:2---999

            for (int i = 2; i < 1000;i++ )

            {

                sPI[i] =Int32.Parse(strPI.Substring(i, 3));

            }

            //=====================================

            //绘图参数与工具:

            int xOrg = pictureBox1.Width / 2;

            int yOrg = pictureBox1.Height / 2;

            Bitmap bmp = new Bitmap(boxWidth, boxHeight);

            Graphics g = Graphics.FromImage(bmp);

            g.Clear(Color.Black);

            Brush bhBlue = new SolidBrush(Color.FromArgb(44,0,66));

            Brush bhWhite = new SolidBrush(Color.White);

            Pen penYellow = new Pen(Color.Yellow, 4);

            Pen penLightPink = new Pen(Color.LightPink, 2);

            //====================================

            //生成极坐标系下的数据集:

            Random rd = new Random((int)DateTime.Now.Ticks);//随机数据类

            int R1 = 999*sPI[2 + rd.Next(1000-2)];//用作倍数

            int R2 = sPI[2 + rd.Next(1000-2)]; ;//用作除数

            int stp = 3 + 3 * rd.Next(9);//细分程度

            double maxR = 0;//记下最大半径

            List<Point> pt3 = new List<Point>(); //点的集合

            //算法构建---By daode1212,daode3056

            for (float q = -PI; q <= PI; q += PI / stp)

            {

                int x = (int)(R1 * Math.Cos(q) % R2);//X坐标先扩大,再取余数

                int y = (int)(R1 * Math.Sin(q) % R2);//Y坐标先扩大,再取余数

                double R = Math.Sqrt((x * x + y * y));//当前半径

                if (R > maxR) maxR = R; //记下最大半径

                pt3.Add(new Point(x, y));//压入集合中  

            }

            //控制大小,并实现平移:

            var pt4 = pt3.Select(o => new Point((int)(xOrg + 300 * o.X / maxR), (int)(yOrg + 300 * o.Y / maxR))).ToArray();

            //根据点的数目选择使用光滑曲线还是折线簇绘制:

            if (pt3.Count % 3 == 1)

            {

                g.FillPolygon(bhBlue, pt4);

                g.DrawBeziers(penYellow, pt4);

            }

            else

            {

                g.FillClosedCurve(bhBlue, pt4);

                g.DrawLines(penLightPink, pt4);

            }

            pt3.Clear(); pt4 = null;

  //生成文本与保存图片: ===============================

  string txt = sender.ToString().Split(':')[1] + string.Format("_{0}`{1}`{2}", R1, R2, stp);

  g.DrawString(txt, new Font("", 12), bhWhite, boxWidth / 2 - 150, boxHeight - 50);

  pictureBox1.Image = bmp;

  bmp.Save(txt + ".png"); this.Text = txt + ".png  ---文件已经保存";

  this.pictureBox1.Refresh();

}

下是各图片的缩略图(局部):

二〇二二年八月二十六日

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值