26.04.2009 | 23:05
Djipi je napisao:
Bilo bi jednostavnije odgovoriti na ovo pitanje da si definirao konkretan problem kojeg pokušavaš riješiti (ako imaš neki na umu, naravno). Kuglica koja reagira na ajfonov akcelerometar je prilično trivijalan zadatak i ovo što si napisao da si napravio za trenje nije daleko od "prave" fizike. Pišem pod navodnicima jer se fizika i tako uvijek pojednostavni za sve real-time simulacije.
Najviše je problem što kretanje te kuglice ovisi o konstantama koja sam ja izvukao iz šešira i koje daju dojam realnosti unutar postojećih parametara. Jedna kuglica i ne znam koliko iteracija po sekundi. A ako stvar jednom zakompliciram i broj iteracija po sekundi se bitno smanji onda ove konstante više neće biti dobre i što onda? Ne da mi se stalno to narihtavati, dakle problem zapravo nisam riješio nego imam privid.
A i privid nije baš savršen, pošto recimo nagle trzaje odnosno naglo naginjanje iPoda na suprotnu stranu baš nisam pogodio. Realna kuglica bi se naglo zaustavila i pojurila nazad, a ova moja uspori pa onda stane pa lagano krene na drugu stranu, pa tek onda ubrza. Kao da ide kroz med ili nešto.
Nije to to!
Počeo sam od osnovnog primjera iz knjige
Beginning iPhone Development: Exploring the iPhone SDK, (
13. poglavlje, ako netko ima knjigu). Oni imaju samo osnovno ubrzanje od akcelerometra, na koje sam onda ja dodao usporavanje zbog trenja, nekakvu inerciju i odbijance od zida, detekciju dodira da možeš lopticu prstom premještati i još par fora. Dodao sam još i ispis svih vrijednosti obračuna, naravno zelenom bojom na crnoj podlozi, da malo bude ala matrix.
Ovo je matematika kretanja:
#define kVelocityMultiplier 800
#define kFloorFrictionValue .045
#define kDecelerationMultiplier .01
#define kBouncingMultiplier 1.13
- (void)setCurPoint:(CGPoint)newPoint
{
prevPoint = curPoint;
curPoint = newPoint;
if (curPoint.x < 0) {
curPoint.x = 0;
xBallVelocity = -(xBallVelocity * kBouncingMultiplier); // 0;
}
if (curPoint.y < 0) {
curPoint.y = 0;
yBallVelocity = -(yBallVelocity * kBouncingMultiplier); // 0;
}
if (curPoint.x > self.bounds.size.width - image.size.width) {
curPoint.x = self.bounds.size.width - image.size.width;
xBallVelocity = -(xBallVelocity * kBouncingMultiplier); // 0;
}
if (curPoint.y > self.bounds.size.height - image.size.height) {
curPoint.y = self.bounds.size.height - image.size.height;
yBallVelocity = -(yBallVelocity * kBouncingMultiplier); // 0;
}
CGRect curImageRect = CGRectMake (curPoint.x, curPoint.y, image.size.width, image.size.height);
CGRect prevImageRect = CGRectMake (prevPoint.x, prevPoint.y, image.size.width, image.size.height);
[self setNeedsDisplayInRect:CGRectUnion(curImageRect, prevImageRect)];
}
- (CGFloat)floorFriction:(CGFloat)acceValue
{
if (acceValue > kFloorFrictionValue)
acceValue -= kFloorFrictionValue;
else if (acceValue < -kFloorFrictionValue)
acceValue += -kFloorFrictionValue;
else
acceValue = 0.;
return (acceValue);
}
- (CGFloat)deceleration:(CGFloat)acceValue
{
CGFloat retVal = acceValue - (acceValue * kDecelerationMultiplier);
if (retVal > 20. || retVal < -20.)
return (retVal / 10.);
if (retVal < .001 && retVal > -.001)
return (0.);
return (retVal);
}
- (void)draw
{
static NSDate *lastDrawTime = nil;
if (lastDrawTime) {
NSTimeInterval secondsSinceLastDraw = -([lastDrawTime timeIntervalSinceNow]);
xBallVelocity += ([self floorFriction:acceleration.x] * secondsSinceLastDraw);
xBallVelocity = [self deceleration:xBallVelocity];
yBallVelocity += -([self floorFriction:acceleration.y] * secondsSinceLastDraw);
yBallVelocity = [self deceleration:yBallVelocity];
CGFloat xDelta = xBallVelocity * secondsSinceLastDraw * kVelocityMultiplier;
CGFloat yDelta = yBallVelocity * secondsSinceLastDraw * kVelocityMultiplier;
self.curPoint = CGPointMake (curPoint.x + xDelta, curPoint.y + yDelta);
}
[lastDrawTime release];
lastDrawTime = [[NSDate alloc] init];
}
(Original je na
iphonedevbook.com ako nekog zanima)
Uglavnom, koliko god kretanje svima kojima sam pokazao program izgleda realno, nakon nekog vremena počinju primjedbe a i sam pogled na source code pokazuje da je sve nekako traljavo. Zato mi treba malo teorije, a pogotovo mi fali riječnik pojmova za ovo područje.
Bacit ću pogled na onaj Bullet API link.