您的位置:首页 > 编程语言 > C#

【Code Art / C#】随机贝塞尔曲线效果测试

2016-03-18 20:22 429 查看








贝塞尔曲线是通过几个控制点来绘制曲线的一种方法。通过若干个贝塞尔曲线随机组合,然后随机移动每个控制点,会实现怎样的效果呢?

用这样简单粗暴的思路,写了以下绘制代码。

然后将画完的一帧做模糊处理,不擦除画布继续画一帧,然后用Timer循环绘制,便实现了如图所示的效果。

以下为随机绘制一帧的代码,如需要动画效果和如图所示的效果请参照以上思路自行实现。

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using sf = RandBezier.SystemFramework;

namespace RandBezier
{
/// <summary>
/// 贝塞尔节点结构
/// </summary>
public class RandPoint
{
public RandPoint()
{
this.X = sf.Rand.Next(0, sf.Win_Width);
this.Y = sf.Rand.Next(0, sf.Win_Height);
this.dx = sf.Rand.Next(-100, 100) * 1f / 100;
this.dy = sf.Rand.Next(-100, 100) * 1f / 100;
this.offset_dx = sf.Rand.Next(-100, 100) * 1f / 1000;
this.offset_dy = sf.Rand.Next(-100, 100) * 1f / 1000;
}

public float X { get; set; }
public float Y { get; set; }
public float dx = 0f;
public float dy = 0f;

private float offset_dx = 0f;
private float offset_dy = 0f;
private int count = 0;

/// <summary>
/// 移动处理
/// </summary>
public void Do()
{
this.X += this.dx;
if (this.X < 0 || this.X > sf.Win_Width)
{
this.dx = -this.dx;
this.offset_dx = -this.offset_dx;
}
this.Y += this.dy;
if (this.Y < 0  || this.Y > sf.Win_Height)
{
this.dy = -this.dy;
this.offset_dy = -this.offset_dy;
}
this.dx += this.offset_dx;
if (Math.Abs(this.dx) > 10)
{
this.offset_dx = -this.offset_dx;
}
this.dy += this.offset_dy;
if (Math.Abs(this.dy) > 10)
{
this.offset_dy = -this.offset_dy;
}
if (this.count > 150)
{
this.count = 0;
this.offset_dx = sf.Rand.Next(-100, 100) * 1f / 1000;
this.offset_dy = sf.Rand.Next(-100, 100) * 1f / 1000;
}
this.count++;
}
}

/// <summary>
/// 颜色结构
/// </summary>
public class RandColor
{
private int min = 180;
private int max = 255;

public RandColor()
{
this.R = sf.Rand.Next(min, max);
this.G = sf.Rand.Next(min, max);
this.B = sf.Rand.Next(min, max);
this.offset_r = sf.Rand.Next(-5, 5);
this.offset_g = sf.Rand.Next(-5, 5);
this.offset_b = sf.Rand.Next(-5, 5);
}

public int R { get; set; }
public int G { get; set; }
public int B { get; set; }

private int offset_r = 0;
private int offset_g = 0;
private int offset_b = 0;
private int count = 0;

public void Do()
{
this.R += this.offset_r;
if (this.R < min)
{
this.R = min;
this.offset_r = -this.offset_r;
}
if (this.R > max)
{
this.R = max;
this.offset_r = -this.offset_r;
}
this.G += this.offset_g;
if (this.G < min)
{
this.G = min;
this.offset_g = -this.offset_g;
}
if (this.G > max)
{
this.G = max;
this.offset_g = -this.offset_g;
}
this.B += this.offset_b;
if (this.B < min)
{
this.B = min;
this.offset_b = -this.offset_b;
}
if (this.B > max)
{
this.B = max;
this.offset_b = -this.offset_b;
}
if (this.count > 100)
{
this.count = 0;
this.offset_r = sf.Rand.Next(-5, 5);
this.offset_g = sf.Rand.Next(-5, 5);
this.offset_b = sf.Rand.Next(-5, 5);
}
this.count++;
}

public Color GetColor()
{
return Color.FromArgb(this.R, this.G, this.B);
}
}

/// <summary>
/// 贝塞尔绘制器
/// </summary>
public class BezierDraw
{
private int Width = 800;
private int Height = 600;
private Graphics graphics = null;
private Bitmap bmp_temp = null;
private Bitmap bmp_back = null;
private List<RandPoint> pointList;
private List<PointF> pointDrawList;
private RandColor randColor;

/// <summary>
/// 构造函数
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="g"></param>
public BezierDraw(int width,int height,Graphics g)
{
this.Width = width;
this.Height = height;
this.graphics = g;
this.bmp_temp = new Bitmap(width, height);
this.bmp_back = new Bitmap(width, height);
this.pointList = new List<RandPoint>();
this.randColor = new RandColor();
this.pointDrawList = new List<PointF>();
for (int i = 0; i < 100; i++)
{
pointList.Add(new RandPoint());
}
}

/// <summary>
/// 处理
/// </summary>
public void Do()
{
if (randColor != null)
{
randColor.Do();
}
if (pointDrawList != null && pointList != null)
{
pointDrawList.Clear();
foreach (RandPoint p in pointList)
{
p.Do();
pointDrawList.Add(new PointF(p.X,p.Y));
}
}
}

private int count = 0;

/// <summary>
/// 画出
/// </summary>
public void Draw()
{
if (graphics != null && bmp_temp != null && randColor != null)
{
// 背景图
Graphics gb = Graphics.FromImage(bmp_back);
gb.FillRectangle(new SolidBrush(Color.Black), 0, 0, Width, Height);

// 渐变
if (count > 25)
{
bmp_temp = BitmapCtrlOpacity(bmp_temp, 0.89f);
count = 0;
}
else
{
bmp_temp = BitmapCtrlOpacity(bmp_temp, 0.95f);
}
count++;
bmp_temp = BimapZoom(bmp_temp);
// bmp_temp = GaussianBlur(bmp_temp);
// bmp_temp = BitmapOpacity(bmp_temp, 0.95f);
Graphics g = Graphics.FromImage(bmp_temp);
g.SmoothingMode = SmoothingMode.AntiAlias;

// 画曲线
Pen pen = new Pen(randColor.GetColor());
pen.Width = 1.5f;
g.DrawBeziers(pen, pointDrawList.ToArray());

// 画到背景上
gb.DrawImage(bmp_temp, 0, 0);
// 画到设备上
graphics.DrawImage(bmp_back, 0, 0);
}
}

public static Bitmap BimapZoom(Bitmap srcBitmap)
{
Bitmap bmp = new Bitmap(srcBitmap.Width, srcBitmap.Height);
Bitmap bmp_temp = new Bitmap((int)(srcBitmap.Width / 2.5), (int)(srcBitmap.Height / 2.5));
Graphics g = Graphics.FromImage(bmp_temp);
g.SmoothingMode = SmoothingMode.HighSpeed;
g.DrawImage(srcBitmap, 0, 0, bmp_temp.Width, bmp_temp.Height);
g = Graphics.FromImage(bmp);
g.SmoothingMode = SmoothingMode.HighSpeed;
g.DrawImage(bmp_temp, 0, 0, srcBitmap.Width, srcBitmap.Height);
return bmp;
}

/// <summary>
/// 设置图像透明度
/// </summary>
/// <param name="srcImage">源图像</param>
/// <param name="opacity">透明度</param>
/// <returns>返回图像</returns>
public static Bitmap BitmapCtrlOpacity(Bitmap srcImage, float opacity)
{
float[][] nArray ={ new float[] {1, 0, 0, 0, 0},
new float[] {0, 1, 0, 0, 0},
new float[] {0, 0, 1, 0, 0},
new float[] {0, 0, 0, opacity, 0},
new float[] {0, 0, 0, 0, 1}
};
ColorMatrix matrix = new ColorMatrix(nArray);
ImageAttributes attributes = new ImageAttributes();
attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
Bitmap resultImage = new Bitmap(srcImage.Width, srcImage.Height);
Graphics g = Graphics.FromImage(resultImage);
g.SmoothingMode = SmoothingMode.HighSpeed;
g.DrawImage(srcImage, new Rectangle(0, 0, srcImage.Width, srcImage.Height), 0, 0, srcImage.Width, srcImage.Height, GraphicsUnit.Pixel, attributes);
//DrawImage(srcImage, ref resultImage, new Rectangle(0, 0, srcImage.Width, srcImage.Height), new Point(0, 0));
g.Dispose();
return resultImage;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: