/** * @author Richard Davey<EMAIL_ADDRESS>* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * Ninja Physics Circle constructor. * Note: This class could be massively optimised and reduced in size. I leave that challenge up to you. * * @class Phaser.Physics.Ninja.Circle * @classdesc Arcade Physics Constructor * @constructor * @param {Phaser.Physics.Ninja.Body} body - The body that owns this shape. * @param {number} x - The x coordinate to create this shape at. * @param {number} y - The y coordinate to create this shape at. * @param {number} radius - The radius of this Circle. */ Phaser.Physics.Ninja.Circle = function (body, x, y, radius) { /** * @property {Phaser.Physics.Ninja.Body} system - A reference to the body that owns this shape. */ this.body = body; /** * @property {Phaser.Physics.Ninja} system - A reference to the physics system. */ this.system = body.system; /** * @property {Phaser.Point} pos - The position of this object. */ this.pos = new Phaser.Point(x, y); /** * @property {Phaser.Point} oldpos - The position of this object in the previous update. */ this.oldpos = new Phaser.Point(x, y); /** * @property {number} radius - The radius of this circle shape. */ this.radius = radius; /** * @property {number} xw - Half the width. * @readonly */ this.xw = radius; /** * @property {number} xw - Half the height. * @readonly */ this.yw = radius; /** * @property {number} width - The width. * @readonly */ this.width = radius * 2; /** * @property {number} height - The height. * @readonly */ this.height = radius * 2; /** * @property {number} oH - Internal var. * @private */ this.oH = 0; /** * @property {number} oV - Internal var. * @private */ this.oV = 0; /** * @property {Phaser.Point} velocity - The velocity of this object. */ this.velocity = new Phaser.Point(); /** * @property {object} circleTileProjections - All of the collision response handlers. */ this.circleTileProjections = {}; this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_FULL] = this.projCircle_Full; this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_45DEG] = this.projCircle_45Deg; this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONCAVE] = this.projCircle_Concave; this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONVEX] = this.projCircle_Convex; this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGs] = this.projCircle_22DegS; this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGb] = this.projCircle_22DegB; this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGs] = this.projCircle_67DegS; this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGb] = this.projCircle_67DegB; this.circleTileProjections[Phaser.Physics.Ninja.Tile.TYPE_HALF] = this.projCircle_Half; } Phaser.Physics.Ninja.Circle.prototype.constructor = Phaser.Physics.Ninja.Circle; Phaser.Physics.Ninja.Circle.COL_NONE = 0; Phaser.Physics.Ninja.Circle.COL_AXIS = 1; Phaser.Physics.Ninja.Circle.COL_OTHER = 2; Phaser.Physics.Ninja.Circle.prototype = { /** * Updates this Circles position. * * @method Phaser.Physics.Ninja.Circle#integrate */ integrate: function () { var px = this.pos.x; var py = this.pos.y; // integrate this.pos.x += (this.body.drag * this.pos.x) - (this.body.drag * this.oldpos.x); this.pos.y += (this.body.drag * this.pos.y) - (this.body.drag * this.oldpos.y) + (this.system.gravity * this.body.gravityScale); // store this.velocity.set(this.pos.x - px, this.pos.y - py); this.oldpos.set(px, py); }, /** * Process a world collision and apply the resulting forces. * * @method Phaser.Physics.Ninja.Circle#reportCollisionVsWorld * @param {number} px - The tangent velocity * @param {number} py - The tangent velocity * @param {number} dx - Collision normal * @param {number} dy - Collision normal * @param {number} obj - Object this Circle collided with */ reportCollisionVsWorld: function (px, py, dx, dy, obj) { var p = this.pos; var o = this.oldpos; // Calc velocity var vx = p.x - o.x; var vy = p.y - o.y; // Find component of velocity parallel to collision normal var dp = (vx * dx + vy * dy); var nx = dp * dx; //project velocity onto collision normal var ny = dp * dy; //nx,ny is normal velocity var tx = vx - nx; //px,py is tangent velocity var ty = vy - ny; // We only want to apply collision response forces if the object is travelling into, and not out of, the collision var b, bx, by, fx, fy; if (dp < 0) { fx = tx * this.body.friction; fy = ty * this.body.friction; b = 1 + this.body.bounce; bx = (nx * b); by = (ny * b); if (dx === 1) { this.body.touching.left = true; } else if (dx === -1) { this.body.touching.right = true; } if (dy === 1) { this.body.touching.up = true; } else if (dy === -1) { this.body.touching.down = true; } } else { // Moving out of collision, do not apply forces bx = by = fx = fy = 0; } // Project object out of collision p.x += px; p.y += py; // Apply bounce+friction impulses which alter velocity o.x += px + bx + fx; o.y += py + by + fy; }, /** * Collides this Circle against the world bounds. * * @method Phaser.Physics.Ninja.Circle#collideWorldBounds */ collideWorldBounds: function () { var dx = this.system.bounds.x - (this.pos.x - this.radius); if (0 < dx) { this.reportCollisionVsWorld(dx, 0, 1, 0, null); } else { dx = (this.pos.x + this.radius) - this.system.bounds.width; if (0 < dx) { this.reportCollisionVsWorld(-dx, 0, -1, 0, null); } } var dy = this.system.bounds.y - (this.pos.y - this.radius); if (0 < dy) { this.reportCollisionVsWorld(0, dy, 0, 1, null); } else { dy = (this.pos.y + this.radius) - this.system.bounds.height; if (0 < dy) { this.reportCollisionVsWorld(0, -dy, 0, -1, null); } } }, /** * Collides this Circle with a Tile. * * @method Phaser.Physics.Ninja.Circle#collideCircleVsTile * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {boolean} True if they collide, otherwise false. */ collideCircleVsTile: function (tile) { var pos = this.pos; var r = this.radius; var c = tile; var tx = c.pos.x; var ty = c.pos.y; var txw = c.xw; var tyw = c.yw; var dx = pos.x - tx; // tile->obj delta var px = (txw + r) - Math.abs(dx); // penetration depth in x if (0 < px) { var dy = pos.y - ty; // tile->obj delta var py = (tyw + r) - Math.abs(dy); // pen depth in y if (0 < py) { // object may be colliding with tile // determine grid/voronoi region of circle center this.oH = 0; this.oV = 0; if (dx < -txw) { // circle is on left side of tile this.oH = -1; } else if (txw < dx) { // circle is on right side of tile this.oH = 1; } if (dy < -tyw) { // circle is on top side of tile this.oV = -1; } else if (tyw < dy) { // circle is on bottom side of tile this.oV = 1; } return this.resolveCircleTile(px, py, this.oH, this.oV, this, c); } } }, /** * Resolves tile collision. * * @method Phaser.Physics.Ninja.Circle#resolveCircleTile * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ resolveCircleTile: function (x, y, oH, oV, obj, t) { if (0 < t.id) { return this.circleTileProjections[t.type](x, y, oH, oV, obj, t); } else { // console.log("ResolveCircleTile() was called with an empty (or unknown) tile!: ID=" + t.id + ")"); return false; } }, /** * Resolves Full tile collision. * * @method Phaser.Physics.Ninja.Circle#projCircle_Full * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ projCircle_Full: function (x, y, oH, oV, obj, t) { //if we're colliding vs. the current cell, we need to project along the //smallest penetration vector. //if we're colliding vs. horiz. or vert. neighb, we simply project horiz/vert //if we're colliding diagonally, we need to collide vs. tile corner if (oH == 0) { if (oV == 0) { //collision with current cell if (x < y) { //penetration in x is smaller; project in x var dx = obj.pos.x - t.pos.x;//get sign for projection along x-axis //NOTE: should we handle the delta == 0 case?! and how? (project towards oldpos?) if (dx < 0) { obj.reportCollisionVsWorld(-x, 0, -1, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { obj.reportCollisionVsWorld(x, 0, 1, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } } else { //penetration in y is smaller; project in y var dy = obj.pos.y - t.pos.y;//get sign for projection along y-axis //NOTE: should we handle the delta == 0 case?! and how? (project towards oldpos?) if (dy < 0) { obj.reportCollisionVsWorld(0, -y, 0, -1, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { obj.reportCollisionVsWorld(0, y, 0, 1, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } } } else { //collision with vertical neighbor obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } } else if (oV == 0) { //collision with horizontal neighbor obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //diagonal collision //get diag vertex position var vx = t.pos.x + (oH * t.xw); var vy = t.pos.y + (oV * t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx * dx + dy * dy); var pen = obj.radius - len; if (0 < pen) { //vertex is in the circle; project outward if (len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } return Phaser.Physics.Ninja.Circle.COL_NONE; }, /** * Resolves 45 Degree tile collision. * * @method Phaser.Physics.Ninja.Circle#projCircle_45Deg * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ projCircle_45Deg: function (x, y, oH, oV, obj, t) { //if we're colliding diagonally: // -if obj is in the diagonal pointed to by the slope normal: we can't collide, do nothing // -else, collide vs. the appropriate vertex //if obj is in this tile: perform collision as for aabb-ve-45deg //if obj is horiz OR very neighb in direction of slope: collide only vs. slope //if obj is horiz or vert neigh against direction of slope: collide vs. face var signx = t.signx; var signy = t.signy; var lenP; if (oH == 0) { if (oV == 0) { //colliding with current tile var sx = t.sx; var sy = t.sy; var ox = (obj.pos.x - (sx * obj.radius)) - t.pos.x;//this gives is the coordinates of the innermost var oy = (obj.pos.y - (sy * obj.radius)) - t.pos.y;//point on the circle, relative to the tile center //if the dotprod of (ox,oy) and (sx,sy) is negative, the innermost point is in the slope //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) var dp = (ox * sx) + (oy * sy); if (dp < 0) { //collision; project delta onto slope and use this as the slope penetration vector sx *= -dp;//(sx,sy) is now the penetration vector sy *= -dp; //find the smallest axial projection vector if (x < y) { //penetration in x is smaller lenP = x; y = 0; //get sign for projection along x-axis if ((obj.pos.x - t.pos.x) < 0) { x *= -1; } } else { //penetration in y is smaller lenP = y; x = 0; //get sign for projection along y-axis if ((obj.pos.y - t.pos.y) < 0) { y *= -1; } } var lenN = Math.sqrt(sx * sx + sy * sy); if (lenP < lenN) { obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //colliding vertically if ((signy * oV) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //we could only be colliding vs the slope OR a vertex //look at the vector form the closest vert to the circle to decide var sx = t.sx; var sy = t.sy; var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//this gives is the coordinates of the innermost var oy = obj.pos.y - (t.pos.y + (oV * t.yw));//point on the circle, relative to the closest tile vert //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the vertex, otherwise by the normal. //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronoi region, or that of the vertex. var perp = (ox * -sy) + (oy * sx); if (0 < (perp * signx * signy)) { //collide vs. vertex var len = Math.sqrt(ox * ox + oy * oy); var pen = obj.radius - len; if (0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're //penetrating the slope. note that this method of penetration calculation doesn't hold //in general (i.e it won't work if the circle is in the slope), but works in this case //because we know the circle is in a neighboring cell var dp = (ox * sx) + (oy * sy); var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. if (0 < pen) { //collision; circle out along normal by penetration amount obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } } else if (oV == 0) { //colliding horizontally if ((signx * oH) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //we could only be colliding vs the slope OR a vertex //look at the vector form the closest vert to the circle to decide var sx = t.sx; var sy = t.sy; var ox = obj.pos.x - (t.pos.x + (oH * t.xw));//this gives is the coordinates of the innermost var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//point on the circle, relative to the closest tile vert //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the normal, otherwise by the vertex. //(NOTE: this is the opposite logic of the vertical case; // for vertical, if the perp prod and the slope's slope agree, it's outside. // for horizontal, if the perp prod and the slope's slope agree, circle is inside. // ..but this is only a property of flahs' coord system (i.e the rules might swap // in righthanded systems)) //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronio region, or that of the vertex. var perp = (ox * -sy) + (oy * sx); if ((perp * signx * signy) < 0) { //collide vs. vertex var len = Math.sqrt(ox * ox + oy * oy); var pen = obj.radius - len; if (0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're //penetrating the slope. note that this method of penetration calculation doesn't hold //in general (i.e it won't work if the circle is in the slope), but works in this case //because we know the circle is in a neighboring cell var dp = (ox * sx) + (oy * sy); var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. if (0 < pen) { //collision; circle out along normal by penetration amount obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } else { //colliding diagonally if (0 < ((signx * oH) + (signy * oV))) { //the dotprod of slope normal and cell offset is strictly positive, //therefore obj is in the diagonal neighb pointed at by the normal, and //it cannot possibly reach/touch/penetrate the slope return Phaser.Physics.Ninja.Circle.COL_NONE; } else { //collide vs. vertex //get diag vertex position var vx = t.pos.x + (oH * t.xw); var vy = t.pos.y + (oV * t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx * dx + dy * dy); var pen = obj.radius - len; if (0 < pen) { //vertex is in the circle; project outward if (len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } return Phaser.Physics.Ninja.Circle.COL_NONE; }, /** * Resolves Concave tile collision. * * @method Phaser.Physics.Ninja.Circle#projCircle_Concave * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ projCircle_Concave: function (x, y, oH, oV, obj, t) { //if we're colliding diagonally: // -if obj is in the diagonal pointed to by the slope normal: we can't collide, do nothing // -else, collide vs. the appropriate vertex //if obj is in this tile: perform collision as for aabb //if obj is horiz OR very neighb in direction of slope: collide vs vert //if obj is horiz or vert neigh against direction of slope: collide vs. face var signx = t.signx; var signy = t.signy; var lenP; if (oH == 0) { if (oV == 0) { //colliding with current tile var ox = (t.pos.x + (signx * t.xw)) - obj.pos.x;//(ox,oy) is the vector from the circle to var oy = (t.pos.y + (signy * t.yw)) - obj.pos.y;//tile-circle's center var twid = t.xw * 2; var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; //note that this should be precomputed at compile-time since it's constant var len = Math.sqrt(ox * ox + oy * oy); var pen = (len + obj.radius) - trad; if (0 < pen) { //find the smallest axial projection vector if (x < y) { //penetration in x is smaller lenP = x; y = 0; //get sign for projection along x-axis if ((obj.pos.x - t.pos.x) < 0) { x *= -1; } } else { //penetration in y is smaller lenP = y; x = 0; //get sign for projection along y-axis if ((obj.pos.y - t.pos.y) < 0) { y *= -1; } } if (lenP < pen) { obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //we can assume that len >0, because if we're here then //(len + obj.radius) > trad, and since obj.radius <= trad //len MUST be > 0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { return Phaser.Physics.Ninja.Circle.COL_NONE; } } else { //colliding vertically if ((signy * oV) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //we could only be colliding vs the vertical tip //get diag vertex position var vx = t.pos.x - (signx * t.xw); var vy = t.pos.y + (oV * t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx * dx + dy * dy); var pen = obj.radius - len; if (0 < pen) { //vertex is in the circle; project outward if (len == 0) { //project out vertically dx = 0; dy = oV; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } else if (oV == 0) { //colliding horizontally if ((signx * oH) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //we could only be colliding vs the horizontal tip //get diag vertex position var vx = t.pos.x + (oH * t.xw); var vy = t.pos.y - (signy * t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx * dx + dy * dy); var pen = obj.radius - len; if (0 < pen) { //vertex is in the circle; project outward if (len == 0) { //project out horizontally dx = oH; dy = 0; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //colliding diagonally if (0 < ((signx * oH) + (signy * oV))) { //the dotprod of slope normal and cell offset is strictly positive, //therefore obj is in the diagonal neighb pointed at by the normal, and //it cannot possibly reach/touch/penetrate the slope return Phaser.Physics.Ninja.Circle.COL_NONE; } else { //collide vs. vertex //get diag vertex position var vx = t.pos.x + (oH * t.xw); var vy = t.pos.y + (oV * t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx * dx + dy * dy); var pen = obj.radius - len; if (0 < pen) { //vertex is in the circle; project outward if (len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } return Phaser.Physics.Ninja.Circle.COL_NONE; }, /** * Resolves Convex tile collision. * * @method Phaser.Physics.Ninja.Circle#projCircle_Convex * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ projCircle_Convex: function (x, y, oH, oV, obj, t) { //if the object is horiz AND/OR vertical neighbor in the normal (signx,signy) //direction, collide vs. tile-circle only. //if we're colliding diagonally: // -else, collide vs. the appropriate vertex //if obj is in this tile: perform collision as for aabb //if obj is horiz or vert neigh against direction of slope: collide vs. face var signx = t.signx; var signy = t.signy; var lenP; if (oH == 0) { if (oV == 0) { //colliding with current tile var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center var twid = t.xw * 2; var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; //note that this should be precomputed at compile-time since it's constant var len = Math.sqrt(ox * ox + oy * oy); var pen = (trad + obj.radius) - len; if (0 < pen) { //find the smallest axial projection vector if (x < y) { //penetration in x is smaller lenP = x; y = 0; //get sign for projection along x-axis if ((obj.pos.x - t.pos.x) < 0) { x *= -1; } } else { //penetration in y is smaller lenP = y; x = 0; //get sign for projection along y-axis if ((obj.pos.y - t.pos.y) < 0) { y *= -1; } } if (lenP < pen) { obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //note: len should NEVER be == 0, because if it is, //projeciton by an axis shoudl always be shorter, and we should //never arrive here ox /= len; oy /= len; obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //colliding vertically if ((signy * oV) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(0, y * oV, 0, oV, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //obj in neighboring cell pointed at by tile normal; //we could only be colliding vs the tile-circle surface var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center var twid = t.xw * 2; var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; //note that this should be precomputed at compile-time since it's constant var len = Math.sqrt(ox * ox + oy * oy); var pen = (trad + obj.radius) - len; if (0 < pen) { //note: len should NEVER be == 0, because if it is, //obj is not in a neighboring cell! ox /= len; oy /= len; obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } else if (oV == 0) { //colliding horizontally if ((signx * oH) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //obj in neighboring cell pointed at by tile normal; //we could only be colliding vs the tile-circle surface var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center var twid = t.xw * 2; var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; //note that this should be precomputed at compile-time since it's constant var len = Math.sqrt(ox * ox + oy * oy); var pen = (trad + obj.radius) - len; if (0 < pen) { //note: len should NEVER be == 0, because if it is, //obj is not in a neighboring cell! ox /= len; oy /= len; obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //colliding diagonally if (0 < ((signx * oH) + (signy * oV))) { //obj in diag neighb cell pointed at by tile normal; //we could only be colliding vs the tile-circle surface var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the tile-circle to var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//the circle's center var twid = t.xw * 2; var trad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile; //note that this should be precomputed at compile-time since it's constant var len = Math.sqrt(ox * ox + oy * oy); var pen = (trad + obj.radius) - len; if (0 < pen) { //note: len should NEVER be == 0, because if it is, //obj is not in a neighboring cell! ox /= len; oy /= len; obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. vertex //get diag vertex position var vx = t.pos.x + (oH * t.xw); var vy = t.pos.y + (oV * t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx * dx + dy * dy); var pen = obj.radius - len; if (0 < pen) { //vertex is in the circle; project outward if (len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } return Phaser.Physics.Ninja.Circle.COL_NONE; }, /** * Resolves Half tile collision. * * @method Phaser.Physics.Ninja.Circle#projCircle_Half * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ projCircle_Half: function (x,y,oH,oV,obj,t) { //if obj is in a neighbor pointed at by the halfedge normal, //we'll never collide (i.e if the normal is (0,1) and the obj is in the DL.D, or R neighbors) // //if obj is in a neigbor perpendicular to the halfedge normal, it might //collide with the halfedge-vertex, or with the halfedge side. // //if obj is in a neigb pointing opposite the halfedge normal, obj collides with edge // //if obj is in a diagonal (pointing away from the normal), obj collides vs vertex // //if obj is in the halfedge cell, it collides as with aabb var signx = t.signx; var signy = t.signy; var celldp = (oH*signx + oV*signy);//this tells us about the configuration of cell-offset relative to tile normal if(0 < celldp) { //obj is in "far" (pointed-at-by-normal) neighbor of halffull tile, and will never hit return Phaser.Physics.Ninja.Circle.COL_NONE; } else if(oH == 0) { if(oV == 0) { //colliding with current tile var r = obj.radius; var ox = (obj.pos.x - (signx*r)) - t.pos.x;//this gives is the coordinates of the innermost var oy = (obj.pos.y - (signy*r)) - t.pos.y;//point on the circle, relative to the tile center //we perform operations analogous to the 45deg tile, except we're using //an axis-aligned slope instead of an angled one.. var sx = signx; var sy = signy; //if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) var dp = (ox*sx) + (oy*sy); if(dp < 0) { //collision; project delta onto slope and use this to displace the object sx *= -dp;//(sx,sy) is now the projection vector sy *= -dp; var lenN = Math.sqrt(sx*sx + sy*sy); var lenP = Math.sqrt(x*x + y*y); if(lenP < lenN) { obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP,t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { obj.reportCollisionVsWorld(sx,sy,t.signx,t.signy); return Phaser.Physics.Ninja.Circle.COL_OTHER; } return true; } } else { //colliding vertically if(celldp == 0) { var r = obj.radius; var dx = obj.pos.x - t.pos.x; //we're in a cell perpendicular to the normal, and can collide vs. halfedge vertex //or halfedge side if((dx*signx) < 0) { //collision with halfedge side obj.reportCollisionVsWorld(0,y*oV,0,oV,t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //collision with halfedge vertex var dy = obj.pos.y - (t.pos.y + oV*t.yw);//(dx,dy) is now the vector from the appropriate halfedge vertex to the circle var len = Math.sqrt(dx*dx + dy*dy); var pen = obj.radius - len; if(0 < pen) { //vertex is in the circle; project outward if(len == 0) { //project out by 45deg dx = signx / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //due to the first conditional (celldp >0), we know we're in the cell "opposite" the normal, and so //we can only collide with the cell edge //collision with vertical neighbor obj.reportCollisionVsWorld(0,y*oV,0,oV,t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } } } else if(oV == 0) { //colliding horizontally if(celldp == 0) { var r = obj.radius; var dy = obj.pos.y - t.pos.y; //we're in a cell perpendicular to the normal, and can collide vs. halfedge vertex //or halfedge side if((dy*signy) < 0) { //collision with halfedge side obj.reportCollisionVsWorld(x*oH,0,oH,0,t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //collision with halfedge vertex var dx = obj.pos.x - (t.pos.x + oH*t.xw);//(dx,dy) is now the vector from the appropriate halfedge vertex to the circle var len = Math.sqrt(dx*dx + dy*dy); var pen = obj.radius - len; if(0 < pen) { //vertex is in the circle; project outward if(len == 0) { //project out by 45deg dx = signx / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //due to the first conditional (celldp >0), we know w're in the cell "opposite" the normal, and so //we can only collide with the cell edge obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } } else { //colliding diagonally; we know, due to the initial (celldp >0) test which has failed //if we've reached this point, that we're in a diagonal neighbor on the non-normal side, so //we could only be colliding with the cell vertex, if at all. //get diag vertex position var vx = t.pos.x + (oH*t.xw); var vy = t.pos.y + (oV*t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx*dx + dy*dy); var pen = obj.radius - len; if(0 < pen) { //vertex is in the circle; project outward if(len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } return Phaser.Physics.Ninja.Circle.COL_NONE; }, /** * Resolves 22 Degree tile collision. * * @method Phaser.Physics.Ninja.Circle#projCircle_22DegS * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ projCircle_22DegS: function (x,y,oH,oV,obj,t) { //if the object is in a cell pointed at by signy, no collision will ever occur //otherwise, // //if we're colliding diagonally: // -collide vs. the appropriate vertex //if obj is in this tile: collide vs slope or vertex //if obj is horiz neighb in direction of slope: collide vs. slope or vertex //if obj is horiz neighb against the slope: // if(distance in y from circle to 90deg corner of tile < 1/2 tileheight, collide vs. face) // else(collide vs. corner of slope) (vert collision with a non-grid-aligned vert) //if obj is vert neighb against direction of slope: collide vs. face var signx = t.signx; var signy = t.signy; if(0 < (signy*oV)) { //object will never collide vs tile, it can't reach that far return Phaser.Physics.Ninja.Circle.COL_NONE; } else if(oH == 0) { if(oV == 0) { //colliding with current tile //we could only be colliding vs the slope OR a vertex //look at the vector form the closest vert to the circle to decide var sx = t.sx; var sy = t.sy; var r = obj.radius; var ox = obj.pos.x - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost var oy = obj.pos.y - t.pos.y;//point on the circle, relative to the tile corner //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the vertex, otherwise by the normal or axially. //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronio region, or that of the vertex. var perp = (ox*-sy) + (oy*sx); if(0 < (perp*signx*signy)) { //collide vs. vertex var len = Math.sqrt(ox*ox + oy*oy); var pen = r - len; if(0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope or vs axis ox -= r*sx;//this gives us the vector from oy -= r*sy;//a point on the slope to the innermost point on the circle //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) var dp = (ox*sx) + (oy*sy); if(dp < 0) { //collision; project delta onto slope and use this to displace the object sx *= -dp;//(sx,sy) is now the projection vector sy *= -dp; var lenN = Math.sqrt(sx*sx + sy*sy); //find the smallest axial projection vector if(x < y) { //penetration in x is smaller lenP = x; y = 0; //get sign for projection along x-axis if((obj.pos.x - t.pos.x) < 0) { x *= -1; } } else { //penetration in y is smaller lenP = y; x = 0; //get sign for projection along y-axis if((obj.pos.y - t.pos.y)< 0) { y *= -1; } } if(lenP < lenN) { obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } else { //colliding vertically; we can assume that (signy*oV) < 0 //due to the first conditional far above obj.reportCollisionVsWorld(0,y*oV, 0, oV, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } } else if(oV == 0) { //colliding horizontally if((signx*oH) < 0) { //colliding with face/edge OR with corner of wedge, depending on our position vertically //collide vs. vertex //get diag vertex position var vx = t.pos.x - (signx*t.xw); var vy = t.pos.y; var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; if((dy*signy) < 0) { //colliding vs face obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //colliding vs. vertex var len = Math.sqrt(dx*dx + dy*dy); var pen = obj.radius - len; if(0 < pen) { //vertex is in the circle; project outward if(len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //we could only be colliding vs the slope OR a vertex //look at the vector form the closest vert to the circle to decide var sx = t.sx; var sy = t.sy; var ox = obj.pos.x - (t.pos.x + (oH*t.xw));//this gives is the coordinates of the innermost var oy = obj.pos.y - (t.pos.y - (signy*t.yw));//point on the circle, relative to the closest tile vert //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the normal, otherwise by the vertex. //(NOTE: this is the opposite logic of the vertical case; // for vertical, if the perp prod and the slope's slope agree, it's outside. // for horizontal, if the perp prod and the slope's slope agree, circle is inside. // ..but this is only a property of flahs' coord system (i.e the rules might swap // in righthanded systems)) //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronio region, or that of the vertex. var perp = (ox*-sy) + (oy*sx); if((perp*signx*signy) < 0) { //collide vs. vertex var len = Math.sqrt(ox*ox + oy*oy); var pen = obj.radius - len; if(0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're //penetrating the slope. note that this method of penetration calculation doesn't hold //in general (i.e it won't work if the circle is in the slope), but works in this case //because we know the circle is in a neighboring cell var dp = (ox*sx) + (oy*sy); var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. if(0 < pen) { //collision; circle out along normal by penetration amount obj.reportCollisionVsWorld(sx*pen, sy*pen, sx, sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } else { //colliding diagonally; due to the first conditional above, //obj is vertically offset against slope, and offset in either direction horizontally //collide vs. vertex //get diag vertex position var vx = t.pos.x + (oH*t.xw); var vy = t.pos.y + (oV*t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx*dx + dy*dy); var pen = obj.radius - len; if(0 < pen) { //vertex is in the circle; project outward if(len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } return Phaser.Physics.Ninja.Circle.COL_NONE; }, /** * Resolves 22 Degree tile collision. * * @method Phaser.Physics.Ninja.Circle#projCircle_22DegB * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ projCircle_22DegB: function (x,y,oH, oV, obj,t) { //if we're colliding diagonally: // -if we're in the cell pointed at by the normal, collide vs slope, else // collide vs. the appropriate corner/vertex // //if obj is in this tile: collide as with aabb // //if obj is horiz or vertical neighbor AGAINST the slope: collide with edge // //if obj is horiz neighb in direction of slope: collide vs. slope or vertex or edge // //if obj is vert neighb in direction of slope: collide vs. slope or vertex var signx = t.signx; var signy = t.signy; if(oH == 0) { if(oV == 0) { //colliding with current cell var sx = t.sx; var sy = t.sy; var r = obj.radius; var ox = (obj.pos.x - (sx*r)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost var oy = (obj.pos.y - (sy*r)) - (t.pos.y + (signy*t.yw));//point on the AABB, relative to a point on the slope //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) var dp = (ox*sx) + (oy*sy); if(dp < 0) { //collision; project delta onto slope and use this to displace the object sx *= -dp;//(sx,sy) is now the projection vector sy *= -dp; var lenN = Math.sqrt(sx*sx + sy*sy); //find the smallest axial projection vector if(x < y) { //penetration in x is smaller lenP = x; y = 0; //get sign for projection along x-axis if((obj.pos.x - t.pos.x) < 0) { x *= -1; } } else { //penetration in y is smaller lenP = y; x = 0; //get sign for projection along y-axis if((obj.pos.y - t.pos.y)< 0) { y *= -1; } } if(lenP < lenN) { obj.reportCollisionVsWorld(x, y, x/lenP, y/lenP, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //colliding vertically if((signy*oV) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //we could only be colliding vs the slope OR a vertex //look at the vector form the closest vert to the circle to decide var sx = t.sx; var sy = t.sy; var ox = obj.pos.x - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost var oy = obj.pos.y - (t.pos.y + (signy*t.yw));//point on the circle, relative to the closest tile vert //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the vertex, otherwise by the normal. //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronio region, or that of the vertex. var perp = (ox*-sy) + (oy*sx); if(0 < (perp*signx*signy)) { //collide vs. vertex var len = Math.sqrt(ox*ox + oy*oy); var pen = obj.radius - len; if(0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're //penetrating the slope. note that this method of penetration calculation doesn't hold //in general (i.e it won't work if the circle is in the slope), but works in this case //because we know the circle is in a neighboring cell var dp = (ox*sx) + (oy*sy); var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. if(0 < pen) { //collision; circle out along normal by penetration amount obj.reportCollisionVsWorld(sx*pen, sy*pen,sx, sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } } else if(oV == 0) { //colliding horizontally if((signx*oH) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //colliding with edge, slope, or vertex var ox = obj.pos.x - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost var oy = obj.pos.y - t.pos.y;//point on the circle, relative to the closest tile vert if((oy*signy) < 0) { //we're colliding with the halfface obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //colliding with the vertex or slope var sx = t.sx; var sy = t.sy; //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the slope, otherwise by the vertex. //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronio region, or that of the vertex. var perp = (ox*-sy) + (oy*sx); if((perp*signx*signy) < 0) { //collide vs. vertex var len = Math.sqrt(ox*ox + oy*oy); var pen = obj.radius - len; if(0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're //penetrating the slope. note that this method of penetration calculation doesn't hold //in general (i.e it won't work if the circle is in the slope), but works in this case //because we know the circle is in a neighboring cell var dp = (ox*sx) + (oy*sy); var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. if(0 < pen) { //collision; circle out along normal by penetration amount obj.reportCollisionVsWorld(sx*pen, sy*pen, t.sx, t.sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } } else { //colliding diagonally if( 0 < ((signx*oH) + (signy*oV)) ) { //the dotprod of slope normal and cell offset is strictly positive, //therefore obj is in the diagonal neighb pointed at by the normal. //collide vs slope //we should really precalc this at compile time, but for now, fuck it var slen = Math.sqrt(2*2 + 1*1);//the raw slope is (-2,-1) var sx = (signx*1) / slen;//get slope _unit_ normal; var sy = (signy*2) / slen;//raw RH normal is (1,-2) var r = obj.radius; var ox = (obj.pos.x - (sx*r)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost var oy = (obj.pos.y - (sy*r)) - (t.pos.y + (signy*t.yw));//point on the circle, relative to a point on the slope //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) var dp = (ox*sx) + (oy*sy); if(dp < 0) { //collision; project delta onto slope and use this to displace the object //(sx,sy)*-dp is the projection vector obj.reportCollisionVsWorld(-sx*dp, -sy*dp, t.sx, t.sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } return Phaser.Physics.Ninja.Circle.COL_NONE; } else { //collide vs the appropriate vertex var vx = t.pos.x + (oH*t.xw); var vy = t.pos.y + (oV*t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx*dx + dy*dy); var pen = obj.radius - len; if(0 < pen) { //vertex is in the circle; project outward if(len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } return Phaser.Physics.Ninja.Circle.COL_NONE; }, /** * Resolves 67 Degree tile collision. * * @method Phaser.Physics.Ninja.Circle#projCircle_67DegS * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ projCircle_67DegS: function (x,y,oH,oV,obj,t) { //if the object is in a cell pointed at by signx, no collision will ever occur //otherwise, // //if we're colliding diagonally: // -collide vs. the appropriate vertex //if obj is in this tile: collide vs slope or vertex or axis //if obj is vert neighb in direction of slope: collide vs. slope or vertex //if obj is vert neighb against the slope: // if(distance in y from circle to 90deg corner of tile < 1/2 tileheight, collide vs. face) // else(collide vs. corner of slope) (vert collision with a non-grid-aligned vert) //if obj is horiz neighb against direction of slope: collide vs. face var signx = t.signx; var signy = t.signy; if(0 < (signx*oH)) { //object will never collide vs tile, it can't reach that far return Phaser.Physics.Ninja.Circle.COL_NONE; } else if(oH == 0) { if(oV == 0) { //colliding with current tile //we could only be colliding vs the slope OR a vertex //look at the vector form the closest vert to the circle to decide var sx = t.sx; var sy = t.sy; var r = obj.radius; var ox = obj.pos.x - t.pos.x;//this gives is the coordinates of the innermost var oy = obj.pos.y - (t.pos.y - (signy*t.yw));//point on the circle, relative to the tile corner //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the normal or axis, otherwise by the corner/vertex //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronoi region, or that of the vertex. var perp = (ox*-sy) + (oy*sx); if((perp*signx*signy) < 0) { //collide vs. vertex var len = Math.sqrt(ox*ox + oy*oy); var pen = r - len; if(0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope or vs axis ox -= r*sx;//this gives us the vector from oy -= r*sy;//a point on the slope to the innermost point on the circle //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) var dp = (ox*sx) + (oy*sy); if(dp < 0) { //collision; project delta onto slope and use this to displace the object sx *= -dp;//(sx,sy) is now the projection vector sy *= -dp; var lenN = Math.sqrt(sx*sx + sy*sy); //find the smallest axial projection vector if(x < y) { //penetration in x is smaller lenP = x; y = 0; //get sign for projection along x-axis if((obj.pos.x - t.pos.x) < 0) { x *= -1; } } else { //penetration in y is smaller lenP = y; x = 0; //get sign for projection along y-axis if((obj.pos.y - t.pos.y)< 0) { y *= -1; } } if(lenP < lenN) { obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); return Phaser.Physics.Ninja.Circle.COL_AXIS } else { obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } else { //colliding vertically if((signy*oV) < 0) { //colliding with face/edge OR with corner of wedge, depending on our position vertically //collide vs. vertex //get diag vertex position var vx = t.pos.x; var vy = t.pos.y - (signy*t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; if((dx*signx) < 0) { //colliding vs face obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //colliding vs. vertex var len = Math.sqrt(dx*dx + dy*dy); var pen = obj.radius - len; if(0 < pen) { //vertex is in the circle; project outward if(len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //we could only be colliding vs the slope OR a vertex //look at the vector form the closest vert to the circle to decide var sx = t.sx; var sy = t.sy; var ox = obj.pos.x - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost var oy = obj.pos.y - (t.pos.y + (oV*t.yw));//point on the circle, relative to the closest tile vert //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the vertex, otherwise by the normal. //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronio region, or that of the vertex. var perp = (ox*-sy) + (oy*sx); if(0 < (perp*signx*signy)) { //collide vs. vertex var len = Math.sqrt(ox*ox + oy*oy); var pen = obj.radius - len; if(0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're //penetrating the slope. note that this method of penetration calculation doesn't hold //in general (i.e it won't work if the circle is in the slope), but works in this case //because we know the circle is in a neighboring cell var dp = (ox*sx) + (oy*sy); var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. if(0 < pen) { //collision; circle out along normal by penetration amount obj.reportCollisionVsWorld(sx*pen, sy*pen, t.sx, t.sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } } else if(oV == 0) { //colliding horizontally; we can assume that (signy*oV) < 0 //due to the first conditional far above obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //colliding diagonally; due to the first conditional above, //obj is vertically offset against slope, and offset in either direction horizontally //collide vs. vertex //get diag vertex position var vx = t.pos.x + (oH*t.xw); var vy = t.pos.y + (oV*t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx*dx + dy*dy); var pen = obj.radius - len; if(0 < pen) { //vertex is in the circle; project outward if(len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } return Phaser.Physics.Ninja.Circle.COL_NONE; }, /** * Resolves 67 Degree tile collision. * * @method Phaser.Physics.Ninja.Circle#projCircle_67DegB * @param {number} x - Penetration depth on the x axis. * @param {number} y - Penetration depth on the y axis. * @param {number} oH - Grid / voronoi region. * @param {number} oV - Grid / voronoi region. * @param {Phaser.Physics.Ninja.Circle} obj - The Circle involved in the collision. * @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision. * @return {number} The result of the collision. */ projCircle_67DegB: function (x,y,oH, oV, obj,t) { //if we're colliding diagonally: // -if we're in the cell pointed at by the normal, collide vs slope, else // collide vs. the appropriate corner/vertex // //if obj is in this tile: collide as with aabb // //if obj is horiz or vertical neighbor AGAINST the slope: collide with edge // //if obj is vert neighb in direction of slope: collide vs. slope or vertex or halfedge // //if obj is horiz neighb in direction of slope: collide vs. slope or vertex var signx = t.signx; var signy = t.signy; if(oH == 0) { if(oV == 0) { //colliding with current cell var sx = t.sx; var sy = t.sy; var r = obj.radius; var ox = (obj.pos.x - (sx*r)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost var oy = (obj.pos.y - (sy*r)) - (t.pos.y - (signy*t.yw));//point on the AABB, relative to a point on the slope //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) var dp = (ox*sx) + (oy*sy); if(dp < 0) { //collision; project delta onto slope and use this to displace the object sx *= -dp;//(sx,sy) is now the projection vector sy *= -dp; var lenN = Math.sqrt(sx*sx + sy*sy); //find the smallest axial projection vector if(x < y) { //penetration in x is smaller lenP = x; y = 0; //get sign for projection along x-axis if((obj.pos.x - t.pos.x) < 0) { x *= -1; } } else { //penetration in y is smaller lenP = y; x = 0; //get sign for projection along y-axis if((obj.pos.y - t.pos.y)< 0) { y *= -1; } } if(lenP < lenN) { obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } else { //colliding vertically if((signy*oV) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //colliding with edge, slope, or vertex var ox = obj.pos.x - t.pos.x;//this gives is the coordinates of the innermost var oy = obj.pos.y - (t.pos.y + (signy*t.yw));//point on the circle, relative to the closest tile vert if((ox*signx) < 0) { //we're colliding with the halfface obj.reportCollisionVsWorld(0, y*oV, 0, oV, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //colliding with the vertex or slope var sx = t.sx; var sy = t.sy; //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the vertex, otherwise by the slope. //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronio region, or that of the vertex. var perp = (ox*-sy) + (oy*sx); if(0 < (perp*signx*signy)) { //collide vs. vertex var len = Math.sqrt(ox*ox + oy*oy); var pen = obj.radius - len; if(0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're //penetrating the slope. note that this method of penetration calculation doesn't hold //in general (i.e it won't work if the circle is in the slope), but works in this case //because we know the circle is in a neighboring cell var dp = (ox*sx) + (oy*sy); var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. if(0 < pen) { //collision; circle out along normal by penetration amount obj.reportCollisionVsWorld(sx*pen, sy*pen, sx, sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } } } else if(oV == 0) { //colliding horizontally if((signx*oH) < 0) { //colliding with face/edge obj.reportCollisionVsWorld(x*oH, 0, oH, 0, t); return Phaser.Physics.Ninja.Circle.COL_AXIS; } else { //we could only be colliding vs the slope OR a vertex //look at the vector form the closest vert to the circle to decide var slen = Math.sqrt(2*2 + 1*1);//the raw slope is (-2,-1) var sx = (signx*2) / slen;//get slope _unit_ normal; var sy = (signy*1) / slen;//raw RH normal is (1,-2) var ox = obj.pos.x - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost var oy = obj.pos.y - (t.pos.y - (signy*t.yw));//point on the circle, relative to the closest tile vert //if the component of (ox,oy) parallel to the normal's righthand normal //has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy) //then we project by the slope, otherwise by the vertex. //note that this is simply a VERY tricky/weird method of determining //if the circle is in side the slope/face's voronio region, or that of the vertex. var perp = (ox*-sy) + (oy*sx); if((perp*signx*signy) < 0) { //collide vs. vertex var len = Math.sqrt(ox*ox + oy*oy); var pen = obj.radius - len; if(0 < pen) { //note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0 ox /= len; oy /= len; obj.reportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } else { //collide vs. slope //if the component of (ox,oy) parallel to the normal is less than the circle radius, we're //penetrating the slope. note that this method of penetration calculation doesn't hold //in general (i.e it won't work if the circle is in the slope), but works in this case //because we know the circle is in a neighboring cell var dp = (ox*sx) + (oy*sy); var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case.. if(0 < pen) { //collision; circle out along normal by penetration amount obj.reportCollisionVsWorld(sx*pen, sy*pen, t.sx, t.sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } } else { //colliding diagonally if( 0 < ((signx*oH) + (signy*oV)) ) { //the dotprod of slope normal and cell offset is strictly positive, //therefore obj is in the diagonal neighb pointed at by the normal. //collide vs slope var sx = t.sx; var sy = t.sy; var r = obj.radius; var ox = (obj.pos.x - (sx*r)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost var oy = (obj.pos.y - (sy*r)) - (t.pos.y - (signy*t.yw));//point on the circle, relative to a point on the slope //if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope //and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy) var dp = (ox*sx) + (oy*sy); if(dp < 0) { //collision; project delta onto slope and use this to displace the object //(sx,sy)*-dp is the projection vector obj.reportCollisionVsWorld(-sx*dp, -sy*dp, t.sx, t.sy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } return Phaser.Physics.Ninja.Circle.COL_NONE; } else { //collide vs the appropriate vertex var vx = t.pos.x + (oH*t.xw); var vy = t.pos.y + (oV*t.yw); var dx = obj.pos.x - vx;//calc vert->circle vector var dy = obj.pos.y - vy; var len = Math.sqrt(dx*dx + dy*dy); var pen = obj.radius - len; if(0 < pen) { //vertex is in the circle; project outward if(len == 0) { //project out by 45deg dx = oH / Math.SQRT2; dy = oV / Math.SQRT2; } else { dx /= len; dy /= len; } obj.reportCollisionVsWorld(dx*pen, dy*pen, dx, dy, t); return Phaser.Physics.Ninja.Circle.COL_OTHER; } } } return Phaser.Physics.Ninja.Circle.COL_NONE; } }


Brake Values
<0;max> where 0 is disabled retarder and max is maximal value found in Truck configuration See Also: Constants.Motor.RetarderStepCount <summary> Current level of the retarder </summary> <!----> **INFORMATION** <!----> 0;max where 0 is disabled retarder and max is maximal value found in TRUCK configuration <!----> **INFORMATION** <!----> <seealso cref="Constants.Motor.RetarderStepCount" />.
Pressure in the brake air tank in psi
Temperature of the brakes in degrees celsius.
Is the parking brake enabled?
Is the motor brake enabled?


subject = "Your offer has been declined: {{ project.name }}" ==
Hi {{ user.name }},
We are sorry, but the user you chose for your project "{{ project.name }}" has declined your offer.
Click here to open the project management page.
{% if reason %} {{ reason|raw }} {% else %} A reason has not been specified. {% endif %}


Preprocessing¶
This part of the tutorial discusses ways to preprocess your original data in order to create the set of edges, and their associated weights or original deviations, needed to create an MDE problem. These preprocessing methods are analogous to feature engineering in machine learning, where raw data are converted to feature vectors. As in feature engineering, the preprocessing can have a strong effect on the final result, i.e., the embedding.
Preprocessing methods can be grouped into two types: those that
are based on neighbors of the items, and those that are based on
distances between items. The high-level functions
pymde.preserve_neighbors
and pymde.preserve_distances
(which were used in the Getting Started guide) use neighbor-based and
distance-based preprocessing behind-the-scenes, in order to create reasonable
MDE problems. But you can just as well preprocess the data yourself, to
create custom embeddings.
PyMDE provides a few preprocessing methods for original data that come as a data matrix (one row for each item) or a graph (one node for each item).
Graph¶
The preprocessing methods often work with or return pymde.Graph
instances,
which package up a list of edges and their associated weights.
A graph can be created from a weighted adjacency matrix (a scipy.sparse matrix, numpy array, or torch Tensor), or a torch Tensor containing the edges and weights. For example
adjacency_matrix = sp.csr_matrix(np.array([
[0, 1, 1],
[1, 0, 1],
[1, 1, 0],
]))
graph = pymde.Graph(adjacency_matrix)
or
edges = torch.tensor([
[0, 1],
[0, 2],
[1, 2],
])
weights = torch.ones(edges.shape[0])
graph = pymde.Graph.from_edges(edges, weights)
Given a graph, you can access the edges, weights, and adjacency matrix with
graph.edges
graph.weights
graph.adjacency_matrix
The API documentation describes the pymde.Graph
class
in more detail.
Neighbor-based preprocessing¶
Similar items¶
A neighbor of an item can be thought of an item that is in some sense
similar to it. One class of preprocessing methods computes some neighbors
of each item, and uses the pairs of neighbors as edges, associating these
edges with positive weights. These weights can then be used to create
a distortion function based on weights, using one of the classes
in pymde.penalties
. A common preprocessing step is to compute the
k
-nearest neighbors of each item, where k
is a parameter.
knn_graph = pymde.preprocess.k_nearest_neighbors(data, k=10)
Preprocessing based on neighbors can be thought of as a “sparsifying”
operation: they take data and return a sparse graph (the knn_graph
).
-
pymde.preprocess.
k_nearest_neighbors
(data, k, max_distance=None, verbose=False) Compute k-nearest neighbors, given data matrix or graph.
This function computes a k-nearest neighbor graph, given either a data matrix or an original graph.
When the input is a data matrix, each row is treated as the feature vector of an item, and the Euclidean distance is used to judge how close two items are to each other.
When the input is a graph, each node is an item, and the distance between two items is taken to be the length of the shortest-path between them.
In the returned graph, if i is a neighbor of j and j a neighbor of i, then the weight w_{ij} will be +2; if only one is a neighbor of the other, then w_{ij} will be +1; if neither are neighbors of each other, then (i, j) will not be in the graph.
- Parameters
data (torch.Tensor, np.ndarray, scipy.sparse matrix, or pymde.Graph) – A data matrix, shape
(n_items, n_features)
, or apymde.Graph
k (int) – The number of nearest neighbors per item
max_distance (float (optional)) – If not
None
, neighborhoods are restricted to have a radius no greater than max_distance.verbose (bool) – If
True
, print verbose output.
- Returns
The k-nearest neighbor graph. Access the weights with
graph.weights
, and the edges withgraph.edges
- Return type
Distance-based preprocessing¶
Another preprocessing step is to compute some distances between pairs of
items. We can use the pymde.preprocess.distances
function to compute
distances between pairs of items.
distance_graph = pymde.preprocess.distances(data)
When the original input is a graph, this function can be thought of as a “densifying” operation, since it returns a denser graph. You can control how dense the returned graph is with a keyword argument.
-
pymde.preprocess.
distances
(data, retain_fraction=1.0, verbose=False) Compute distances, given data matrix or graph.
This function computes distances between some pairs of items, given either a data matrix or a
pymde.Graph
instance.When the input is a data matrix, each row is treated as the feature vector of an item.
When the input is a graph, each node is an item, and the distance between two items is taken to be the length of the shortest-path between them.
The
retain_fraction
keyword argument can be used to compute only a fraction of the distances. This can be useful when there are many items, in which case storing all the distances may be intractable.- Parameters
data (torch.Tensor, np.ndarray, scipy.sparse matrix, or pymde.Graph) – A data matrix, shape
(n_items, n_features)
, or apymde.Graph
retain_fraction (float, optional) – A float between 0 and 1, specifying the fraction of all
(n_items choose 2)
to compute. For example, ifretain_fraction
is 0.1, only 10 percent of the edges will be stored.verbose – If
True
, print verbose output.
- Returns
A graph object holding the distances and corresponding edges. Access the distances with
graph.distances
, and the edges withgraph.edges
.- Return type


Tracking the most popular programming languages, databases and software development tools in whoishiring discussion threads.
With a Sunday posting day, the number of postings was down this month which explains the drop in the charts across the board. This month I'm also trying something new, breaking out the big list into more specific categories. I'll add more charts and categories next month as I assign categories for the terms.
Not much of a change in the programming language race. The top 4 remained the same.
| Rank | Last Month | Change | Last Year | Change | |
|---|---|---|---|---|---|
| Python | 1 | 1 | 0 | 2 | +1 |
| JavaScript | 2 | 2 | 0 | 1 | -1 |
| Ruby | 3 | 3 | 0 | 3 | 0 |
| Java | 4 | 4 | 0 | 4 | 0 |
| C++ | 5 | 6 | +1 | 6 | +1 |
| Clojure | 6 | 8 | +2 | 8 | +2 |
| Scala | 7 | 5 | -2 | 9 | +2 |
| C | 8 | 7 | -1 | 7 | -1 |
| C# | 9 | 10 | +1 | 5 | -4 |
| Objective-C | 10 | 9 | -1 | 10 | 0 |
Compare Rails, node.js, PHP and Django
June shows more of the same with the rank being 1) Rails 2) node.js 3) PHP and 4) Django. After threatening Rails in May, with only 1 less mention, node.js has fallen back again leaving Rails as the clear top choice.
Compare AngularJS, Backbone, Ember and jQuery
JavaScript Frameworks are a fast moving bunch. In a comparison of some of the most popular ones though, we can see AngularJS double up Backbone for the second month in a row. jQuery took a large drop this month, perhaps because its now assumed or becuase it's becoming less necessary?
Compare Postgresql, MySQL and SQL Server
Postgresql shows a steady rise to being the top RDBMS choice. It regained the top spot after MySQL won the past 2 months. Not only that though, Postgresql achieved its largest margin of victory ever.
Compare Mongodb, Cassandra, Riak and CouchDB
After dominating the NoSQL space for the past 3 years, MongoDB came close to losing its crown to Cassandra, encountering a large dropoff from May to June. Other databases such as Riak and CouchDB continue to have a presence, but do not show much growth.
Compare Chef, Puppet, Ansible and the DevOps term itself
DevOps, the merger of systems administrators and programmers to drive infrastructure automation, is enjoying a real competition. With the current big 3, Chef was the clear winner with Puppet regaining its standard second place finish. Ansible could not maintain the momentum this month and fell back to third, but keep an eye on this one over the next few months. I'm witnessing Ansible chosen more anecdotally and I myself chose it recently.
| Tech | Rank | Last Month | Change | Last Year | Change |
|---|---|---|---|---|---|
| Python | 1 | 1 | 0 | 2 | +1 |
| JavaScript | 2 | 2 | 0 | 1 | -1 |
| Ruby | 3 | 5 | +2 | 3 | 0 |
| iOS | 4 | 4 | 0 | 4 | 0 |
| Rails | 5 | 6 | +1 | 5 | 0 |
| Android | 6 | 3 | -3 | 7 | +1 |
| AngularJS | 7 | 8 | +1 | 22 | +15 |
| Postgresql | 8 | 14 | +6 | 32 | +24 |
| Java | 9 | 9 | 0 | 6 | -3 |
| node.js | 10 | 7 | -3 | 13 | +3 |
| linux | 11 | 22 | +11 | 16 | +5 |
| Machine Learning | 12 | 15 | +3 | 17 | +5 |
| passionate | 13 | 13 | 0 | 15 | +2 |
| CSS | 14 | 11 | -3 | 8 | -6 |
| Front End | 15 | 19 | +4 | 31 | +16 |
| passion | 16 | 27 | +11 | 27 | +11 |
| AWS | 17 | 17 | 0 | 14 | -3 |
| Redis | 18 | 25 | +7 | 24 | +6 |
| PHP | 19 | 16 | -3 | 18 | -1 |
| DevOps | 20 | 18 | -2 | 48 | +28 |
| Tech | Mentions | Rank | Last Year Mentions | Last Year Rank | Change |
|---|---|---|---|---|---|
| Bash | 5 | 61 | 0 | 190 | +129 |
| Docker | 6 | 57 | 0 | 172 | +115 |
| OpenStack | 5 | 62 | 1 | 133 | +71 |
| Spark | 7 | 52 | 1 | 114 | +62 |
| Puppet | 6 | 58 | 1 | 110 | +52 |
| R | 8 | 50 | 2 | 96 | +46 |
| Spring | 10 | 46 | 2 | 89 | +43 |
| EC2 | 7 | 55 | 2 | 86 | +31 |
| Data Science | 14 | 37 | 4 | 67 | +30 |
| DevOps | 21 | 20 | 8 | 48 | +28 |
| Tech | Mentions | Rank | Last Year Mentions | Last Year Rank | Change |
|---|---|---|---|---|---|
| Erlang | 1 | 120 | 6 | 51 | -69 |
| Asp | 2 | 97 | 5 | 58 | -39 |
| C# | 5 | 65 | 15 | 30 | -35 |
| Objective-C | 4 | 78 | 9 | 45 | -33 |
| jQuery | 12 | 40 | 26 | 10 | -30 |
| Mongodb | 14 | 36 | 23 | 12 | -24 |
| Haskell | 3 | 84 | 5 | 61 | -23 |
| Heroku | 4 | 79 | 5 | 56 | -23 |
| Django | 12 | 42 | 20 | 19 | -23 |
| SQL Server | 4 | 76 | 6 | 54 | -22 |


