基本信息
源码名称:C# 流媒体模拟例子源码
源码大小:0.02M
文件格式:.rar
开发语言:C#
更新时间:2015-09-14
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):78630559
本次赞助数额为: 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;
}
}
}
}
}