top of page
Search
cedarcantab

Studying Box2D-Lite in Javascript, Part 10.4: Submerged area of polygon

Updated: Mar 1




/**

* @export

* @return {number}

* @param {box2d.b2Vec2} normal

* @param {number} offset

* @param {box2d.b2Transform} xf

* @param {box2d.b2Vec2} c

*/

box2d.b2PolygonShape.prototype.ComputeSubmergedArea = function(normal, offset, xf, c) {

// Transform plane into shape co-ordinates

var normalL = box2d.b2MulT_R_V2(xf.q, normal, box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_normalL);

var offsetL = offset - box2d.b2Dot_V2_V2(normal, xf.p);

var depths = box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_depths;

var diveCount = 0;

var intoIndex = -1;

var outoIndex = -1;

var lastSubmerged = false;

for (var i = 0, ict = this.m_count; i < ict; ++i) {

depths[i] = box2d.b2Dot_V2_V2(normalL, this.m_vertices[i]) - offsetL;

var isSubmerged = depths[i] < (-box2d.b2_epsilon);

if (i > 0) {

if (isSubmerged) {

if (!lastSubmerged) {

intoIndex = i - 1;

diveCount++;

}

} else {

if (lastSubmerged) {

outoIndex = i - 1;

diveCount++;

}

}

}

lastSubmerged = isSubmerged;

}

switch (diveCount) {

case 0:

if (lastSubmerged) {

// Completely submerged

var md = box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_md;

this.ComputeMass(md, 1);

box2d.b2Mul_X_V2(xf, md.center, c);

return md.mass;

} else {

//Completely dry

return 0;

}

break;

case 1:

if (intoIndex === (-1)) {

intoIndex = this.m_count - 1;

} else {

outoIndex = this.m_count - 1;

}

break;

}

var intoIndex2 = ((intoIndex + 1) % this.m_count);

var outoIndex2 = ((outoIndex + 1) % this.m_count);

var intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]);

var outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]);

var intoVec = box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_intoVec.Set(

this.m_vertices[intoIndex].x (1 - intoLamdda) + this.m_vertices[intoIndex2].x intoLamdda,

this.m_vertices[intoIndex].y (1 - intoLamdda) + this.m_vertices[intoIndex2].y intoLamdda);

var outoVec = box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_outoVec.Set(

this.m_vertices[outoIndex].x (1 - outoLamdda) + this.m_vertices[outoIndex2].x outoLamdda,

this.m_vertices[outoIndex].y (1 - outoLamdda) + this.m_vertices[outoIndex2].y outoLamdda);

// Initialize accumulator

var area = 0;

var center = box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_center.SetZero();

var p2 = this.m_vertices[intoIndex2];

var p3 = null;

// An awkward loop from intoIndex2+1 to outIndex2

var i = intoIndex2;

while (i !== outoIndex2) {

i = (i + 1) % this.m_count;

if (i === outoIndex2)

p3 = outoVec;

else

p3 = this.m_vertices[i];

var triangleArea = 0.5 ((p2.x - intoVec.x) (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x));

area += triangleArea;

// Area weighted centroid

center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3;

center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3;

p2 = p3;

}

//Normalize and transform centroid

center.SelfMul(1 / area);

box2d.b2Mul_X_V2(xf, center, c);

return area;

}

2 views0 comments

Recent Posts

See All

p2 naive broadphase

var Broadphase = require('../collision/Broadphase'); module.exports = NaiveBroadphase; /** * Naive broadphase implementation. Does N^2...

sopiro motor constranit

import { Matrix2, Vector2 } from "./math.js"; import { RigidBody } from "./rigidbody.js"; import { Settings } from "./settings.js";...

Comments


記事: Blog2_Post
bottom of page