need interpolation algorithm... not cosine

BlitzMax Forums/BlitzMax Programming/need interpolation algorithm... not cosine

anybody have any ideas for a quick interpolation algorithm that would look something like this... as opposed to the second cosine graph?

0                                                              0
0                                                              0
 0                                                            0
 0                                                            0
  0                                                          0
   0                                                        0
    00                                                    00
      000                                              000
         0000                                      0000
             00000000000000000000000000000000000000
             
             
             
             
0000                                                             0000
    000                                                       000
       00                                                   00
         00                                               00
           0                                             0
            0                                           0
             0                                         0
              0                                       0
               00                                   00
                 00                               00
                   00                           00
                     000                     000
                        000               000
                           0000       0000
                               0000000


thanks!

You mean along the lines of y=x^2 ? (parabolic curve)

not really(in my attempts anyway) a parabolic is too close to the cosine for the bottom. I tried limiting the y but then the bottom "corners" were too harsh. it's close.. and that is what I may end up using. the key is something that ramps down then stay steady and then ramps up all through a time or distance variable but I'd like a softer transition from the "sides" to the "bottom".

I would start with a higher power of x, and then fiddle with that to get what you want.

Something like (x^6)/1000 looks close - change the 6 to a higher number if you want a wider gap, and increase the 1000 to a higher number if you want a less steep curve.

Here is what you might want. I did this by drawing 1/2 of an oval with a diameter equal to the distance between the points, then rotated and transformed the oval to match the position and angle of the points.
SuperStrict

Type TPoint
	Field x:Float
	Field y:Float
End Type

Local Point1:TPoint = New TPoint 'first point
Point1.x = 50
Point1.y = 300

Local Point2:TPoint = New TPoint 'second point
Point2.x = 750
Point2.y = 150

Local ArcDirection:Int = -1 'arc up or down
Local MidPoint:TPoint = New TPoint 'a point half way between point 1 and point 2
MidPoint.x = (Point2.x-Point1.x)/2+Point1.x
MidPoint.y = (Point2.y-Point1.y)/2+Point1.y

Local Angle:Float = ATan2(Point2.y-Midpoint.y,Point2.x-Midpoint.x) 'The angle of the first point with the middle point
Local Distx:Float = Sqr((MidPoint.x-Point1.x)^2+(MidPoint.y-Point1.y)) 'Distance point1 is from midpoint

Local Maxy:Float = 200 'How far to arc

Graphics 800,600

Cls
For Local a:Int = 180 To 0 Step -10 '0 is at point 2, 180 is at point 1, 180/step will give the number of steps :)
	Local Point:TPoint = New TPoint 'The point to be plotted
	Point.x = Cos(a) * Distx 'Find where the x,y coordinate is on in the arc
	Point.y = Sin(a) * Maxy
	Local PointAngle:Float = ATan2(Point.y,Point.x)*ArcDirection + Angle 'now rotate the arc to the proper angle
	Local PointDist:Float = Sqr(Point.x^2+Point.y^2)
	
	
	DrawOval (Cos(PointAngle)*PointDist + Midpoint.x)-5,(Sin(PointAngle)*PointDist + Midpoint.y)-5,10,10
Next
Flip
WaitKey()


ArcDirection is the direction you want the path to curve. 1 is down and -1 is up.
Angle is the angle between where the path starts and ends.
MaxY is how far out the path will move

This probably isn't the most efficient way to do this, but it might be a place to start.

TomToad - that does look like a rather unwieldy way of doing things. But an ellipse is a type of conic section, so it's on the same sort of track as a parabola.

edit: oop, totally forgot what I came back to this thread for - you can use this equation grapher to play around with equations and see what they look like.

TomToad - yeah that does give the shape I want but it's just too much calculation....

Warpy... off the bat what you said does look good but I can't seem to find the right calculation for the full curve(both sides)

a parabolic calc using I using for reference would look like this on the grapher link you posted

a*(x^2)+b*x
filling in the numbers...
x range(0 to 60)
y range(-50 to 50
a = -.045
b = 2.699
for
-.045*(x^2)+x*2.699

How about something like this? It starts with a circle 1/3 of the way through the curve, then switches to a line 1/3 of the way, then switches to a circle the last 1/3. Shouldn't be too difficult to modify for different curves and distances.
SuperStrict

Graphics 800,600
Type TPoint
	Field x:Float
	Field y:Float
End Type

Local Point1:TPoint = New TPoint
Point1.x = 50
Point1.y = 300

Local Point2:TPoint = New TPoint
Point2.x = 750
Point2.y = 300

Local Dist:Float = (Point2.x-Point1.x)/3.0

For Local t:Float = 0 To 1 Step .01
	Local Point:TPoint = New TPoint
	If t < 1/3.0 'first edge
		Local a:Float = 180.0-90.0*(t*3)
		Point.x = Cos(a)*Dist+Dist+Point1.x
		Point.y = Sin(a)*Dist+300
	Else If t < 2/3.0 'bottom
		Point.x = (Point2.x-Point1.x)*t+Point1.x
		Point.y = Dist+Point1.y
	Else
		Local a:Float = 90.0*((1.0-t)*3)
		Point.x = Cos(a)*Dist-Dist+Point2.x
		Point.y = Sin(a)*dist+300
	End If
	
	DrawOval Point.x-5,point.y-5,10,10
Next

Flip
WaitKey()

Edit: Just saw what you posted after posting this. The calcualtions in my previous example can be greatly reduced if you are only going to be following a path allong verticle or horizontal endpoints.

yep... that's exactly the shape I was looking for but it changes x... x is a linear component.. this works for drawing the shape but what I'm doing though is basically making a 2d heightmap... sorry I should have been more clear and my top graph should actually look like this, whoops!
0                                                              0
                                                                
 0                                                            0
                                                             
  0                                                          0
   0                                                        0
    00                                                    00
      000                                              000
         0000                                      0000
             00000000000000000000000000000000000000


Ok, that reminds me of this post a bit http://www.blitzbasic.com/Community/posts.php?topic=80236#901908
So I came up with this. x increases in a linear fasion, and y is calculated based on x. It also elliminates the need for sin() and cos(), however, I had to add a Sqr(), but only for the ends.
SuperStrict
Graphics 800,600

Type TPoint
	Field x:Float
	Field y:Float
End Type

Local Point1:TPoint = New TPoint
Point1.x = 50
Point1.y = 300

Local Point2:TPoint = New TPoint
Point2.x = 650
Point2.y = 300

Local MaxY:Float = 200
Local Maxy2:Float = Maxy^2
Cls
Local x:Float, y:Float
Local Dist:Float

For x = 0 To 600 Step 10
	If x < MaxY 'left edge
		Dist = Maxy-x
		y = Sqr(Maxy2-Dist*Dist)
	Else If x > (Point2.x-Point1.x)-Maxy 'right edge
		Local Dist:Float = (x-((Point2.x-Point1.x)-Maxy))
		y = Sqr(Maxy2-Dist*Dist)
	Else
		y = Maxy
	End If
	DrawOval x+Point1.x-5,y+300-5,10,10
Next
Flip
WaitKey()


ok that works! yeah I'm not crazy about the sqr but it's called only on deformation of the map so it shouldn't be to much of a problem.

thanks!