[quote]
...you could have the point move a smaller number of pixels at a time...
[/uote]
Yes. But how many pixels and in which direction?? Linear interpolation allows you to do this. The only way to find out the increments on x and y are to normalize the vector.
0,50------------------------------->30,100
To get from 0,50 to 30,100 we must know how much to move on x for every y or vice versa. You could use the slope intercept form of a line to find this out or you could normalize the vector.
Normalizing the vector requires using the square root function.
First subtract the points:
diffx=x2-x1 ;30-0=30
diffy=y2-y1 ;100-50=50
so we've moved 30 pixels on x and 50 on y. Very large increments. Too large. So we need to normalize the vector. To normalize a vector you divide the x and y vectors by the total distance between the points.
The distance formula is sqrt((diffx*diffx*)+(diffy*diffy))
Then you divide diffx and diffy by this value to get your x and y normalized vectors. If you increment along this normalized vector - you will stay on the line at all times. To move along the vector in larger increments - simply multiply by a scale factor.
Note that this is also a good way to 'shoot' bullets at another object.
You only need to normalize the vector once so it's not really expensive.
Here is an example that might be in game code for shooting bullets at players/objects. Not the best structure but hey I coded it while sitting here so gimme a break.
Code:
...
struct vector2D
{
double x;
double y;
};
struct Bullet
{
vector2D ScreenPos;
vector2D VelocityVector;
double Speed;
}
void Normalize(vector2D *Start,vector2D *End,vector2D *Result)
{
double diffx=Start->x-End->y;
double diffy=Start->y-End->y;
double dist=sqrt((diffx*diffx)+(diffy*diffy));
Result->x=diffx/dist;
Result->y=diffy/dist;
}
void ShootBulletAt(vector2D *Source,vector2D *Target,Bullet *NewBullet,double NewSpeed)
{
vector2D Result;
Normalize(Source,Target,&Result);
NewBullet->VelocityVector.x=Result->x;
NewBullet->VelocityVector.y=Result->y;
NewBullet->ScreenPos.x=(int)Source->x;
NewBullet->ScreenPos.y=(int)Source->y;
NewBullet->Speed=NewSpeed;
}
void UpdateBullet(Bullet *tBullet)
{
Bullet->ScreenPos.x+=(Bullet->VelocityVector.x*Bullet->Speed);
Bullet->ScreenPos.y+=(Bullet->VelocityVector.y*Bullet->Speed);
}
....
To show you what bilinear interpolation does code this - if you have a DOS compiler and a Win9X platform.
Code:
#include <dos.h>
#include <conio.h>
typedef unsigned char BYTE;
BYTE far *Screen;
#define XYTOMEM(x,y) ((y<<6)+(y<<8)+x)
void SetMode(void);
void Init(void);
void DrawTexture(void);
void FilterTexture(void);
double BI(double v1,double v2,double v3,double v4,double f1,double f2);
void SetMode(void)
{
asm {
mov ax,13h
int 10h
}
}
void Init(void)
{
Screen=(BYTE far *)MK_FP(0xa000,0);
asm {
push di
les di,[Screen]
mov cx,07D00h
mov ax,0
rep stosw
pop di
}
SetMode();
}
void DrawTexture
{
for (int i=0;i<50;i++)
{
for (int j=0;j<50;j++)
{
Screen[XYTOMEM(i,j)]=16+random(10);
}
}
}
void FilterTexture(void)
{
for (int i=0;i<50;i++)
{
for (int j=0;j<50;j++)
{
int i2=i+1;
if (i2>50) i2=0;
int j2=j+1;
if (j2>50) j2=0;
BYTE Pixel1=Screen[XYTOMEM(i,j)];
BYTE Pixel2=Screen[XYTOMEM(i2,j)];
BYTE Pixel3=Screen[XYTOMEM(i,j2)];
BYTE Pixel4=Screen[XYTOMEM(i2,j2)];
BYTE FilteredPixel=(BYTE)BI((double)Pixel1,(double)Pixel2,(double)Pixel3,(double)Pixel4,.5,.5);
Screen[XYTOMEM(i,j)]=FilteredPixel;
}
}
}
double BI(double v1,double v2,double v3,double f1,double f2)
{
double val1=0.0,fval=0.0;
asm {
fld [v2]
fsub [v1]
fmul [f1]
fadd [v1]
fstp [val1]
fld [v4]
fsub [v3]
fmul [f1]
fadd [v3]
fsub [val1]
fmul [f2]
fadd [val1]
fstp [fval]
}
return fval;
}
int main(void)
{
Init();
DrawTexture();
getch();
FilterTexture();
getch();
return(0);
}