PDA

View Full Version : Distance from a Point to a Line



Joe123
04-22-2008, 02:55 AM
Well, I wrote this for Gleeok, but I'm sure other people might want to make lasers or tripwires or something too, so I thought I'd post it here.

int DistancePointToLine(int x1,int y1,int x2,int y2,int distx,int disty){
int dx = x2-x1;
if(dx != 0){
int m = (y2-y1)/dx;
int c = y1 - m*x1;
return (Abs(-m*distx + disty - c))/Sqrt(m*m + 1);
}
else return Abs(distx-x1);
}


Pretty self explanitory, the inputs go:
(LineXcoord1,LineYcoord1)(LineXcoord2,LineYcoord2) (PointtomeausretoX,PointtomeasuretoY)

In that order.


Might not look so interesting, but don't be fooled!
Coupled with Screen->Line, it's actually quite fun =P


ffc script laser{
void run(){
int i;
int x1 = 128; int y1 = 0;
int x2 = 160; int y2 = 168;
while(true){
while(i<256){
Screen->Line(4,x1,y1,i,y2,Rand(120)+1,1,0,0,0,128);
if(DistancePointToLine(x1,y1,i,y2,Link->X+8, Link->Y+8) < 2) Game->PlaySound(36);
i+=2;
Waitframe();
}
while(i>0){
Screen->Line(4,x1,y1,i,y2,Rand(120)+1,1,0,0,0,128);
if(DistancePointToLine(x1,y1,i,y2,Link->X+8, Link->Y+8) < 2) Game->PlaySound(36);
i-=2;
Waitframe();
}
}
}
}

Here's a little example of how you might use it.
At the moment, it only plays a sound effect if Link gets hit.
But imagine what it could do!

C-Dawg
04-23-2008, 12:17 PM
Perfect. I was looking for something like this, but for some reason my math wasn't working properly. Good show.

Joe123
04-23-2008, 02:42 PM
Ah, glad to be able to help ^_^

Mine wasn't either, then I realised that when I had a vertical line I was dividing by 0.
So I added in that if else, and now it's fine.

Schwa
05-01-2008, 05:49 AM
So wait... This script detects if Link or an object is in between two fixed points? I mean it's awesome either way, but I'm just trying to get an idea of what it does...

And I would assume you can change these fixed points on the go, by setting the X and Y position of one of the points to the variable of another FFC and such...

Wow, nice and diverse. Diverse is good for this kinda stuff. =D

C-Dawg
05-01-2008, 08:39 AM
What?

No.

This script determines the shortest distance from the player to a given line on the screen. For instance, if the player is at (2,2), he or she would be 1 unit away from a line that passes through (1,1) and (3,1).

What this lets you do is, say, have an enemy fire a lazer using the draw function (LttP eye statutes, for example), check if the player is too close to the line, and if he or she is, damage the player.

Joe123
05-01-2008, 12:01 PM
Try copying the example script and the integer into a script file and sticking it on a screen.

Probably the best way to show.

Joe123
05-12-2008, 05:35 AM
And, if you still doubt the power of the distancepointtoline....


ffc script laser{
void run(int d,int w,int a){
int dx; int dy;
int m; int c;
int i; int j;
if(a==0) a=1;
if(d==0) d=4;
if(w==0) w = 4;

//this is the number of frames behind Link the laser is. Because we don't have variable arrays, if you want
//to change it, you have to change all 3 numbers here. Make them the same. Please.
int fb = 20;
int x[20]; int y[20];

x[0] = Link->X+8;
x[0] = Link->Y+8;
for(j=0;j<fb-1;j++){
for(i=fb-1;i>0;i--){
x[i] = x[i-1];
y[i] = y[i-1];
}
Waitframe();
}

npc e = Screen->LoadNPC(a);
j = 0;
while(e->isValid()){
if(j>0) j--;
x[0] = Link->X+8;
y[0] = Link->Y+8;
for(i=fb-1;i>0;i--){
x[i] = x[i-1];
y[i] = y[i-1];
}

dx = (e->X+8)-x[fb-1];
dy = (e->Y+8)-y[fb-1];
if(dx != 0){
m = dy/dx;
c = y[fb-1] - m*x[fb-1];
if(dy==0){
y[fb] = y[fb-1];
if(dx>0) x[fb] = 0;
else x[fb] = 256;
}else if(dy>0){
y[fb] = 0;
x[fb] = (y[fb]-c)/m;
}else{
y[fb] = 256;
x[fb] = (y[fb]-c)/m;
}
}else{
x[fb] = x[fb-1];
if(dy>0) y[fb] = 0;
else y[fb] = 168;
}

Screen->Line(2,e->X+8,e->Y+8,x[fb],y[fb],Rand(120)+1,1,0,0,0,128);
if(j==0){
if(DistancePointToLine(e->X+8,e->Y+8,x[fb],y[fb],Link->X+8,Link->Y+8) < 2 && Link->Z == 0){
Game->PlaySound(36);
Game->PlaySound(19);
Link->HP -= d;
}
j = w;
}
Waitframe();
}
}
}
D0: Damage of laser (default quarter heart)
D1: Number of frames to wait between taking damage from laser (default 4)
D2: Number of enemy on screen to give laser attack to (default 1)

Then have a go with this!

Put it on the screen with an enemy and POW!


It's quite fun really =D
I'd advise giving Link Roc's Feather though, otherwise he'll just get completely destroyed.



It's basically a laser coming from the first enemy on the list that follows where Link was 20 frames ago.
Pretty lethal =P

Also, if you want to edit how many 'frames ago' it attacks (so at the moment, it hits where Link was 20 frames ago. Say, you want it to hit where he was 5 frames ago maybe?) then I've noted up the places you have to change in the script.
If we had variable sized arrays, I could just make that into another argument variable, but seeing as we don't, I can't.