|Jul28-12, 09:43 PM||#18|
AI optimal rotation of a rigid body
What I mean is to make the parameter you pass (i.e. t between 0 and 1 inclusive) to vary non-linearly. Instead of going from 0 to 1 in incremental steps that are the same, you can make it go say faster at the start and then let it decay at the end.
Different kinds of behaviours for f(t) where f(t) is in [0,1] and t is in [0,1] give different kinds of behaviours for how the AI rotates itself to approach the target.
If you are continually updating the path every tick so that the SLERP changes in accordance with the new position, then you can base the behaviour of f(t) on things like the dot product of the direction vector of the ship and the vector of the actual ship itself: speed it up when they are not aligned (i.e. dot product < 0) and then make it slow down when they are close (dot product > .05 for example)
You can, by transforming the parameter and how its incremented, directly control how the object moves and what it looks like when it rotates.
|Jul30-12, 01:44 PM||#19|
Thanks, I understand that a non-linear parameter will give the appearance of an accel/decel rotation, but that's more applicable to animation. I also can't see how it would cope with the case where e.g. the ship is at (Y,P,R) = (90,0,0), wants to get to (0,90,0) and is initially rotating around the yaw axis at 10 deg/second - as the path the ship would take is no longer a linear interpolation but a curve.
I think I can get it to work using something similar to http://www.shiffman.net/itp/classes/...09/seekarrive/ but for rotations. I'm going off on holidays now, and it's not quite working but I suspect it's due to a bug rather than a problem with the method, so I'll see if I can get it fixed when I get back - if I do, I'll post back here with my algorithm.
Thanks for all the suggestions so far!
|Aug16-12, 05:01 PM||#20|
Well, I haven't got C++ working but my python seems to be working well enough - using the seek/arrive steering behaviour I posted in my last post:
#!/usr/bin/env python3 from math import sqrt,sin,cos,acos rot_thrust = 0.01 #degrees per timestep DEGTORAD = 0.0174532 def main(): rot = Quaternion(1/sqrt(2),0,0,-1/sqrt(2)) drot = Quaternion(cos(30*rot_thrust*DEGTORAD),0,sin(30*rot_thrust*DEGTORAD),0) d2rot = Quaternion(1,0,0,0) goal = Vector(0,5,0) step = 0 while abs(rot.w - 1) > 0.00000001: step += 1 d2rot = steer(rot,drot,goal) drot = d2rot * drot rot = drot * rot def steer(rot,drot,goal): desired_drot = get_desired_drot(goal,rot,drot) desired_d2rot = (desired_drot * drot.inverse()).normalise() return get_d2rot(desired_d2rot) def get_desired_drot(goal,rot,drot): slow_down_dist = 90*DEGTORAD #radians max_speed = 0.0146221 #radians per timestep dot = Vector(0,1,0).dot(goal.normalise()); axis = goal.cross(Vector(0,1,0)).normalise() alpha = acos(dot) if axis == None and dot == 1: #parallel desired_rot = Quaternion(1,0,0,0) elif axis == None and dot == -1: #opposite desired_rot = Quaternion(0,1,0,0) else: desired_rot = Quaternion(cos(alpha/2),axis.x*sin(alpha/2),axis.y*sin(alpha/2),axis.z*sin(alpha/2)) to_desired = (desired_rot * rot.inverse()).normalise() dist = acos(to_desired.w)*2; if dist > 0: axis = Vector(to_desired.x,to_desired.y,to_desired.z).normalise() if dist < slow_down_dist: theta = max_speed*dist/slow_down_dist else: theta = max_speed return Quaternion(cos(theta/2),axis.x*sin(theta/2),axis.y*sin(theta/2),axis.z*sin(theta/2)) else: return Quaternion(1,0,0,0) def get_d2rot(desired): axis = Vector(desired.x,desired.y,desired.z).normalise() desired_theta = acos(desired.w)*2 assert(desired_theta >= 0) theta = min(desired_theta,rot_thrust*DEGTORAD) return Quaternion(cos(theta/2),axis.x*sin(theta/2),axis.y*sin(theta/2),axis.z*sin(theta/2))
|Similar Threads for: AI optimal rotation of a rigid body|
|Rotation of a Rigid Body||Introductory Physics Homework||8|
|Rotation of a Rigid Body||Classical Physics||2|
|rigid body rotation||General Physics||2|
|rotation of a rigid body||Introductory Physics Homework||6|