瘋狂的圖形(利用C# + GDI plus模擬雜亂無章的現實場景)
本文給出了模擬竹葉、長葉草、雜亂石頭、天上繁星等關鍵代碼。使用.Net環境下C#語言,GDI+編寫。
?
模擬竹葉
挺像的吧?誰說不像,我跟誰急!
//關鍵參數
int minCorners = 3;
int maxCorners =4;
PointF[] points = Stone.CreateStone(new Point((int)(perX * j), (int)(perY * i)), (int)(perX * 1.4f), (int)(perX * 0.009f), corners);
模擬長葉青草
說實話,這個不太像,太整齊了,應該再雜亂無章點。
//關鍵參數
int minCorners = 20;
int maxCorners =38;
PointF[] points = Stone.CreateStone(new Point((int)(perX * j), (int)(perY * i)), (int)(perX * 0.88f), (int)(perX * 0.01f), corners);
g.FillClosedCurve(Brushes.Green, points, FillMode.Winding);
?
模擬不規則的石塊
這個……怎麽有的石塊總是多出來那麽一點點,好像石頭上長了草似的?如果被你發現,說明你是個細心的人。反之,說你粗心也不為過,哈哈!
//關鍵參數:
int minCorners = 3;
int maxCorners =4;
PointF[] points = Stone.CreateStone(new Point((int)(perX * j), (int)(perY * i)), (int)(perX * 0.4f), (int)(perX * 0.396f), corners);
g.FillClosedCurve(Brushes.Gray, points, FillMode.Winding);
?
天上星,亮晶晶
//關鍵參數:
int minCorners = 3;
int maxCorners =4;
PointF[] points = Stone.CreateStone(new Point((int)(perX * j), (int)(perY * i)), (int)(perX * 0.18f), (int)(perX * 0.06f), corners);
g.FillClosedCurve(Brushes.White, points, FillMode.Winding);
?
//關鍵代碼:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace ZPXP.Com.Util
{
??? public static class Stone
??? {
??????? public static PointF[] CreateStone(Point center, int outerRadius, int inner_radius, int arms)
??????? {
??????????? int center_x = center.X;
??????????? int center_y = center.Y;
??????????? PointF[] points = new PointF[arms * 2];
??????????? double offset = Math.PI / 2;
??????????? double arc = 2 * Math.PI / arms;
??????????? double half = arc / 2;
??????????? double angle = 0;
??????????? for (int i = 0; i < arms; i++)
??????????? {
??????????????? Random randomOuter = new Random((int)DateTime.Now.Ticks);
??????????????? outerRadius = outerRadius - randomOuter.Next((int)(inner_radius * 0.06 * new Random().Next(-20,20) /30d), (int)(inner_radius * 0.08));
??????????????? //outerRadius = outerRadius - randomOuter.Next((int)(inner_radius * 0.16 * new Random().Next(-20, 20) / 30d), (int)(inner_radius * 0.18));
??????????????? Random randomInner = new Random(Guid.NewGuid().GetHashCode());
??????????????? inner_radius = inner_radius + randomInner.Next((int)(inner_radius * 0.02 * new Random().Next(-100,100) /150d), (int)(inner_radius * 0.08));
??????????????? //inner_radius = inner_radius + randomInner.Next((int)(inner_radius * 0.02 * new Random().Next(-100, 100) / 150d), (int)(inner_radius * 0.22));
??????????????
??????????????? if (inner_radius > outerRadius)
??????????????? {
??????????????????? int temp = outerRadius;
??????????????????? outerRadius = inner_radius;
??????????????????? inner_radius = temp;
??????????????? }
??????????????? double angleTemp = arc * randomInner.Next(-5, 5) / 10d;
??????????????? angle = i * arc;
??????????????? angle += angleTemp;
??????????????? points[i * 2].X = (float)(center_x + Math.Cos(angle - offset) * outerRadius);
??????????????? points[i * 2].Y = (float)(center_y + Math.Sin(angle - offset) * outerRadius);
??????????????? points[i * 2 + 1].X = (float)(center_x + Math.Cos(angle + half - offset) * inner_radius);
??????????????? points[i * 2 + 1].Y = (float)(center_y + Math.Sin(angle + half - offset) * inner_radius);
??????????? }
??????????? return points;
??????? }
??? }
}
?
測試用代碼:
private void button3_Click(object sender, EventArgs e)
??????? {
??????????? int width = 500;
??????????? int height = 500;
??????????? int x = 0;
??????????? int y = 0;
??????????? int numX = 10;
??????????? int numY =10;
??????????? float perX = width * 1f / numX;
??????????? float perY = height * 1f / numY;
??????????? Bitmap image = new Bitmap(width, height);
??????????? Graphics g = Graphics.FromImage(image);
??????????? g.CompositingQuality = CompositingQuality.HighQuality;
??????????? g.SmoothingMode = SmoothingMode.HighQuality;
??????????? g.InterpolationMode = InterpolationMode.HighQualityBicubic;
??????????? g.FillRectangle(Brushes.Black, new Rectangle(0,0, width, height));
??????????? int minCorners = 3;
??????????? int maxCorners =18;
??????????? int lastCorners = minCorners;
??????????? for (int i = 0; i < numX; i++)
??????????? {
??????????????? for (int j = 0; j < numY; j++)
??????????????? {
??????????????????? long tick = DateTime.Now.Ticks;
??????????????????? Random random = new Random((int)(tick & 0xffffffff) | (int)(tick >> 32));
??????????????????? int corners = random.Next(minCorners, maxCorners);
??????????????????? if (Math.Abs(corners - lastCorners) < (maxCorners - minCorners) / 2) corners = RetrievRandomCorners(minCorners, maxCorners);
??????????????????? lastCorners = corners;
??????????????????? //PointF[] points = Stone.CreateStone(new Point((int)(perX * j), (int)(perY * i)), (int)(perX * 0.9f), (int)(perX * 0.8f), corners);
??????????????????? PointF[] points = Stone.CreateStone(new Point((int)(perX * j), (int)(perY * i)), (int)(perX * 0.18f), (int)(perX * 0.06f), corners);
??????????????????? g.FillClosedCurve(Brushes.White, points, FillMode.Winding);
??????????????? }
??????????? }
??????????? picEncode.Image = image;
??????? }
??????? private int RetrievRandomCorners(int minCorners, int maxCorners)
??????? {
??????????? return new Random(Guid.NewGuid().GetHashCode()).Next(minCorners, maxCorners);
??????? }
?
瘋狂的圖形(利用C# + GDI plus模擬雜亂無章的現實場景)