skin pores different region {border-style sebaceous clinical oily px;} sebum study #ffffff;} Dermatol. characteristics number obtained related correlation acne Comed. Cont. malar parameters products regions results skin, Maia Skin evaluated image region, using ./j.-...x Figure comedones epidermis evaluation face higher nose presented FIGURE Visioscan Vivascope comedones. cosmetic excessive px; {font-family Res. analysis content development evaluate follicle font-size glands lower pores, signs surface Campos, Melo Seb Ser acne, active comedone count cutaneous differences double; facial glan. images inflammatory infundibulum large observed pore present thickness Acad. Technol. Zouboulis appearance aspect biophysical border-color border-width cause compared dermatological factors formation imaging improve open positive presents production properties region. regions. showing software solid; structural structure techniques visible {font-style {font-weight < Acne Campos Count Evaluation Pores Ramli activity bold camera characterization characterized chin closed conditions count, courier; depths dermis efficacy em; enlarged glands, great hair human important lesions lesions, life lipid oiliness possible pt;} relation research roughness skin. study, tissue undesirable used


Tik-Tok of Oz
by L. Frank Baum
To My Readers
Additional Information
- Year Published: 1914
- Language: English
- Country of Origin: United States of America
- Source: Baum, L. F. (1914). Tik-Tok of Oz. Chicago: Reilly and Britton.
-
Readability:
- Flesch–Kincaid Level: 7.0
- Word Count: 428
- Genre: Fantasy
- Keywords: 20th century literature, american literature, books of oz, children's literature, fantasy, l. frank baum
- ✎ Cite This
Downloads
The very marked success of my last year’s fairy book, “The Patchwork Girl of Oz,” convinces me that my readers like the Oz stories “best of all,” as one little girl wrote me. So here, my dears, is a new Oz story in which is introduced Ann Soforth, the Queen of Oogaboo, whom Tik-Tok assisted in conquering our old acquaintance, the Nome King. It also tells of Betsy Bobbin and how, after many adventures, she finally reached the marvelous Land of Oz.
There is a play called “The Tik-Tok Man of Oz,” but it is not like this story of “Tik-Tok of Oz,” although some of the adventures recorded in this book, as well as those in several other Oz books, are included in the play. Those who have seen the play and those who have read the other Oz books will find in this story a lot of strange characters and adventures that they have never heard of before.
In the letters I receive from children there has been an urgent appeal for me to write a story that will take Trot and Cap’n Bill to the Land of Oz, where they will meet Dorothy and Ozma. Also they think Button-Bright ought to get acquainted with Ojo the Lucky. As you know, I am obliged to talk these matters over with Dorothy by means of the “wireless,” for that is the only way I can communicate with the Land of Oz. When I asked her about this idea, she replied: “Why, haven’t you heard?” I said “No.” “Well,” came the message over the wireless, “I’ll tell you all about it, by and by, and then you can make a book of that story for the children to read.”
So, if Dorothy keeps her word and I am permitted to write another Oz book, you will probably discover how all these characters came together in the famous Emerald City. Meantime, I want to tell all my little friends—whose numbers are increasing by many thousands every year—that I am very grateful for the favor they have shown my books and for the delightful little letters I am constantly receiving. I am almost sure that I have as many friends among the children of America as any story writer alive; and this, of course, makes me very proud and happy.
L. Frank Baum.
“OZCOT”
at HOLLYWOOD
in CALIFORNIA,
1914.


