Jump to content
  • Advertisement
Sign in to follow this  
meteors

Need nice way to create parabolic trajectory

This topic is 4156 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I have made basic parabolic paths (by subtracting from a pre-set Y-amount), but I am looking for something more elaborate. I'm using this to create a trajectory for a mortar/projectile. I would really like a function which takes three parameters: the launching position(Vector), the landing position(Vector), and the angle of arc (float). Anyone have a function like this sitting on their hard drive? I also wouldn't mind finding a Class which does this and offers more features; this is something I do fairly often and would love more flexibility. I am happy to answer any questions if it helps to convey what I'm looking for. Thanks in advance!! Regards, -joshua joshua >>at<< spaceweather.com

Share this post


Link to post
Share on other sites
Advertisement
You could take a look at my two responses here for a couple of trajectory equations and functions, you could also do it iteratively (as you seem to be currently) as was also suggested there.

Unfortunately neither method I presented uses the angle of the arc, although im sure you could use the angle to calculate an initial speed/direction vector, but you did say you were interested in alternatives [smile]

Good luck

Share this post


Link to post
Share on other sites
Hey DMatter,

That's a helpful thread, but of course it's not exactly what I'm looking for. I really want a function with this signature:

Vector3 calculateTrajectory(Vector3 orgin, Vector3 destination, double arc);


Any ideas :-)



Thanks!!!!! Best,
-joshua

Share this post


Link to post
Share on other sites
R = horizontal difference of points
H = altitude difference to target
A = arc angle from ground
G = gravity constant
S = initial speed of the projectile

t = R / cos(A)

solve for S:
H = G * t * t / 2 + sin(A) * S * t

S = (H - G * t * t / 2) / (sin(A) * t)


Now that you have S, just make a new vector in the direction of the target, at the arc angle with magnitude of S.

I just did this now, there may be errors. But this should get you started.

Share this post


Link to post
Share on other sites
Quote:
Original post by meteors
Hey DMatter,

That's a helpful thread, but of course it's not exactly what I'm looking for. I really want a function with this signature:

Vector3 calculateTrajectory(Vector3 orgin, Vector3 destination, double arc);

I'm afraid that's not well-defined. If 'arc' defines the angle at the origin, then the (function) parameter set will uniquely define a parabola. To determine a point on the trajectory you'd also need to pass an input (mathematical) parameter, most likely time-from-launch or current-angle-from-some-give-point.

But yes, the best way to proceed would be to solve the quadratic equations of motion to describe the parabola as an appropriate polynomial, then evaluate it using the passed parameter.

Think carefully about exactly what inputs will be available and what form you want the output to be in, then report back.

Admiral

Share this post


Link to post
Share on other sites
Hi Admiral,

Argh...math...

Do you not know of any library which makes this sort of thing easy?



Cheers!
-joshua

Share this post


Link to post
Share on other sites
Quote:
Original post by meteors
Do you not know of any library which makes this sort of thing easy?

The mathematics isn't too tricky. I'm sure there are a few of us who'd be happy to walk you through the calculation and corresponding code. But first we need to know exactly what you're trying to achieve, 'cause it's not clear at the moment.

Take a step back and describe your goal (rather than your method) and we'll see how we can help.

Admiral

Share this post


Link to post
Share on other sites
Here's a way to do that's alot simpler since I cheated a bit with the equations:

""" turretGrav.py
Side view of turrent gun
Jaime Moreno
4/13/07
"""


import pygame, math
pygame.init()

class Label(pygame.sprite.Sprite):
""" Label Class (simplest version)
Properties:
font: any pygame font object
text: text to display
center: desired position of label center (x, y)
"""

def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.font = pygame.font.SysFont("None", 30)
self.text = ""
self.center = (320, 240)

def update(self):
self.image = self.font.render(self.text, 1, (0, 0, 0))
self.rect = self.image.get_rect()
self.rect.center = self.center

class Turret(pygame.sprite.Sprite):
def __init__(self, shell):
self.shell = shell
pygame.sprite.Sprite.__init__(self)
self.imageMaster = pygame.image.load("turret.gif")
self.imageMaster = self.imageMaster.convert()
self.imageMaster = pygame.transform.scale2x(self.imageMaster)
self.rect = self.imageMaster.get_rect()
self.rect.center = (100, 300)
self.turnRate = 10
self.dir = 0
self.charge = 5

def update(self):
self.checkKeys()
self.rotate()

