创建半圆形刚体

今天网友【纯洁的坏蛋】提问,如何在Box2D中创建一个半圆形的刚体。回想一下,我曾经在Box2D工具类(AS3版本)LDEasyBox2D中,创建了一个静态方法,createSemiCircle(),可以简单的创建一个半圆形形状。

LDEasyBox2D类库在github仓库上的地址:
https://github.com/ladeng6666/LDEasyBox2D

刚才花了几分钟时间,把createSemiCircle()方法,转换成了Egret + p2环境下实现方案。
首先,我们来看一下详细的代码:

    private createSemiCircle(w:number,h:number): number[][] {
        var arcSimulateAnglePrecise: number = 10*Math.PI/180;
        w /= this.factor;
        h /= this.factor;

        var r:number = (h*h+w*w/4)/h/2;
        var angleSize:number = Math.acos((r-h)/r)*2;
        if(angleSize<arcSimulateAnglePrecise) throw Error("the angle of semicircle is too small");
        var verticesList:number[][] = new Array();
        var tempVertex: number[] = new Array();
        var verticesCount:number = Math.floor(Math.PI*2/arcSimulateAnglePrecise * angleSize/Math.PI/2);

        for (var i:number = 0; i < verticesCount; i++) 
        {
            tempVertex= new Array(
                    r*Math.cos(arcSimulateAnglePrecise*i + (Math.PI-angleSize)/2),
                    r*Math.sin(arcSimulateAnglePrecise*i + (Math.PI-angleSize)/2) -r+h
            );
            verticesList.push(tempVertex);
        }
        tempVertex= new Array(
            r*Math.cos(angleSize + (Math.PI-angleSize)/2),
            r*Math.sin(angleSize + (Math.PI-angleSize)/2) -r+h
        );
        verticesList.push(tempVertex);

        return verticesList;
    }

createSemiCircle()函数的用方法大概是这样的:

  1. 提供半圆形的宽w和高h
  2. 以w和h为参数,调用createSemiCircle()函数,获取半圆形的顶点数组vertices。
  3. 使用body类的fromPolygon()函数,创建对应形状的刚体。

关于fromPolygon()函数的用法,请参考教程:p2中的形状(下)

点击下载源文件并编译成功后,点击舞台任意位置,可以创建宽和高随机的半圆形,如下图所示:

半圆形

原理说明

在p2中,除了标准圆,我们无法直接绘制完美的圆弧。当需要的时候,只能通过多边形Convex形状,创建一个标准等分的多边形来模拟。例如下图中,用12等边的多边形模拟的圆形。
Alt text

这时,每个边与圆心形成的夹角,即为代码中的arcSimulateAnglePrecise变量。

那么假设现在我们要创建一个宽为w,高为h的半圆形,那么代码中其他的临时变量,如下图所示:
Alt text
然后,绘制半圆形的大致步骤如下:

  1. 当angleSize < arcSimulateAnglePrecise时,不绘制刚体形状。
  2. 按照勾股定理,我们可以列出下面的公式:
    Alt text

解方程可以得到圆形的半径r为:

    var r:number = (h*h+w*w/4)/h/2;
  1. 根据angleSize 和 arcSimulateAnglePrecise变量,计算出半圆形的顶点个数verticesCount。
  2. 循环遍历,计算每一个顶点的坐标。
  3. 将这些坐标保存在verticesList数组中。

最后,通过body类的fromPolygon()函数,和createSemiCircle()返回的顶点数组,就可以轻松的创建出半圆形状的刚体啦。

One Reply to “创建半圆形刚体”

Comments are closed.