I figured it out. Basically the Normal has to be NORMALISED into a unit vector and then multiplied by the NormalVector as you have done above. Here's my code:
Works very nicely thanks. Try changing the coords of the line vector to whatever.
Hopefully this will prove useful to others. Now I have to apply it to my ball code and see if it works on corners, fingers crossed!
Strict Graphics 800,600,0 Global offsetX=400 Global offsetY=200 Global line:TVector = TVector.Create(100,200) Global linein:TVector = TVector.Create(100,50) Global lineout:TVector = linein.CreateCopy() lineout.rebound(line) Global Normal:TVector = line.CalcNormal() 'for display only While Not KeyHit(KEY_ESCAPE) Cls line.draw(offsetX,offsetY) SetColor 0,255,0 linein.draw(offsetX+line.x/2-linein.x,offsetY+line.y/2-linein.y) SetColor 0,0,255 lineout.draw(offsetX+line.x/2,offsetY+line.y/2) SetColor 255,255,255 normal.draw(offsetX+line.x/2,offsetY+line.y/2) Flip Wend Type TVector Field x! Field y! Function Create:TVector(x!,y!) Local v:TVector = New TVector v.x=x v.y=y Return v End Function Function CreateFromPoints:TVector(x!,y!,x2!,y2!) 'Point x2,y2 will be the end point so x,y is subtracted from it. 'This is useful for creating a Distance vector. Local v:TVector = New TVector v.x=x2-x v.y=y2-y Return v End Function Function CreateFromVectorsAdded:TVector(v1:TVector,v2:TVector) Local newv:TVector = v1.CreateCopy() newv.AddVector(v2) Return newv End Function Function CreateFromVectorScaled:TVector(v1:TVector, Multiplier:Double) Local newv:TVector = v1.CreateCopy() newv.Multiply(Multiplier) Return newv End Function Function CreateFromVectorsSubtracted:TVector(v1:TVector,v2:TVector) 'v2 will be the end point so v1 is subtracted from it. 'This is useful for creating a Distance vector. Local newv:TVector = v2.CreateCopy() newv.SubtractVector(v1) Return newv End Function Method AddVector(v:TVector) x:+v.x y:+v.y End Method Method CalcLength!() 'Calc the hypotenuese using the Pythagorean Formula. '(can also use square root of dot product of itself, which is the same formula) Return Sqr(x*x+y*y) End Method Method CalcNormal:TVector() 'Returns a right hand normal Local v:TVector = New TVector v.x = 0-y v.y = x Return v End Method Method CalcSlope!() 'Slope is change in y over change in x 'Warning, if x is 0 this will return infinite. Return y/x End Method Method CreateCopy:TVector() Local v:TVector = New TVector v.x=x v.y=y Return v End Method Method CopyFrom(source:TVector) x=source.x y=source.y End Method Method DotProduct!(v2:TVector) Return x*v2.x + y*v2.y End Method Method Draw(StartX!,StartY!,DrawLastPixel=True) DrawLine StartX,StartY,StartX+x,StartY+y,DrawLastPixel End Method Method Multiply(multiplier!) x:*multiplier y:*multiplier End Method Method Normalise() 'Nomalises x and y components into range -1 to 1 Local length!=CalcLength() x:/length y:/length End Method Method Rebound(Surface: TVector) 'Takes the current vector as the Old Direction and bounces 'it off of a surface vector using angle of incidence = angle of reflection rule 'First calc a normal to the surface. Local Normal:TVector = Surface.CalcNormal() 'Make the normal into a unit vector. Normal.Normalise() 'Now turn the normal vector into a projection vector. 'and subtract twice from the old direction (this vector) Local dot! = Normal.DotProduct(Self) Normal.Multiply(dot*2) Self.SubtractVector(Normal) End Method Method Reverse() x=0-x y=0-y End Method Method Rotate(angle!) 'clockwise Local tx# = (x * Cos(angle)) - (y * Sin(angle)) Local ty# = (x * Sin(angle)) + (y * Cos(angle)) x=tx y=ty End Method Method Scale(multiplier!) x:*multiplier y:*multiplier End Method Method SubtractVector(v:TVector) x:-v.x y:-v.y End Method End Type
Works very nicely thanks. Try changing the coords of the line vector to whatever.
Hopefully this will prove useful to others. Now I have to apply it to my ball code and see if it works on corners, fingers crossed!