我正在使用Apple的这个Accelerometer graph并尝试将其G-force代码转换为 +/- 128 。
下图显示标签中的 x , y , z 值与图表上的输出不匹配:(请注意,addX:y:z
值是图表上方标签中显示的值
x,y,z 值从蓝牙外设接收,然后使用以下方式转换:
// Updates LABELS
- (void)didReceiveRawAcceleromaterDataWithX:(NSInteger)x Y:(NSInteger)y Z:(NSInteger)z
{
dispatch_async(dispatch_get_main_queue(), ^{
_labelAccel.text = [NSString stringWithFormat:@"x:%li y:%li z:%li", (long)x, (long)y, (long)z];
});
}
// Updates GRAPHS
- (void)didReceiveAcceleromaterDataWithX:(NSInteger)x Y:(NSInteger)y Z:(NSInteger)z
{
dispatch_async(dispatch_get_main_queue(), ^{
float xx = ((float)x) / 8192;
float yy = ((float)y) / 8192;
float zz = ((float)z) / 8192;
[_xGraph addX:xx y:0 z:0];
[_yGraph addX:0 y:yy z:0];
[_zGraph addX:0 y:0 z:zz];
});
}
- (BOOL)addX:(UIAccelerationValue)x y:(UIAccelerationValue)y z:(UIAccelerationValue)z
{
// If this segment is not full, then we add a new acceleration value to the history.
if (index > 0)
{
// First decrement, both to get to a zero-based index and to flag one fewer position left
--index;
xhistory[index] = x;
yhistory[index] = y;
zhistory[index] = z;
// And inform Core Animation to redraw the layer.
[layer setNeedsDisplay];
}
// And return if we are now full or not (really just avoids needing to call isFull after adding a value).
return index == 0;
}
- (void)drawLayer:(CALayer*)l inContext:(CGContextRef)context
{
// Fill in the background
CGContextSetFillColorWithColor(context, kUIColorLightGray(1.f).CGColor);
CGContextFillRect(context, layer.bounds);
// Draw the grid lines
DrawGridlines(context, 0.0, 32.0);
// Draw the graph
CGPoint lines[64];
int i;
float _granularity = 16.f; // 16
NSInteger _granualCount = 32; // 32
// X
for (i = 0; i < _granualCount; ++i)
{
lines[i*2].x = i;
lines[i*2+1].x = i + 1;
lines[i*2].y = xhistory[i] * _granularity;
lines[i*2+1].y = xhistory[i+1] * _granularity;
}
CGContextSetStrokeColorWithColor(context, _xColor.CGColor);
CGContextStrokeLineSegments(context, lines, 64);
// Y
for (i = 0; i < _granualCount; ++i)
{
lines[i*2].y = yhistory[i] * _granularity;
lines[i*2+1].y = yhistory[i+1] * _granularity;
}
CGContextSetStrokeColorWithColor(context, _yColor.CGColor);
CGContextStrokeLineSegments(context, lines, 64);
// Z
for (i = 0; i < _granualCount; ++i)
{
lines[i*2].y = zhistory[i] * _granularity;
lines[i*2+1].y = zhistory[i+1] * _granularity;
}
CGContextSetStrokeColorWithColor(context, _zColor.CGColor);
CGContextStrokeLineSegments(context, lines, 64);
}
如何计算上述代码以精确显示图表上的正确加速度计值?
答案 0 :(得分:1)
我发布这个作为aswer而不是评论,因为我没有足够的声誉,但我写的可能足以让你朝着正确的方向发送,它甚至可能算作答案......
您的问题仍然不包括真正重要的内容。我假设xx / yy / zz的计算没有问题。虽然我不知道8192应该是什么意思。
我想这个问题出现在你将值映射到像素坐标的部分...... lines []包含您的值,范围是标签中值的1/8192。所以你的x值-2应该在-0.0000像素的像素位置,所以稍微(远小于1像素)在视图上方...因为你看到线条进一步向下,必须有一些翻译到位(未在您的代码中显示)
重要但未显示的第二部分是DrawGridlines。可能有一种不同的方法将值映射到像素坐标...
使用调试器检查绘制+ 127行时获得的像素坐标,以及在历史数组中插入+127值时获得的像素坐标
阅读代码时需要改进的一些想法:
1.)将图形放在它自己的绘制一个图形的类中(并且只有一个历史。不知何故,你似乎已经部分已经存在(否则我无法弄清楚你的_xGraph / _yGraph / _zGraph)但另一方面你绘制所有一个drawLayer中的3个值???目前你似乎有3 * 3历史缓冲区,其中3 * 2填充零...
2.)使用一个地方进行Y的计算,用于绘制网格和绘制线条。
3.)使用CGContextMoveToPoint(); + CGContextAddLineToPoint();而不是用这些丑陋的2 * i + 1个凹痕复制到行[] ......