/// <summary> /// use this to round to a percent (0 to 100) /// </summary> public static double RoundNumber(double num) { int dec = 2; double result = 100 * JsMath.Round(num * JsMath.Pow(10, dec)) / JsMath.Pow(10, dec); return(result); }
//the following function handles the "physics" of how the can moves //calculating roation of the can and the direction of movement etc. //can be ignored if you only care about how to grab accelerometer readings //and do animations. // //the can wants to slide in the direction of the slope of the table. // //and wants to rotate such that the can is perpendicular to that direction (has reciprocal slope) // //the label of the can want to rotate in the direction opposite to gravity. public static void DoCanPhysics(XdkAcceleration a) { x_ispos = 1; y_ispos = 1; //take the abs tilt values so we don't //get stupid results while doing interim //calculations absx = JsMath.Abs(a.x); absy = JsMath.Abs(a.y); if (absx < .1) { absx = 0; } if (absy < .1) { absy = 0; } //skip the calculations if there is no movement; if (absx == absy && absx == 0) { return; } //var opp; //var adj; //what is the angle of the vector of motion of the can? //first calc without regard to sign of the accelerometer vectors lastangle = vectangle; vectangle = JsMath.Round(JsMath.Atan2(a.y, a.x) * 180 / JsMath.PI); // //ignore small variations in rotation so that the can doesn't shake incessantly // if (lastangle > vectangle) { // if (Math.abs(lastangle - vectangle) < 10) { // vectangle = lastangle; // } // } // else { // if (Math.abs(vectangle - lastangle) < 10) { // vectangle = lastangle; // } // } //now, adjust the arctan calculation for direction of the accel vectors //by adding the correct angle based on the quatrant // that the motion occurs in. //quadrant 1 if (x_ispos > 0 && y_ispos > 0) { vectangle = 90 - vectangle; } //quadrant 2 else if (x_ispos > 0 && y_ispos < 0) { vectangle = 90 + vectangle; } //quadrant 3 else if (x_ispos < 0 && y_ispos < 0) { vectangle = 270 - vectangle; } //quadrant 4 else if (x_ispos < 0 && y_ispos > 0) { vectangle = 270 + vectangle; } //make the motion vect angle positive. if (vectangle < 0) { vectangle = (vectangle + 360) % 360; } //allow some accelerated movement based on how tilted the device is dx = JsMath.Floor(JsMath.Log(RoundNumber(absx) * 5)); dx = JsMath.Max(dx, 0); dy = JsMath.Floor(JsMath.Log(RoundNumber(absy) * 5)); dy = JsMath.Max(dy, 0); x_ispos = 1; y_ispos = 1; if (a.x < 0) { x_ispos = -1; } if (a.y < 0) { y_ispos = -1; } //now put back the sign dx = dx * x_ispos; dy = dy * y_ispos; //calculate can movements current_left += dx; current_top -= dy; canangle = (canangle + 360) % 360; double a1, a2, a3, a4, af; //a1 and a2 then can is within 90 //a3 and a4 can is upside down relative to //the motion vector labeldirection = 1; a1 = vectangle + 90 - canangle; //HtmlElement.GetById("accel_z").innerHTML = "case 1: " ; af = a1; a2 = vectangle - 90 - canangle; if (JsMath.Abs(a2) < JsMath.Abs(af)) { af = a2; // HtmlElement.GetById("accel_z").innerHTML = "case 2: "; } a3 = vectangle + 90 - canangle + 180; if (JsMath.Abs(a3) < JsMath.Abs(af)) { af = a3; //HtmlElement.GetById("accel_z").innerHTML = "case 3: "; labeldirection = -1; } a4 = vectangle - 90 - canangle + 180; if (JsMath.Abs(a4) < JsMath.Abs(af)) { af = a4; // HtmlElement.GetById("accel_z").innerHTML = "case 4: a4 = " + a4 + "a3 = " + a3 + "a2 = " + a2 + "a1 = " + a1; labeldirection = -1; } if (af > 180) { af = -1 * (360 - af); } //HtmlElement.GetById("accel_y").innerHTML = "vectangle= " + vectangle + "; canangle=" + canangle + " rotpos=" + af; // + "; rotneg=" + rotneg + "; nextrot=" + nextrot; // HtmlElement.GetById("accel_x").innerHTML = "a.x = " + a.x + ", a.y = " + a.y; //which way should the label spin? //it should spin right when moving at 90deg to the //motion vector, spin left when moving at 270deg if (canangle > vectangle) { labeldirection = -1; } if (JsMath.Abs(canangle - vectangle) > 180) { labeldirection = labeldirection * -1; } //if the movement is right or down then the label and can is upright, label move left labelleft += labeldirection * JsMath.Ceil(JsMath.Sqrt(dx * dx + dy * dy)); if (af > 3) { canangle++; } else if (af < -3) { canangle--; } }