Is it possible to get v8 to internally inline a function? - javascript

I'm wondering if there is any way to get v8 to internally inline a function to speed up overall execution.
I have a simple function that returns the total energy of a pixel:
function pxEnergy(x, y) {
var tmp = (y * cols + x - 1) * 4
return (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3];
}
I'm calling this ~96,000,000 times and my code takes ~2 sec to run.
If I inline the function 8 times in my loops, e.g.:
xSum += -2 * (tmp = (y * cols + x - 1) * 4, (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3]);
The same code now takes ~500ms to run. But it's ugly as sin :)
So I'm wondering if anyone has any magic tricks up their sleeves to get the same speedup without manually inlining the function.
[edit] full code per request:
generateEnergyMap() {
// woo-hoo, nothing to do!
if (!this.dirty) { return Promise.resolve(); }
var energyMap = this.energyMap = [];
var cols = this.width;
var rows = this.height;
var data = this.data;
var pxEnergy = new Function('data', 'cols', 'x', 'y', 'var ix = (y * cols + x) * 4; return (data[ix] + data[ix + 1] + data[ix + 2]) * data[ix + 3]');
return this.imgPromise.then(function() {
for (var y = 0; y < rows; y++) {
energyMap.push([]);
for (var x = 0; x < cols; x++) {
var up = y;
var down = y < (rows - 1);
var left = x;
var right = x < (cols - 1);
var tmp;
var xSum = 0;
var ySum = 0;
if (left) {
xSum += -2 * pxEnergy(data, cols, x - 1, y); // (tmp = (y * cols + x - 1) * 4, (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3]);
if (up) {
xSum += tmp = -1 * pxEnergy(data, cols, x - 1, y - 1); // (tmp = ((y - 1) * cols + x - 1) * 4, (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3]);
ySum += tmp;
}
if (down) {
xSum += -1 * (tmp = pxEnergy(data, cols, x - 1, y + 1)); // (tmp = (tmp = ((y + 1) * cols + x - 1) * 4, (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3]));
ySum += tmp;
}
}
if (right) {
xSum += 2 * pxEnergy(data, cols, x + 1, y); // (tmp = (y * cols + x + 1) * 4, (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3]);
if (up) {
xSum += tmp = pxEnergy(data, cols, x + 1, y - 1); // (tmp = ((y - 1) * cols + x + 1) * 4, (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3]);
ySum += -1 * tmp;
}
if (down) {
xSum += tmp = pxEnergy(data, cols, x + 1, y + 1); // (tmp = ((y + 1) * cols + x + 1) * 4, (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3]);
ySum += tmp;
}
}
if (up) {
ySum += -2 * pxEnergy(data, cols, x, y - 1); // (tmp = ((y - 1) * cols + x) * 4, (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3]);
}
if (down) {
ySum += 2 * pxEnergy(data, cols, x, y + 1); // (tmp = ((y + 1) * cols + x) * 4, (data[tmp] + data[tmp + 1] + data[tmp + 2]) * data[tmp + 3]);
}
energyMap[y].push(Math.sqrt(xSum * xSum + ySum * ySum));
}
}
});
}

Related

How to make this cube a Sphere in P5.js?

