OpenGL物理泡泡

    泡泡是由于水的表面张力而形成的。这种张力是物体受到拉力作用时,存在于其内部而垂直于两相邻  肥皂泡部分接触面上的相互牵引力。
    肥皂“打破”了水的表面张力,它把表面张力降低到只有通常状况下的1/3,而这正是吹泡泡所需的最佳张力。

要点
为了达到模拟泡泡的目的,需要考虑以下两点
1. 水分子之间的张力(相邻分子间的吸引力):约束相邻分子之间的距离
2. 泡泡内部空气对所有泡泡表面水分子的作用力:使得泡泡鼓起来 
模拟思路
用一个质点模拟一个水分子,将所有水分子排列在一个圆上,将相邻的水分子用具有弹力的线连接起来模拟水分子之间的张力;
在圆的内部放N个质量较大的质点对所有的水分子产生作用力。

实现


1. 质点类

质点类模拟水分子和泡泡内部空气压力作用质点

class Point
{
public:
    float x, y;//位置
    float fx, fy;//受到的外力合
    float vx, vy;//移动速度

    float mass;//质量
    Point() {
        fx = 0;
        fy = 0;
        vx = vy = 0;
        x = y = 0;
        mass = MASS_DEFAULT;
    }
    Point(float x, float y)
    {
        fx = 0;
        fy = 0;
        vx = vy = 0;
        this->x = x;
        this->y = y;
        mass = MASS_DEFAULT;
    }
    Point(float x, float y, float mass)
    {
        fx = 0;
        fy = 0;
        this->x = x;
        this->y = y;
        vx = vy = 0;
        this->mass = mass*MASS_DEFAULT;
    }
    void Move() {
        fx = fx / mass;//外力除以质量等于加速度
        fy = fy / mass;
        vx += fx;//加速度改变速度
        vy += fy;
        x += vx;//速度改变位置
        y += vy;
        fx = fy = 0;
    }
};
2. 质点间作用力
float Power(const Point *p1, Point *p2)
{
    float x = p1->x - p2->x;//计算距离
    float y = p1->y - p2->y;

    float dist = (x*x + y*y);
    float dist2 = sqrt(dist);

    x /= dist2 * 8;
    y /= dist2 * 8;

    x *= p2->mass*p1->mass / dist;//f=(m1*m2/R^2)
    y *= p2->mass*p1->mass / dist;

    //外力作用于泡泡上的质点
    p2->fx -= x;
    p2->fy -= y;

    return dist;//返回能量值
}
3.用弹力公式模拟张力
float Spring(Point *p1, Point *p2, float best_dist)
{
    float x = p1->x - p2->x;
    float y = p1->y - p2->y;

    float dist = sqrt(x*x + y*y);
    float ch_dist = (dist - best_dist);//形变长度
    if (ch_dist <= 1e-10)
        return 0;

    x /= dist;//力的方向
    y /= dist;

    float p = ch_dist*K_FLOAT;//形变长度*弹力系数==弹力

    x = x*p;
    y = y*p;

    //弹力作用于连接的两个质点
    p1->fx -= x;
    p1->fy -= y;
    p2->fx += x;
    p2->fy += y;

    return dist;
}
4. OpenGL 绘制
void display()
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    static float r=.99, g= .99, b= .99;

    glColor4f(1, 1, 1, 0.5f);
    glLineWidth(2.5f);
    glBindTexture(GL_TEXTURE_2D, TexName);
    glBegin(GL_POLYGON);
    // 绘制多边形   
    for (int i = 0; i < POINT_SIZE; i++)
    {
        glVertex2f(points[i]->x, points[i]->y);
        glTexCoord2fv(TexCoord[i]);
    }
    glVertex2f(points[0]->x, points[0]->y);
    glEnd();

    glColor4f(r, g, b,0.5f);
    glBegin(GL_LINE_STRIP);
    // 绘制框线   
    for (int i = 0; i < POINT_SIZE; i++)
    {
        glVertex2f(points[i]->x, points[i]->y);
    }
    glVertex2f(points[0]->x, points[0]->y);
    glEnd();
    glEnd();
    glFlush();
}

效果


像大白哦

这里用了两个质点内部影响泡泡,会有形状变化的动态效果,下面是在泡泡内部贴一张图的效果,加上泡泡变化的效果非常有趣

泡泡一样的表情

你可以去下载源码看看

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值