def checkKeys(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.dir += self.turnRate
if self.dir > 360:
self.dir = self.turnRate
if keys[pygame.K_RIGHT]:
self.dir -= self.turnRate
if self.dir < 0:
self.dir = 360 - self.turnRate
if keys[pygame.K_UP]:
self.charge += 1
if self.charge > 20:
self.charge = 20
if keys[pygame.K_DOWN]:
self.charge -= 1
if self.charge < 0:
self.charge = 0

if keys[pygame.K_SPACE]:
self.shell.x = self.rect.centerx
self.shell.y = self.rect.centery
self.shell.speed = self.charge
self.shell.dir = self.dir
self.shell.calcVector()

def rotate(self):
oldCenter = self.rect.center
self.image = pygame.transform.rotate(self.imageMaster, self.dir)
self.rect = self.image.get_rect()
self.rect.center = oldCenter

class Shell(pygame.sprite.Sprite):
def __init__(self, screen, background): # add background to draw path
pygame.sprite.Sprite.__init__(self)
self.screen = screen
self.background = background

self.image = pygame.Surface((10, 10))
self.image.fill((0xff, 0xff, 0xff))
self.image.set_colorkey((0xff, 0xff, 0xff))
pygame.draw.circle(self.image, (0, 0, 0), (5, 5), 5)
self.image = pygame.transform.scale(self.image, (5, 5))
self.rect = self.image.get_rect()
self.rect.center = (-100, -100)

self.gravity = .5 # modify gravity as needed
self.speed = 0
self.dir =0
self.dx = 0
self.dy = 0
self.reset()

def update(self):
# self.calcVector()
# since we commented out calcVector() need to add self.dx,dy above!
self.calcPos()
self.checkBounds()
self.rect.center = (self.x, self.y)

def calcVector(self):
radians = self.dir * math.pi / 180

self.dx = self.speed * math.cos(radians)
self.dy = self.speed * math.sin(radians)
self.dy *= -1

# clear the background each time we fire so old paths don't show up
#self.background.fill((0x00,0xcc,0x00))

def calcPos(self):
# compensate for gravity


self.dy += self.gravity

# draw shell path
# get old position for drawing
oldx = self.x
oldy = self.y
self.x += self.dx
self.y += self.dy

pygame.draw.line(self.background, (0,0,0), (oldx, oldy),(self.x,self.y))



def checkBounds(self):
screen = self.screen
if self.x > screen.get_width():
self.reset()
if self.x < 0:
self.reset()
if self.y > screen.get_height():
self.reset()
if self.y < 0:
self.reset()

def reset(self):
""" move off stage and stop"""
self.x = -100
self.y = -100
self.speed = 0

def main():
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption ("Firing a Shell")

background = pygame.Surface(screen.get_size())
background.fill((0x00, 0xCC, 0x00))
screen.blit(background, (0, 0))

shell = Shell(screen, background)
turret = Turret(shell)
lblOutput = Label()
lblOutput.center = (100, 20)

allSprites = pygame.sprite.Group(shell, turret, lblOutput)

clock = pygame.time.Clock()
keepGoing = True
while keepGoing:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False

#update label
lblOutput.text = "dir: %d speed %d" % (turret.dir, turret.charge)

# blit background for drawings
screen.blit(background, (0,0))

#allSprites.clear(screen, background)
allSprites.update()
allSprites.draw(screen)
pygame.display.flip()

if __name__ == "__main__":
main()


Share this post


Link to post
Share on other sites
TheAdmiral,

Later today (when I have free time), I will explain in detail what I want to do. I really appreciate your offer to help :-)


Best,
-joshua

Share this post


Link to post
Share on other sites
Alright. Consider the following. You have a generic parabola which would be expressed as

y(x) = Ax^2 + Bx + C

You also have two points, and initial point (x0, y0) and a final point (x1, y1). This gives us two equations:

y0 = A(x0)^2+B(x0)+C
y1 = A(x1)^2+B(x1)+C

But with 3 unknowns (A,B,C) we don't have a solution yet. But we also have an initial angle theta. This corresponds to a slope of tan(theta). We can evaluate the slope of the parabola by taking a derivative so:

y'(x) = 2A*x+B

y' is our slope which we know at the initial point x=x0 so a third equation is

tan(theta) = 2*A*(x0)+B

This gives three equations:

tan(theta) = 2*A*(x0)+B
y0 = A(x0)^2+B(x0)+C
y1 = A(x1)^2+B(x1)+C

Which can be solved in the usual ways for A, B, and C.

At this point we have the equation we need for the parabola based off the initial point, final point and initial slope.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!