I've been developing a procedural cube, which is built in three steps.
Setting up the vectors
Drawing the triangles needed
Normalizing to convert to sphere
My problem regards to the last step, when I normalize the vectors it only shows a quarter of a sphere. Could anyone help me out with this?
let world;
function setup() {
createCanvas(500, 500, WEBGL);
world = new cube(9, 80); // Testing values
}
function draw() {
background(200);
world.createVertices();
//world.drawPoints();
world.createTriangles();
world.drawTriangles();
}
class cube {
constructor(resolution,scale,vertices, triangles, roundness, normals) {
this.resolution = resolution;
this.vertices = vertices;
this.scale = scale;
this.triangles = triangles;
this.normals = normals;
}
createVertices() {
let cornerVertices = 8;
let edgeVertices = ((this.resolution * 3) - 3) * 4;
let faceVertices = ((this.resolution - 1) * (this.resolution - 1) +(this.resolution - 1) * (this.resolution - 1) +(this.resolution- 1) * (this.resolution - 1)) * 2;
let totalVertices = cornerVertices + edgeVertices + faceVertices // For checking purposes only
this.vertices = []
this.normals = []
let v = 0;
for (let y = 0; y <= this.resolution; y++) {
for (let x = 0; x <= this.resolution; x++) {
this.SetVertex(v++, x, y, 0);
}
for (let z = 1; z <= this.resolution; z++) {
this.SetVertex(v++, this.resolution, y, z);
}
for (let x = this.resolution - 1; x >= 0; x--) {
this.SetVertex(v++, x, y, this.resolution)
}
for (let z = this.resolution - 1; z > 0; z--) {
this.SetVertex(v++, 0, y, z);
}
}
for (let z = 1; z < this.resolution; z++) {
for (let x = 1; x < this.resolution; x++) {
this.SetVertex(v++, x, this.resolution, z);
}
}
for (let z = 1; z < this.resolution; z++) {
for (let x = 1; x < this.resolution; x++) {
this.SetVertex(v++, x, 0, z);
}
}
console.log(this.vertices)
console.log(totalVertices)
}
createTriangles() {
let quads = (this.resolution * this.resolution + this.resolution * this.resolution + this.resolution * this.resolution) * 2; // For checking purposes only
this.triangles = [];
let ring = (this.resolution * 2) * 2;
let t = 0
let v = 0;
for (let y = 0; y < this.resolution; y++, v++) {
for (let q = 0; q < ring - 1; q++, v++) {
t = this.SetQuad(this.triangles, t, v, v + 1, v + ring, v + ring + 1);
}
t = this.SetQuad(this.triangles, t, v, v - ring + 1, v + ring, v + 1);
}
t = this.CreateTopFace(this.triangles, t, ring);
t = this.CreateBottomFace(t, ring);
console.log(this.triangles)
}
drawPoints() {
strokeWeight(1);
let angleX = 200
let angleY = 500
let angleZ = 100
beginShape(POINTS);
for(let i = 0; i < this.vertices.length; i++) {
vertex(this.vertices[i].x * this.scale,this.vertices[i].y * -this.scale,this.vertices[i].z * this.scale)
rotateX(angleX)
rotateY(angleY)
rotateZ(angleZ)
}
endShape();
}
drawTriangles(){
let coordinates = [];
for(let i = 0; i < this.triangles.length; i++){
coordinates.push(this.vertices[this.triangles[i]])
}
console.log(coordinates)
for(let i = 0; i < coordinates.length; i = i + 3) {
beginShape(TRIANGLES);
vertex(coordinates[i].x * this.scale,coordinates[i].y * -this.scale,coordinates[i].z * this.scale)
vertex(coordinates[i + 1].x * this.scale,coordinates[i + 1].y * -this.scale,coordinates[i + 1].z * this.scale)
vertex(coordinates[i + 2].x * this.scale,coordinates[i + 2].y * -this.scale,coordinates[i + 2].z * this.scale)
endShape();
}
}
// Define vertex order.
SetQuad (triangles, i, v00, v10, v01, v11) {
triangles[i] = v00;
triangles[i + 1] = triangles[i + 4] = v01;
triangles[i + 2] = triangles[i + 3] = v10;
triangles[i + 5] = v11;
return i + 6;
}
CreateTopFace(triangles,t, ring) {
let v = ring * this.resolution;
for (let x = 0; x < this.resolution - 1; x++, v++) {
t = this.SetQuad(triangles, t, v, v + 1, v + ring - 1, v + ring);
}
t = this.SetQuad(triangles, t, v, v + 1, v + ring - 1, v + 2);
let vMin = ring * (this.resolution + 1) - 1;
let vMid = vMin + 1;
let vMax = v + 2;
for (let z = 1; z < this.resolution - 1; z++, vMin--, vMid++, vMax++) {
t = this.SetQuad(triangles, t, vMin, vMid, vMin - 1, vMid + this.resolution- 1);
for (let x = 1; x < this.resolution - 1; x++, vMid++) {
t = this.SetQuad(triangles, t, vMid, vMid + 1, vMid + this.resolution - 1, vMid + this.resolution);
}
t = this.SetQuad(triangles, t, vMid, vMax, vMid + this.resolution - 1, vMax + 1);
}
let vTop = vMin - 2;
t = this.SetQuad(triangles, t, vMin, vMid, vTop + 1, vTop);
for (let x = 1; x < this.resolution - 1; x++, vTop--, vMid++) {
t = this.SetQuad(triangles, t, vMid, vMid + 1, vTop, vTop - 1);
}
t = this.SetQuad(triangles, t, vMid, vTop - 2, vTop, vTop - 1);
return t;
}
CreateBottomFace (triangles, t, ring) {
let v = 1;
let vMid = this.vertices.length - (this.resolution - 1) * (this.resolution - 1);
t = this.SetQuad(triangles, t, ring - 1, vMid, 0, 1);
for (let x = 1; x < this.resolution - 1; x++, v++, vMid++) {
t = this.SetQuad(triangles, t, vMid, vMid + 1, v, v + 1);
}
t = this.SetQuad(triangles, t, vMid, v + 2, v, v + 1);
let vMin = ring - 2;
vMid -= this.resolution - 2;
let vMax = v + 2;
for (let z = 1; z < this.resolution - 1; z++, vMin--, vMid++, vMax++) {
t = this.SetQuad(triangles, t, vMin, vMid + this.resolution - 1, vMin + 1, vMid);
for (let x = 1; x < this.resolution - 1; x++, vMid++) {
t = this.SetQuad(triangles, t,vMid + this.resolution - 1, vMid + this.resolution, vMid, vMid + 1);
}
t = this.SetQuad(triangles, t, vMid + this.resolution - 1, vMax + 1, vMid, vMax);
}
let vTop = vMin - 1;
t = this.SetQuad(triangles, t, vTop + 1, vTop, vTop + 2, vMid);
for (let x = 1; x < this.resolution - 1; x++, vTop--, vMid++) {
t = this.SetQuad(triangles, t, vTop, vTop - 1, vMid, vMid + 1);
}
t = this.SetQuad(triangles, t, vTop, vTop - 1, vMid, vTop - 2);
return t;
}
SetVertex (i, x, y, z) {
let v = createVector(x, y, z)
v = v.mult(2)
v = v.div(this.resolution - 1)
this.normals[i] = v.normalize();
this.vertices[i] = this.normals[i];
}
}