eMedical is the online system,design for getting information about a doctor,take appointment with the doctor online.It will reduce the time.
It will also help an organisation in business management.It store records of doctors and medicines.It maintain record of business.


{% include "admin/configs/appearance.html" %}
{% include "admin/configs/theme.html" %}
{% include "admin/configs/accounts.html" %}
{% include "admin/configs/pages.html" %}
{% include "admin/configs/fields.html" %}
{% include "admin/configs/mlc.html" %}
{% include "admin/configs/settings.html" %}
{% include "admin/configs/security.html" %}
{% include "admin/configs/email.html" %}
{% include "admin/configs/time.html" %}
{% include "admin/configs/legal.html" %}
{% include "admin/configs/backup.html" %}
{% include "admin/configs/usermode.html" %}


This keyboard layout is designed for Quinault. It includes an on screen keyboard.
The keyboard will work with Times New Roman or many other Unicode encoded font. SIL International has produced several Unicode fonts that would also be suitable. These fonts are:


In this example I will use NameSilo. Having the cheepest domains on the market I prefer NameSilo.
Lets dive in...
What you will need:
- A Gmail account
- A Domain
Step 1: Set Up Email Forwarding
At the top right corner click Manage My Domains
Click on your domain name
Scroll down to DNS Records
Click Update
Scroll down to Email Forwarding
Click Apply Template
At the top right corner click Manage My Domains
Click Email Forwarding
Enter an [astrisk] into the first field
In the next enter the email you want it to forward to. (e.g<EMAIL_ADDRESS>It may take up to 48 hours for your DNS changes to take effect. You can test your new email by sending an email to<EMAIL_ADDRESS>Step 2: Setup Gmail to send custom domain emails
Go to gmail.comSign In to your gmail account
Click on your avatar
Click Google Account
On the sidebar click Security
Note: 2-Step Verification needs to be on
Click App Passwords
Select Mail
In the next field select Other
Enter the domain name you are using for you email
Click Generate
Copy the password. You will need it in the next few steps
Click on the settings icon
Click settings
Click Accounts and Imports
Click Add another Email address
Enter the name of the email address
Enter the email you want to send emails as
In the input field enter
smtp.gmail.com
Enter your gmail username
Paste the app password you copied (e.g.
qdlw jpms hgsd svzh
)
Select port 365
Click Add Account
You will recieve an email giving you a verification code. Paste that code into the input box. Now Click verify. You are all done! you can now send custom domain emails using gmail! When sending an email click the down arrow in the From: section, then select your custom domain email address.


sign up
input cannot be blank
input cannot be blank
invalid email
password doesn't match or it's blank


Landing Page
Special Projects
This story is part of a series of specially designed stories that represents some of the best journalism The Post has to offer. Check out the rest of the special projects here.
05.31.18
There are very few things that can make you feel more at home in Athens than Welcome Weekend.
From the second you get the keys to your brand new room in your residence hall, everything is new and exciting. You get to unpack your new accessories and make your space exactly how you want it. You start meeting people from all over the state, nation and world, and you’ll all be friends instantly because you probably don’t know many other people.
You’ll probably go to a dining hall for the first time and try pizza from Shively Dining Hall or breakfast foods at Nelson Court. You’ll travel in a pack everywhere and try what will soon become your favorite late-night snack. Maybe you’ll be a fan of fried mac-and-cheese at Union Street Diner, 70 W. Union St., or order fried rice at Fusion Noodle Company, 30 W. Union St.
It will probably be extremely hot, and walking up the hills will feel like climbing a mountain. Mill Street will look like a scene out of a movie during those first few nights back, and you can only get that during that one weekend. Everyone will be so excited and happy to be back, and you’ll probably hear people screaming or shrieking when they get reunited with their friends, which will become a thing you’ll do in the years to come.
During the weekend, you’ll be jammed into Peden Stadium and onto the football field for a photo with every freshman. If it’s anything like when I did it, you will probably be sweaty, sticky and ready to be back in your bed. The sun will be beating on you, and you’ll feel like you’re squinting the entire time.
There will be programs put on by sleep-deprived resident assistants and mandatory floor meetings to attend. You will probably be worried about getting your textbooks and what school supplies you need for classes to start on Monday, but those things will get worked out. You’ll also get a lot of free stuff from pizza to T-shirts to a water bottle or two.
Perhaps the best tradition of Welcome Weekend, however, is when Ohio University President Duane Nellis welcomes you in The Convo along with every other freshman.
“I don’t know how you spent your summer, but I spent mine falling in love. Don’t worry — my wife, Ruthie, already knows all about this,” Nellis said at last year’s convocation. “In fact, she fell in love this summer, too. We both fell in love with Ohio University.”
You’ll fall in love with the campus and town, too. After Convocation, you’ll get to follow the Marching 110 up Richland Avenue and onto College Green.
The band can be heard across campus, but only vaguely until it gets closer to College Green, which is swarming with new opportunities and upperclassmen waiting at the involvement fair.
Kevin Pan | SLOT EDITOR
The Marching 110 performs on College Green at the involvement fair.
Nearly all of the student organizations on campus will be there to welcome you. They’ll want you to join their team, and they’re genuinely excited for you to be there. Everything from Harry Potter Alliance to Bobcathon to even The Post will be there. Find the things you love, and jump right in.
Then, the music gets louder and everyone remembers what it feels like to be back on campus, and new freshmen are officially welcomed to Athens for the first time as they walk through Alumni Gateway and onto College Green.
“So enter that daily thou mayest grow in knowledge wisdom and love,” the gateway reads.
Welcome home. You’re going to love it.
Landing Page
This story is part of a series of specially designed stories that represents some of the best journalism The Post has to offer. Check out the rest of the special projects here.


ClusterResolver
Abstract class for all implementations of ClusterResolvers.
tf.compat.v1.distribute.cluster_resolver.ClusterResolver
tf.compat.v2.distribute.cluster_resolver.ClusterResolver
This defines the skeleton for all implementations of ClusterResolvers. ClusterResolvers are a way for TensorFlow to communicate with various cluster management systems (e.g. GCE, AWS, etc...).
By letting TensorFlow communicate with these systems, we will be able to automatically discover and resolve IP addresses for various TensorFlow workers. This will eventually allow us to automatically recover from underlying machine failures and scale TensorFlow worker clusters up and down.
Note to Implementors: In addition to these abstract methods, you must also implement the task_type, task_id, and rpc_layer attributes. You may choose to implement them either as properties with getters or setters or directly set the attributes.
environment
Returns the current environment which TensorFlow is running in.
There are two possible return values, "google" (when TensorFlow is running in a Google-internal environment) or an empty string (when TensorFlow is running elsewhere).
If you are implementing a ClusterResolver that works in both the Google environment and the open-source world (for instance, a TPU ClusterResolver or similar), you will have to return the appropriate string depending on the environment, which you will have to detect.
Otherwise, if you are implementing a ClusterResolver that will only work in open-source TensorFlow, you do not need to implement this property.
cluster_spec
cluster_spec()
Retrieve the current state of the cluster and return a ClusterSpec.
A ClusterSpec representing the state of the cluster at the moment this function is called.
Implementors of this function must take care in ensuring that the ClusterSpec returned is up-to-date at the time of calling this function. This usually means retrieving the information from the underlying cluster management system every time this function is invoked and reconstructing a cluster_spec, rather than attempting to cache anything.
master
master( task_type=None, task_id=None, rpc_layer=None )
Retrieves the name or URL of the session master.
task_type
: (Optional) The type of the TensorFlow task of the master.task_id
: (Optional) The index of the TensorFlow task of the master.rpc_layer
: (Optional) The RPC protocol for the given cluster.The name or URL of the session master.
Implementors of this function must take care in ensuring that the master returned is up-to-date at the time to calling this function. This usually means retrieving the master every time this function is invoked.
num_accelerators
num_accelerators( task_type=None, task_id=None, config_proto=None )
Returns the number of accelerator cores per worker.
This returns the number of accelerator cores (such as GPUs and TPUs) available per worker.
Optionally, we allow callers to specify the task_type, and task_id, for if they want to target a specific TensorFlow process to query the number of accelerators. This is to support heterogenous environments, where the number of accelerators cores per host is different.
task_type
: (Optional) The type of the TensorFlow task of the machine we
want to query.task_id
: (Optional) The index of the TensorFlow task of the machine we
want to query.config_proto
: (Optional) Configuration for starting a new session to
query how many accelerator cores it has.A map of accelerator types to number of cores.


--- authors: - brad-czerniak #categories: ["one", "two"] #date: 2020-03-03 02:02:02 #hero_classes: "background-color--main-dark color--white" meta: description: "Values for non-color design tokens." # image: # alt: "Default social image" # It's okay for this to be empty if the image is decorative # src: required/meta-image--default.jpg robots: "noindex,follow" # title: "Overrides the tab title and social titles" #permalink: docs/path/page-title/ #published: true #tags: ["three", "four"] title: "Values (design tokens)" ---
The following is a listing of design tokens for the design system of the site. Colors are displayed on their own page. As the design system matures, some values may also be broken out and given examples.
{% assign props = site.data.design-tokens.root | sort %} {% for prop in props %} {% if prop[0] != 'color' %}| Name | Value | Description | Category |
|---|---|---|---|
| {{ item[0] }}--{{ line[0] }} | {{ line[1].value }} | {{ line[1].description }} | {{ line[1].category }} |


new Matrix An extension of an Array that allows you to use it as a 2D Transformation Matrix. Source: Matrix.js, line 12


[all packages]
[package ]
[class hierarchy]
[index]
public class PrinterStringBuffer
(source file: PrinterStringBuffer.java)
java.lang.Object
|
+----Printer
|
+----PrinterStringBuffer
The pure class interface.
public class PrinterStringBuffer
extends Printer
-
An implementation of the
Printer
class which sends all
output to a string buffer.
- Author:
- Alan Jeffrey
- Version: v1.0 1998/06/02
- PrinterStringBuffer()
-
Create a new printer which stores the output.
- printRawString(String)
-
Append a string to the buffer.
- toString()
-
Convert the string buffer back to a string.
@result the contents of the string buffer.
PrinterStringBuffer
public PrinterStringBuffer();
-
Create a new printer which stores the output.
printRawString
public void printRawString(String s);
-
Append a string to the buffer.
- Parameters:
- s - the string to append.
- Overrides:
- printRawString in class Printer
toString
public String toString();
-
Convert the string buffer back to a string.
@result the contents of the string buffer.
- Overrides:
- toString in class Object
[all packages]
[package ]
[class hierarchy]
[index]
PrinterStringBuffer.html