What is kAccelerometerMinStep? - iphone

I have been looking at the Accelerometer Graph example in the iOS Developer library and I have a question about one of the variables that is used...
#define kAccelerometerMinStep 0.02
What is the Accelerometer Min Step? and what role does it have?
Here is how it is being used in the Low Pass Filter...
-(void)addAcceleration:(UIAcceleration*)accel
{
double alpha = filterConstant;
if(adaptive)
{
double d = Clamp(fabs(Norm(x, y, z) - Norm(accel.x, accel.y, accel.z)) / kAccelerometerMinStep - 1.0, 0.0, 1.0);
alpha = (1.0 - d) * filterConstant / kAccelerometerNoiseAttenuation + d * filterConstant;
}
x = accel.x * alpha + x * (1.0 - alpha);
y = accel.y * alpha + y * (1.0 - alpha);
z = accel.z * alpha + z * (1.0 - alpha);
}
And here is how it is being used in the High Pass Filter...
-(void)addAcceleration:(UIAcceleration*)accel
{
double alpha = filterConstant;
if(adaptive)
{
double d = Clamp(fabs(Norm(x, y, z) - Norm(accel.x, accel.y, accel.z)) / kAccelerometerMinStep - 1.0, 0.0, 1.0);
alpha = d * filterConstant / kAccelerometerNoiseAttenuation + (1.0 - d) * filterConstant;
}
x = alpha * (x + accel.x - lastX);
y = alpha * (y + accel.y - lastY);
z = alpha * (z + accel.z - lastZ);
lastX = accel.x;
lastY = accel.y;
lastZ = accel.z;
}
If someone could tell me what the min step is responsible for I would be very grateful...
I would like to capture accelerations ranging in magnitude from 0.05 to 2.00 g force with a frequency response of 0.25-2.50 Hz
Thanks.!

Related

How to draw line until middle point using quadraticBezierTo in flutter?

I'm trying to draw a line between three points using quadraticsBezierTo but here is my problem.
Current result:
Current result
Expected result:
Expected result
Code:
final path = Path();
path.moveTo(p1.x, p1.y);
path.quadraticBezierTo(p2.x, p2.y, p3.x, p3.y);
//Also tried: path.cubicTo(p2.x, p2.y, p2.x, p2.y, p3.x, p3.y);
Do you know how to achieved this result?
Maybe,
path.quadraticBezierTo(
2.0 * p2.x - 0.5 * (p1.x + p3.x), 2.0 * p2.y - 0.5 * (p1.y + p3.y),
p3.x, p3.y);
or
path.cubicTo(
(4.0 * p2.x - p3.x) / 3.0, (4.0 * p2.y - p3.y) / 3.0,
(4.0 * p2.x - p1.x) / 3.0, (4.0 * p2.y - p1.y) / 3.0,
p3.x, p3.y);
Appendix
If you prefer sharper/blunter curves, throw away quadratics Bezier curve and take cubic Bezier curve. Then shift the control points evenly inwards/outwards.
double epsilon = -0.1;
path.cubicTo(
(4.0 * p2.x - p3.x - epsilon * (p3.x - p1.x)) / 3.0, (4.0 * p2.y - p3.y - epsilon * (p3.y - p1.y)) / 3.0,
(4.0 * p2.x - p1.x + epsilon * (p3.x - p1.x)) / 3.0, (4.0 * p2.y - p1.y + epsilon * (p3.y - p1.y)) / 3.0,
p3.x, p3.y);
This breaks tangents at end points of the curve, though.
Bezier curves aren't designed to pass through their control points, but if that's what you want you can do it by modifying the center point. From Wikipedia
For quadratic Bézier curves one can construct intermediate points Q0 and Q1 such that as t varies from 0 to 1:
Point Q0(t) varies from P0 to P1 and describes a linear Bézier curve.
Point Q1(t) varies from P1 to P2 and describes a linear Bézier curve.
Point B(t) is interpolated linearly between Q0(t) to Q1(t) and describes a quadratic Bézier curve.
Thus,
q0 = p0 * (1 - t) + p1 * t and q1 = p1 * (1 - t) + p2 * t and the actual curve is
b = q0 * (1 - t) + q1 * t
= p0 * (1 - t)^2 + p1 * t * (t - 1) + p1 * t * (t - 1) + p2 * t^2
= p0 * (1 - t)^2 + 2 * p1 * t * (t - 1) + p2 * t^2
Note that by ^ I mean exponent, not xor.
So if you want your curve to pass through some point c at time t = 1/2, then we can find what p1 should be.
c = p0 * 0.25 + p1 * 0.5 + p2 * 0.25
So,
p1 = 2 * c - 0.5 * (p0 + p2)