Draw oval using Leafletjs Draw Library

I am trying to draw oval and Circle using Leafletjs Draw library, it works fine but the problem is the Circle boundary doesn't touch with the Mouse pointer on mousemove. here is the code and fiddle.
try to draw the oval you will observe the mouse pointer is not touching the circle boundary
https://jsfiddle.net/Lscupxqp/12/
var points = [L.GeoJSON.latLngToCoords(this._startLatLng),L.GeoJSON.latLngToCoords(latlng)];
var x = Math.abs(points[1][0] - points[0][0]);
var y = Math.abs(points[1][1] - points[0][1]);
var x_percent, y_percent;
x_percent = y_percent = 1;
//show in %
if(x < y) {
x_percent = x / y;
}
else {
y_percent = y / x;
}
this._drawShape(latlng);
this._shape.rx = x_percent;
this._shape.ry = y_percent;
GetPathString method
getPathString: function () {
var p = this._point,
r = this._radius;
if (this._checkIfEmpty()) {
return '';
}
//console.log(this);
if (L.Browser.svg) {
var rr = 'M' + p.x + ',' + (p.y - r) + 'A' + (r * this.rx) + ',' + (r * this.ry) + ',0,1,1,' + (p.x - 0.1) + ',' + (p.y - r) + ' z';
return rr;
} else {
p._round();
r = Math.round(r);
return 'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r + ' 0,' + (65535 * 360);
}
}
It seems I've got your mistake - change (p.y - r) to (p.y - r * this.ry) :
if (L.Browser.svg) {
var rr = 'M' + p.x + ',' + (p.y - r * this.ry) +
'A' + (r * this.rx) + ',' + (r * this.ry) + ',0,0,0,' + p.x + ',' + (p.y + r * this.ry) +
'A' + (r * this.rx) + ',' + (r * this.ry) + ',0,1,0,' + (p.x) + ',' + (p.y - r * this.ry) +' z';

How do I make image face mouse in javascript?

I'm trying to use javascript to make an image face the mouse of the user, I'm close but my calculations are a bit off (the rotation on the x-axis seems to be inverted). I based my code of this link: rotate3d shorthand
javascript:
$(document).mousemove(function(e){
pageheight = $(document).height();
pagewidth = $(document).width();
widthpercentage = e.pageX / pagewidth;
heightpercentage = e.pageY / pageheight;
specialW = (widthpercentage * 180 - 90);
specialH = (heightpercentage * 180 - 90);
function toRadians(degrees) {
radians = degrees * (Math.PI /180);
return radians;
}
function matrix(x, y, z, rads) {
var sc = Math.sin(rads / 2) * Math.cos(rads / 2);
var sq = Math.pow(Math.sin(rads / 2), 2);
var array = [];
var a1 = 1 - 2 * (Math.pow(y, 2) + Math.pow(z, 2)) * sq,
a2 = 2 * (x * y * sq - z * sc),
a3 = 2 * (x * z * sq + y * sc),
a4 = 0,
b1 = 2 * (x * y * sq + z * sc),
b2 = 1 - 2 * (Math.pow(x, 2) + Math.pow(z, 2)) * sq,
b3 = 2 * (y * z * sq - x * sc),
b4 = 0,
c1 = 2 * (x * z * sq - y * sc),
c2 = 2 * (y * z * sq + x * sc),
c3 = 1 - 2 * (Math.pow(x, 2) + Math.pow(y, 2)) * sq,
c4 = 0,
d1 = 0,
d2 = 0,
d3 = 0,
d4 = 1;
array.push(a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4);
return array;
}
xmatrix = matrix(1, 0, 0, toRadians(specialH));
ymatrix = matrix(0, 1, 0, toRadians(specialW));
function multiply(xarray, yarray) {
var newarray = [];
var a1 = (xarray[0] * yarray[0]) + (xarray[4] * yarray[1]) + (xarray[8] * yarray[2]) + (xarray[12] * yarray[3]),
a2 = (xarray[0] * yarray[4]) + (xarray[4] * yarray[5]) + (xarray[8] * yarray[6]) + (xarray[12] * yarray[7]),
a3 = (xarray[0] * yarray[8]) + (xarray[4] * yarray[9]) + (xarray[8] * yarray[10]) + (xarray[12] * yarray[11]),
a4 = (xarray[0] * yarray[12]) + (xarray[4] * yarray[13]) + (xarray[8] * yarray[14]) + (xarray[12] * yarray[15]),
b1 = (xarray[1] * yarray[0]) + (xarray[5] * yarray[1]) + (xarray[9] * yarray[2]) + (xarray[13] * yarray[3]),
b2 = (xarray[1] * yarray[4]) + (xarray[5] * yarray[5]) + (xarray[9] * yarray[6]) + (xarray[13] * yarray[7]),
b3 = (xarray[1] * yarray[8]) + (xarray[5] * yarray[9]) + (xarray[9] * yarray[10]) + (xarray[13] * yarray[11]),
b4 = (xarray[1] * yarray[12]) + (xarray[5] * yarray[13]) + (xarray[9] * yarray[14]) + (xarray[13] * yarray[15]),
c1 = (xarray[2] * yarray[0]) + (xarray[6] * yarray[1]) + (xarray[10] * yarray[2]) + (xarray[14] * yarray[3]),
c2 = (xarray[2] * yarray[4]) + (xarray[6] * yarray[5]) + (xarray[10] * yarray[6]) + (xarray[14] * yarray[7]),
c3 = (xarray[2] * yarray[8]) + (xarray[6] * yarray[9]) + (xarray[10] * yarray[10]) + (xarray[14] * yarray[11]),
c4 = (xarray[2] * yarray[12]) + (xarray[6] * yarray[13]) + (xarray[10] * yarray[14]) + (xarray[14] * yarray[15]),
d1 = (xarray[3] * yarray[0]) + (xarray[7] * yarray[1]) + (xarray[11] * yarray[2]) + (xarray[15] * yarray[3]),
d2 = (xarray[3] * yarray[4]) + (xarray[7] * yarray[5]) + (xarray[11] * yarray[6]) + (xarray[15] * yarray[7]),
d3 = (xarray[3] * yarray[8]) + (xarray[7] * yarray[9]) + (xarray[11] * yarray[10]) + (xarray[15] * yarray[11]),
d4 = (xarray[3] * yarray[12]) + (xarray[7] * yarray[13]) + (xarray[11] * yarray[14]) + (xarray[15] * yarray[15]);
newarray.push(a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4);
return newarray;
}
var newmatrix = multiply(xmatrix, ymatrix);
$('#page1 img').css('transform', 'matrix3d(' + newmatrix[0] + ',' + newmatrix[1] + ',' + newmatrix[2] + ',' + newmatrix[3] + ',' + newmatrix[4] + ',' + newmatrix[5] + ',' + newmatrix[6] + ',' + newmatrix[7] + ',' + newmatrix[8] + ',' + newmatrix[9] + ',' + newmatrix[10] + ',' + newmatrix[11] + ',' + newmatrix[12] + ',' + newmatrix[13] + ',' + newmatrix[14] + ',' + newmatrix[15] + ')');
});
I know it's a lot of code, but if I could get a second a opinion, It would be greatly appreciated. Thanks
No plugins please.
I actually just edited the matrix() function and added this right before array.push:
if ( y = 1 ) {
a3 = a3 * -1;
c1 = c1 * -1;
}
And this fixed the issue.

Pixel by pixel collision detection pinball

I'm currently working on a Pinball game using the HTML5 Canvas and JavaScript. Right now I'm getting a hard time with the pixel by pixel collision, which is fundamental because of the flippers.
Right now my Bounding Box Collision seems to be working
checkCollision(element) {
if (this.checkCollisionBoundingBox(element)) {
console.log("colision with the element bounding box");
if (this.checkCollisionPixelByPixel(element)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
checkCollisionBoundingBox(element) {
if (this.pos.x < element.pos.x + element.width && this.pos.x + this.width > element.pos.x && this.pos.y < element.pos.y + element.height && this.pos.y + this.height > element.pos.y) {
return true;
} else {
return false;
}
}
I've tried several ways of implementing the pixel by pixel one but for some reason it does not work perfectly (on walls, on images, on sprites etc). I'll leave them here:
checkCollisionPixelByPixel(element) {
var x_left = Math.floor(Math.max(this.pos.x, element.pos.x));
var x_right = Math.floor(Math.min(this.pos.x + this.width, element.pos.x + element.width));
var y_top = Math.floor(Math.max(this.pos.y, element.pos.y));
var y_bottom = Math.floor(Math.min(this.pos.y + this.height, element.pos.y + element.height));
for (var y = y_top; y < y_bottom; y++) {
for (var x = x_left; x < x_right; x++) {
var x_0 = Math.round(x - this.pos.x);
var y_0 = Math.round(y - this.pos.y);
var n_pix = y_0 * (this.width * this.total) + (this.width * (this.actual-1)) + x_0; //n pixel to check
var pix_op = this.imgData.data[4 * n_pix + 3]; //opacity (R G B A)
var element_x_0 = Math.round(x - element.pos.x);
var element_y_0 = Math.round(y - element.pos.y);
var element_n_pix = element_y_0 * (element.width * element.total) + (element.width * (element.actual-1)) + element_x_0; //n pixel to check
var element_pix_op = element.imgData.data[4 * element_n_pix + 3]; //opacity (R G B A)
console.log(element_pix_op);
if (pix_op == 255 && element_pix_op == 255) {
console.log("Colision pixel by pixel");
/*Debug*/
/*console.log("This -> (R:" + this.imgData.data[4 * n_pix] + ", G:" + this.imgData.data[4 * n_pix + 1] + ", B:" + this.imgData.data[4 * n_pix + 2] + ", A:" + pix_op + ")");
console.log("Element -> (R:" + element.imgData.data[4 * element_n_pix] + ", G:" + element.imgData.data[4 * element_n_pix + 1] + ", B:" + element.imgData.data[4 * element_n_pix + 2] + ", A:" + element_pix_op + ")");
console.log("Collision -> (x:" + x + ", y:" + y +")");
console.log("This(Local) -> (x:" + x_0 + ", y:" + y_0+")");
console.log("Element(Local) -> (x:" + element_x_0 + ", y:" + element_y_0+")");*/
/*ball vector*/
var vector = {
x: (x_0 - Math.floor(this.imgData.width / 2)),
y: -(y_0 - Math.floor(this.imgData.height / 2))
};
//console.log("ball vector -> ("+vector.x+", "+vector.y+") , Angulo: "+ Math.atan(vector.y/vector.x)* 180/Math.PI);
// THIS WAS THE FIRST TRY, IT DIDN'T WORK WHEN THE BALL WAS GOING NORTHEAST AND COLLIDED WITH A WALL. DIDN'T WORK AT ALL WITH SPRITES
//this.angle = (Math.atan2(vector.y, vector.x) - Math.PI) * (180 / Math.PI);
// THIS WAS THE SECOND ATTEMPT, WORKS WORSE THAN THE FIRST ONE :/
//normal vector
var normal = {
x: (x_0 - (this.imgData.width / 2)),
y: -(y_0 - (this.imgData.height / 2))
};
//Normalizar o vetor
var norm = Math.sqrt(normal.x * normal.x + normal.y * normal.y);
if (norm != 0) {
normal.x = normal.x / norm;
normal.y = normal.y / norm;
}
var n_rad = Math.atan2(normal.y, normal.x);
var n_deg = (n_rad + Math.PI) * 180 / Math.PI;
console.log("Vetor Normal -> (" + normal.x + ", " + normal.y + ") , Angulo: " + n_deg);
//Vetor Velocidade
var velocity = {
x: Math.cos((this.angle * Math.PI / 180) - Math.PI),
y: Math.sin((this.angle * Math.PI / 180) - Math.PI)
};
console.log("Vetor Velocidade -> (" + velocity.x + ", " + velocity.y + ") , Angulo: " + this.angle);
//Vetor Reflexao
var ndotv = normal.x * velocity.x + normal.y * velocity.y;
var reflection = {
x: -2 * ndotv * normal.x + velocity.x,
y: -2 * ndotv * normal.y + velocity.y
};
var r_rad = Math.atan2(reflection.y, reflection.x);
var r_deg = (r_rad + Math.PI) * 180 / Math.PI;
console.log("Vetor Reflexao -> (" + reflection.x + ", " + reflection.y + ") , Angulo: " + r_deg);
this.angle = r_deg;
return true;
}
}
}
return false;
}
}
The ball class
class Ball extends Element {
constructor(img, pos, width, height, n, sound, angle, speed) {
super(img, pos, width, height, n, sound);
this.angle = angle; //direction [0:360[
this.speed = speed;
}
move(ctx, cw, ch) {
var rads = this.angle * Math.PI / 180
var vx = Math.cos(rads) * this.speed / 60;
var vy = Math.sin(rads) * this.speed / 60;
this.pos.x += vx;
this.pos.y -= vy;
ctx.clearRect(0, 0, cw, ch);
this.draw(ctx, 1);
}
}
Assuming a "flipper" is composed of 2 arcs and 2 lines it would be much faster to do collision detection mathematically rather than by the much slower pixel-test method. Then you just need 4 math collision tests.
Even if your flippers are a bit more complicated than arcs+lines, the math hit tests would be "good enough" -- meaning in your fast-moving game, the user cannot visually notice the approximate math results vs the pixel-perfect results and the difference between the 2 types of tests will not affect gameplay at all. But the pixel-test version will take magnitudes more time and resources to accomplish. ;-)
First two circle-vs-circle collision tests:
function CirclesColliding(c1,c2){
var dx=c2.x-c1.x;
var dy=c2.y-c1.y;
var rSum=c1.r+c2.r;
return(dx*dx+dy*dy<=rSum*rSum);
}
Then two circle-vs-line-segment collision tests:
// [x0,y0] to [x1,y1] define a line segment
// [cx,cy] is circle centerpoint, cr is circle radius
function isCircleSegmentColliding(x0,y0,x1,y1,cx,cy,cr){
// calc delta distance: source point to line start
var dx=cx-x0;
var dy=cy-y0;
// calc delta distance: line start to end
var dxx=x1-x0;
var dyy=y1-y0;
// Calc position on line normalized between 0.00 & 1.00
// == dot product divided by delta line distances squared
var t=(dx*dxx+dy*dyy)/(dxx*dxx+dyy*dyy);
// calc nearest pt on line
var x=x0+dxx*t;
var y=y0+dyy*t;
// clamp results to being on the segment
if(t<0){x=x0;y=y0;}
if(t>1){x=x1;y=y1;}
return( (cx-x)*(cx-x)+(cy-y)*(cy-y) < cr*cr );
}

3-D semi-circle with canvas

I have a library of shapes with indicies and vertices that are functions and want to create a 3-D semi-sphere. But I am Having trouble with this. See below of sample 3-D sphere function. How can I create a 3-D semi-sphere function the same way? Please help!
sphere: function (spherical) {
var radius = 0.5,
theta = Math.PI,
phi = 2 * Math.PI,
latLines = 30,
longLines = 30,
currentLat,
currentLong,
currentVertex,
currentIndex,
vertices = [],
indices = [],
finalResult = {},
i,
j,
t,
m;
for (i = 0; i < (latLines + 1); i += 1) {
currentLat = i * theta / latLines;
for (j = 0; j < (longLines + 1); j += 1) {
currentVertex = latLines * i + j;
vertices[currentVertex] = [];
currentLong = j * phi / longLines;
vertices[currentVertex][0] = radius * Math.sin(currentLat) * Math.cos(currentLong);
vertices[currentVertex][1] = radius * Math.cos(currentLat);
vertices[currentVertex][2] = radius * Math.sin(currentLat) * Math.sin(currentLong);
if (spherical) {
vertices[currentVertex][0] *= (currentLat * spherical);
vertices[currentVertex][2] *= (currentLat * spherical);
}
}
}
for (t = 0; t < (latLines + 1); t += 1) {
for (m = 0; m < (longLines + 1); m += 1) {
currentIndex = 2 * ((latLines + 1) * t + m);
indices[2 * ((latLines + 1) * t + m)] = [];
indices[2 * ((latLines + 1) * t + m) + 1] = [];
indices[currentIndex][0] = longLines * t + m;
indices[currentIndex][1] = longLines * t + m + 1;
indices[currentIndex][2] = longLines * (t + 1) + m;
currentIndex += 1;
indices[currentIndex][0] = longLines * (t + 1) + m;
indices[currentIndex][1] = longLines * (t + 1) + m + 1;
indices[currentIndex][2] = longLines * t + m + 1;
}
}
finalResult.vertices = vertices;
finalResult.indices = indices;
return finalResult;
},

Categories