基本信息
源码名称:C# 流媒体模拟例子源码
源码大小:0.02M
文件格式:.rar
开发语言:C#
更新时间:2015-09-14
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
/* * This Ver: * Copyright chocoboboy ( http://twitter.com/chocoboboy ) * MIT License ( http://www.opensource.org/licenses/mit-license.php ) */ /** * Flash version: * Copyright iunpin ( http://wonderfl.net/user/iunpin ) * MIT License ( http://www.opensource.org/licenses/mit-license.php ) * Downloaded from: http://wonderfl.net/c/6eu4 */ /** * Original Java version: * http://grantkot.com/MPM/Liquid.html */ using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Diagnostics; namespace LiquidSimulation { public partial class LiquidTest : Form { private List<Particle> particles = new List<Particle>(); private int gsizeX = 100; private int gsizeY = 100; private int particlesX = 60; private int particlesY = 60; private List<List<Node>> grid; private List<Node> active = new List<Node>(); private Material water = new Material(1, 1, 1, 1, 1, 1); private bool pressed = false; private bool pressedprev = false; private int mx = 0; private int my = 0; private int mxprev = 0; private int myprev = 0; private Bitmap _canvas; private Graphics _g; private Random rnd = new Random(5); public LiquidTest() { InitializeComponent(); } private void LiquidTest_Load(object sender, EventArgs e) { this.Height = gsizeY * 4 20; this.Width = gsizeX * 4 10; pictureBox1.Image = _canvas = new Bitmap(gsizeX * 4, gsizeY * 4); _g = Graphics.FromImage(_canvas); int i, j; grid = new List<List<Node>>(); for (i = 0; i < gsizeX; i ) { grid.Add(new List<Node>()); for (j = 0; j < gsizeY; j ) { grid[i].Add(new Node()); } } Particle p; for (i = 0; i < particlesX; i ) { for (j = 0; j < particlesY; j ) { p = new Particle(water, i 4, j 4, 0, 0); particles.Add(p); } } var action = new Action(() => { paint(null); }); action.BeginInvoke(new AsyncCallback(ar => { action.EndInvoke(ar); }), null); } void mouseMoved(object sender, MouseEventArgs e) { mx = e.X; my = e.Y; } void mouseReleased(object sender, MouseEventArgs e) { pressed = false; } void mousePressed(object sender, MouseEventArgs e) { pressed = true; } private void paint(object sender) { while (!(this.Disposing || this.IsDisposed)) { var watch = Stopwatch.StartNew(); simulate(); _g.Clear(Color.White); var data = _canvas.LockBits(new Rectangle(0, 0, _canvas.Width, _canvas.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); unsafe { int* ptr = (int*)data.Scan0.ToPointer(); foreach (var p in particles) { var x1 = (int)(4 * p.x); var y1 = (int)(4 * p.y); var x2 = (int)(4 * (p.x - p.u)); var y2 = (int)(4 * (p.y - p.v)); ptr[y1 * gsizeX * 4 x1 - 1] = Color.Blue.ToArgb(); ptr[y2 * gsizeX * 4 x2 - 1] = Color.LightBlue.ToArgb(); //_canvas.SetPixel(x1, y1, Color.Blue); //_canvas.SetPixel(x2, y2, Color.FromArgb(0x440000FF)); } } _canvas.UnlockBits(data); try { this.Invoke(new Action(() => { pictureBox1.Refresh(); var fps = 1000 / watch.ElapsedMilliseconds; this.Text = "Liquid Simulation FPS:" fps; })); } catch { } } } private void simulate() { bool drag = false; double mdx = 0.0, mdy = 0.0; if (pressed && pressedprev) { drag = true; mdx = 0.25 * (mx - mxprev); mdy = 0.25 * (my - myprev); } pressedprev = pressed; mxprev = mx; myprev = my; //Node n; //Particle p; foreach (var n in active) { n.clear(); } //active.length = 0; active.Clear(); int i, j; double x, y, phi; double fx = 0.0, fy = 0.0; foreach (var p in particles) { p.cx = (int)(p.x - 0.5); p.cy = (int)(p.y - 0.5); x = p.cx - p.x; p.px[0] = (0.5 * x * x 1.5 * x 1.125); p.gx[0] = (x 1.5); x = 1.0; p.px[1] = (-x * x 0.75); p.gx[1] = (-2.0 * x); x = 1.0; p.px[2] = (0.5 * x * x - 1.5 * x 1.125); p.gx[2] = (x - 1.5); y = p.cy - p.y; p.py[0] = (0.5 * y * y 1.5 * y 1.125); p.gy[0] = (y 1.5); y = 1.0; p.py[1] = (-y * y 0.75); p.gy[1] = (-2.0 * y); y = 1.0; p.py[2] = (0.5 * y * y - 1.5 * y 1.125); p.gy[2] = (y - 1.5); for (i = 0; i < 3; i ) { for (j = 0; j < 3; j ) { var n = grid[p.cx i][p.cy j]; if (!n.active) { active.Add(n); n.active = true; } phi = p.px[i] * p.py[j]; n.m = phi * p.mat.m; n.d = phi; n.gx = p.gx[i] * p.py[j]; n.gy = p.px[i] * p.gy[j]; } } } double density, pressure, weight; Node n01, n02; Node n11, n12; int cx, cy; int cxi, cyi; double pdx, pdy; double C20, C02, C30, C03; double csum1, csum2; double C21, C31, C12, C13, C11; double u, u2, u3; double v, v2, v3; foreach (var p in particles) { cx = Convert.ToInt32(p.x); cy = Convert.ToInt32(p.y); cxi = cx 1; cyi = cy 1; n01 = grid[cx][cy]; n02 = grid[cx][cyi]; n11 = grid[cxi][cy]; n12 = grid[cxi][cyi]; pdx = n11.d - n01.d; pdy = n02.d - n01.d; C20 = 3.0 * pdx - n11.gx - 2.0 * n01.gx; C02 = 3.0 * pdy - n02.gy - 2.0 * n01.gy; C30 = -2.0 * pdx n11.gx n01.gx; C03 = -2.0 * pdy n02.gy n01.gy; csum1 = n01.d n01.gy C02 C03; csum2 = n01.d n01.gx C20 C30; C21 = 3.0 * n12.d - 2.0 * n02.gx - n12.gx - 3.0 * csum1 - C20; C31 = -2.0 * n12.d n02.gx n12.gx 2.0 * csum1 - C30; C12 = 3.0 * n12.d - 2.0 * n11.gy - n12.gy - 3.0 * csum2 - C02; C13 = -2.0 * n12.d n11.gy n12.gy 2.0 * csum2 - C03; C11 = n02.gx - C13 - C12 - n01.gx; u = p.x - cx; u2 = u * u; u3 = u * u2; v = p.y - cy; v2 = v * v; v3 = v * v2; density = n01.d n01.gx * u n01.gy * v C20 * u2 C02 * v2 C30 * u3 C03 * v3 C21 * u2 * v C31 * u3 * v C12 * u * v2 C13 * u * v3 C11 * u * v; pressure = density - 1.0; if (pressure > 2.0) pressure = 2.0; fx = 0.0; fy = 0.0; if (p.x < 4.0) fx = p.mat.m * (4.0 - p.x); else if (p.x > gsizeX - 5) fx = p.mat.m * (gsizeX - 5 - p.x); if (p.y < 4.0) fy = p.mat.m * (4.0 - p.y); else if (p.y > gsizeY - 5) fy = p.mat.m * (gsizeY - 5 - p.y); if (drag) { double vx = Math.Abs(p.x - 0.25 * mx); double vy = Math.Abs(p.y - 0.25 * my); if ((vx < 10.0) && (vy < 10.0)) { weight = p.mat.m * (1.0 - vx * 0.10) * (1.0 - vy * 0.10); fx = weight * (mdx - p.u); fy = weight * (mdy - p.v); } } for (i = 0; i < 3; i ) { for (j = 0; j < 3; j ) { var n = grid[(p.cx i)][(p.cy j)]; phi = p.px[i] * p.py[j]; n.ax = -((p.gx[i] * p.py[j]) * pressure) fx * phi; n.ay = -((p.px[i] * p.gy[j]) * pressure) fy * phi; } } } foreach (var n in active) { if (n.m > 0.0) { n.ax /= n.m; n.ay /= n.m; n.ay = 0.03; } } double mu, mv; foreach (var p in particles) { for (i = 0; i < 3; i ) { for (j = 0; j < 3; j ) { var n = grid[(p.cx i)][(p.cy j)]; phi = p.px[i] * p.py[j]; p.u = phi * n.ax; p.v = phi * n.ay; } } mu = p.mat.m * p.u; mv = p.mat.m * p.v; for (i = 0; i < 3; i ) { for (j = 0; j < 3; j ) { var n = grid[(p.cx i)][(p.cy j)]; phi = p.px[i] * p.py[j]; n.u = phi * mu; n.v = phi * mv; } } } foreach (var n in active) { if (n.m > 0.0) { n.u /= n.m; n.v /= n.m; } } double gu, gv; foreach (var p in particles) { gu = 0.0; gv = 0.0; for (i = 0; i < 3; i ) { for (j = 0; j < 3; j ) { var n = grid[(p.cx i)][(p.cy j)]; phi = p.px[i] * p.py[j]; gu = phi * n.u; gv = phi * n.v; } } p.x = gu; p.y = gv; p.u = 1.0 * (gu - p.u); p.v = 1.0 * (gv - p.v); if (p.x < 1.0) { p.x = (1.0 rnd.NextDouble() * 0.01); p.u = 0.0; } else if (p.x > gsizeX - 2) { p.x = (gsizeX - 2 - rnd.NextDouble() * 0.01); p.u = 0.0; } if (p.y < 1.0) { p.y = (1.0 rnd.NextDouble() * 0.01); p.v = 0.0; } else if (p.y > gsizeY - 2) { p.y = (gsizeY - 2 - rnd.NextDouble() * 0.01); p.v = 0.0; } } } } }