Color Blending in WebGL

I'm using the following library:
https://github.com/tengbao/vanta/blob/master/src/vanta.halo.js
A demo can be found here:
https://www.vantajs.com/?effect=halo
If I'm using a bright (or even white) background color, the effect is not visible anymore.
With my limited WebGL knowledge, my guess is that this is because of the subtraction of the background color (mixedColor = texture2D(...) - backgroundColor) (but I could be wrong).
void main() {
vec2 res2 = iResolution.xy * iDpr;
vec2 uv = gl_FragCoord.xy / res2; // 0 to 1
vec4 oldImage = texture2D(iBuffer, uv);
vec3 mixedColor = oldImage.rgb - backgroundColor;
float cropDist = 0.01;
float cropXOffset = 0.2;
float cropYOffset = 0.2;
vec2 offset = uv + vec2((mixedColor.g - cropXOffset) * cropDist, (mixedColor.r - cropYOffset) * cropDist);
float spinDist = 0.001;
float spinSpeed = 0.2 + 0.15 * cos(iTime * 0.5);
float timeFrac = mod(iTime, 6.5);
vec2 offset2 = uvBig + vec2(cos(timeFrac * spinSpeed) * spinDist, sin(timeFrac * spinSpeed) * spinDist);
mixedColor = texture2D(iBuffer, offset).rgb * 0.4
+ texture2D(iBuffer, offset2).rgb * 0.6
- backgroundColor;
float fadeAmt = 0.0015; // fade this amount each frame // 0.002
mixedColor = (mixedColor - fadeAmt) * .995;
vec4 spectrum = abs( abs( .95*atan(uv.x, uv.y) -vec4(0,2,4,0) ) -3. )-1.;
float angle = atan(pixel.x, pixel.y);
float dist = length(pixel - mouse2*0.15) * 8. + sin(iTime) * .01;
float flowerPeaks = .05 * amplitudeFactor * size;
float flowerPetals = 7.;
float edge = abs((dist + sin(angle * flowerPetals + iTime * 0.5) * sin(iTime * 1.5) * flowerPeaks) * 0.65 / size);
float colorChangeSpeed = 0.75 + 0.05 * sin(iTime) * 1.5;
float rainbowInput = timeFrac * colorChangeSpeed;
float brightness = 0.7;
vec4 rainbow = sqrt(j2hue(cos(rainbowInput))) + vec4(baseColor,0) - 1.0 + brightness;
float factor = smoothstep(1., .9, edge) * pow(edge, 2.);
vec3 color = rainbow.rgb * smoothstep(1., .9, edge) * pow(edge, 20.);
vec4 ring = vec4(
backgroundColor + clamp( mixedColor + color, 0., 1.)
, 1.0);
gl_FragColor = ring;
}
However I'm not able to figure out, how to adapt the behavior, so I can use a bright background.
If I remove the subtraction (and also remove the addition of the same at the end (vec4 ring = vec4(clamp(...))), I get the correct effect but with a black background.
Does anyone have an idea how to adapt the shader?
The problem is likely that backgroundColor is being added to the color to calculate the ring value. This will blow out your final color if backgroundColor is too bright.

Scaling a rotated ellipse

I have a function that draws an ellipse respecting some major axis (vx) and minor axis (vy) scales rotated clockwise by an angle a. I would like to adjust it so that the unrotated ellipse satisfies the equation:
(x / vx)^2 + (y / vy)^2 = s
For some value s which is passed in.
function [] = plotellipse(cx, cy, vx, vy, s, a)
t = linspace(0, 2 * pi);
x = cx + vx * cos(t) * cos(-a) - vy * sin(t) * sin(-a);
y = cy + vy * sin(t) * cos(-a) + vx * cos(t) * sin(-a);
plot(x,y,'y-');
The usual equation for an ellipse, which you have implemented correctly, is
To reduce the desired equation to the same form, divide through by s:
Now x and y become
vxs = vx / sqrt(s)
vys = vy / sqrt(s)
x = cx + vxs * cos(t) * cos(-a) - vys * sin(t) * sin(-a);
y = cy + vys * sin(t) * cos(-a) + vxs * cos(t) * sin(-a);

iOS OpenGL ES 2.0 Quaternion Rotation Slerp to XYZ Position

I am following the quaternion tutorial: http://www.raywenderlich.com/12667/how-to-rotate-a-3d-object-using-touches-with-opengl and am trying to rotate a globe to some XYZ location. I have an initial quaternion and generate a random XYZ location on the surface of the globe. I pass that XYZ location into the following function. The idea was to generate a lookAt vector with GLKMatrix4MakeLookAt and define the end Quaternion for the slerp step from the lookAt matrix.
- (void)rotateToLocationX:(float)x andY:(float)y andZ:(float)z {
// Turn on the interpolation for smooth rotation
_slerping = YES; // Begin auto rotating to this location
_slerpCur = 0;
_slerpMax = 1.0;
_slerpStart = _quat;
// The eye location is defined by the look at location multiplied by this modifier
float modifier = 1.0;
// Create a look at vector for which we will create a GLK4Matrix from
float xEye = x;
float yEye = y;
float zEye = z;
//NSLog(#"%f %f %f %f %f %f",xEye, yEye, zEye, x, y, z);
_currentSatelliteLocation = GLKMatrix4MakeLookAt(xEye, yEye, zEye, 0, 0, 0, 0, 1, 0);
_currentSatelliteLocation = GLKMatrix4Multiply(_currentSatelliteLocation,self.effect.transform.modelviewMatrix);
// Turn our 4x4 matrix into a quat and use it to mark the end point of our interpolation
//_currentSatelliteLocation = GLKMatrix4Translate(_currentSatelliteLocation, 0.0f, 0.0f, GLOBAL_EARTH_Z_LOCATION);
_slerpEnd = GLKQuaternionMakeWithMatrix4(_currentSatelliteLocation);
// Print info on the quat
GLKVector3 vec = GLKQuaternionAxis(_slerpEnd);
float angle = GLKQuaternionAngle(_slerpEnd);
//NSLog(#"%f %f %f %f",vec.x,vec.y,vec.z,angle);
NSLog(#"Quat end:");
[self printMatrix:_currentSatelliteLocation];
//[self printMatrix:self.effect.transform.modelviewMatrix];
}
The interpolation works, I get a smooth rotation, however the ending location is never the XYZ I input - I know this because my globe is a sphere and I am calculating XYZ from Lat Lon. I want to look directly down the 'lookAt' vector toward the center of the earth from that lat/lon location on the surface of the globe after the rotation. I think it may have something to do with the up vector but I've tried everything that made sense.
What am I doing wrong - How can I define a final quaternion that when I finish rotating, looks down a vector to the XYZ on the surface of the globe? Thanks!
Is the following your meaning:
Your globe center is (0, 0, 0), radius is R, the start position is (0, 0, R), your final position is (0, R, 0), so rotate the globe 90 degrees around X-asix?
If so, just set lookat function eye position to your final position, the look at parameters to the globe center.
m_target.x = 0.0f;
m_target.y = 0.0f;
m_target.z = 1.0f;
m_right.x = 1.0f;
m_right.y = 0.0f;
m_right.z = 0.0f;
m_up.x = 0.0f;
m_up.y = 1.0f;
m_up.z = 0.0f;
void CCamera::RotateX( float amount )
{
Point3D target = m_target;
Point3D up = m_up;
amount = amount / 180 * PI;
m_target.x = (cos(PI / 2 - amount) * up.x) + (cos(amount) * target.x);
m_target.y = (cos(PI / 2 - amount) * up.y) + (cos(amount) * target.y);
m_target.z = (cos(PI / 2 - amount) * up.z) + (cos(amount) * target.z);
m_up.x = (cos(amount) * up.x) + (cos(PI / 2 + amount) * target.x);
m_up.y = (cos(amount) * up.y) + (cos(PI / 2 + amount) * target.y);
m_up.z = (cos(amount) * up.z) + (cos(PI / 2 + amount) * target.z);
Normalize(m_target);
Normalize(m_up);
}
void CCamera::RotateY( float amount )
{
Point3D target = m_target;
Point3D right = m_right;
amount = amount / 180 * PI;
m_target.x = (cos(PI / 2 + amount) * right.x) + (cos(amount) * target.x);
m_target.y = (cos(PI / 2 + amount) * right.y) + (cos(amount) * target.y);
m_target.z = (cos(PI / 2 + amount) * right.z) + (cos(amount) * target.z);
m_right.x = (cos(amount) * right.x) + (cos(PI / 2 - amount) * target.x);
m_right.y = (cos(amount) * right.y) + (cos(PI / 2 - amount) * target.y);
m_right.z = (cos(amount) * right.z) + (cos(PI / 2 - amount) * target.z);
Normalize(m_target);
Normalize(m_right);
}
void CCamera::RotateZ( float amount )
{
Point3D right = m_right;
Point3D up = m_up;
amount = amount / 180 * PI;
m_up.x = (cos(amount) * up.x) + (cos(PI / 2 - amount) * right.x);
m_up.y = (cos(amount) * up.y) + (cos(PI / 2 - amount) * right.y);
m_up.z = (cos(amount) * up.z) + (cos(PI / 2 - amount) * right.z);
m_right.x = (cos(PI / 2 + amount) * up.x) + (cos(amount) * right.x);
m_right.y = (cos(PI / 2 + amount) * up.y) + (cos(amount) * right.y);
m_right.z = (cos(PI / 2 + amount) * up.z) + (cos(amount) * right.z);
Normalize(m_right);
Normalize(m_up);
}
void CCamera::Normalize( Point3D &p )
{
float length = sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
if (1 == length || 0 == length)
{
return;
}
float scaleFactor = 1.0 / length;
p.x *= scaleFactor;
p.y *= scaleFactor;
p.z *= scaleFactor;
}
The answer to this question is a combination of the following rotateTo function and a change to the code from Ray's tutorial at ( http://www.raywenderlich.com/12667/how-to-rotate-a-3d-object-using-touches-with-opengl ). As one of the comments on that article says there is an arbitrary factor of 2.0 being multiplied in GLKQuaternion Q_rot = GLKQuaternionMakeWithAngleAndVector3Axis(angle * 2.0, axis);. Remove that "2" and use the following function to create the _slerpEnd - after that the globe will rotate smoothly to XYZ specified.
// Rotate the globe using Slerp interpolation to an XYZ coordinate
- (void)rotateToLocationX:(float)x andY:(float)y andZ:(float)z {
// Turn on the interpolation for smooth rotation
_slerping = YES; // Begin auto rotating to this location
_slerpCur = 0;
_slerpMax = 1.0;
_slerpStart = _quat;
// Create a look at vector for which we will create a GLK4Matrix from
float xEye = x;
float yEye = y;
float zEye = z;
_currentSatelliteLocation = GLKMatrix4MakeLookAt(xEye, yEye, zEye, 0, 0, 0, 0, 1, 0);
// Turn our 4x4 matrix into a quat and use it to mark the end point of our interpolation
_slerpEnd = GLKQuaternionMakeWithMatrix4(_currentSatelliteLocation);
}

OpenGL ES: Translate a matrix to a particular point

Hi guys I am working on a app which requires the use of opengl es. However I have some questions. My task at hand is to rotate a matrix about an arbitrary point say (0,0,0). I did some research on google and the most common approach is
translate the matrix to (0,0,0)
Rotate the matrix
Translate the matrix back to its original position
Effectively
glTranslatef(centerX, centerY, centerZ);
glRotatef(angle, 0, 0, 1);
glTranslatef(-centerX, -centerY, -centerZ);
However my problem is I am using opengl es 2.0. The function translatef does not exist in opengl es 2.0. I have a function called as translateBy but I am unable to figure out how to use translateBy function to translate my matrix to a certain point
Thanks any help would be appreciated.
In OpenGL ES 2.0 you have to use vertex shader and just update the modelview matrix in every frame using
GLint modelviewmatrix = glGetUniformLocation(m_simpleProgram, "ModelviewMatrix");
matrx4 modelviewMatrix = rotation * translation;
glUniformMatrix4fv(modelviewmatrix, 1, 0, modelviewMatrix.Pointer());
assuming matrx4 as a matrix class of 4x4. and rotation and translation are the 4x4 matrix objects for rotation and translation.
Just make your own translate and rotate functions,
Translatef(x,y,z) is equivalent to
Matrx4 Translate( x, y, z)
{
Matrx4 m;
m = { 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, z, 1 }
return m;
}
and Rotatef(degree, vector3 axis) is equivalent to
Matrx4 Rotate( float degree, vector3 axis)
{
float radians = degrees * 3.14159f / 180.0f;
float s = std::sin(radians);
float c = std::cos(radians);
Matrx4 m = Identity(); /// load identity matrix
m[0] = c + (1 - c) * axis.x * axis.x;
m[1] = (1 - c) * axis.x * axis.y - axis.z * s;
m[2] = (1 - c) * axis.x * axis.z + axis.y * s;
m[4] = (1 - c) * axis.x * axis.y + axis.z * s;
m[5] = c + (1 - c) * axis.y * axis.y;
m[6] = (1 - c) * axis.y * axis.z - axis.x * s;
m[8] = (1 - c) * axis.x * axis.z - axis.y * s;
m[9] = (1 - c) * axis.y * axis.z + axis.x * s;
m[10] = c + (1 - c) * axis.z * axis.z;
return m;
}