# HLSL problem - probably my maths

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

## Recommended Posts

Hello, I am trying to draw a line from two points using the GPU. If possible I would like someone just to check my maths in the IsPtOnLine function. I believe it should work as is however the line does not show up. Any help is greatly appreciated you can see the HLSL code below. Cheers, Hinchy.

float2 start = float2(100,400);
float2 end = float2(400,400);

//=====================================================
//
// From Wikipedia Search: dot product
//
// a.b = |a||b|cos(angle)
//
// becomes:
//
// angle = acos( a.b / |a||b| )
//
// normalizing a and b means:
//
// angle = acos( a.b )
//
//=====================================================
bool IsPtOnLine(float2 pt : TEXCOORD0)
{
bool val = false;
float2 dirStart2End = normalize(end-start);
float2 dirStart2Pt = normalize(pt-start);

float angle = acos( dot(dirStart2End,dirStart2Pt) );

// If angle between two directions is zero
// then pt lies on the start-end line therefore
// return true;
if(angle == 0.0f)
{
val = true;
}

return val;
}

//=====================================================
// This is a test to draw a line given two points the
// start and end.
//=====================================================
float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
{
const float4 ON_COLOUR = float4( 1,0,0,1 );
const float4 OFF_COLOUR = float4( 0,0,0,0 );

float4 val = OFF_COLOUR;
bool onLine = IsPtOnLine(texCoord);

// If the point is on the line colour it in
if(onLine)
{
val = ON_COLOUR;
}

return val;
}

##### Share on other sites
I don't really know how things work in HLSL, but under normal circumstances, the test as you've written it will rarely if ever return true due to floating-point imprecision.

In practice, you would use some sort of tolerance test for this, such as testing to see if the point is within a certain distance of the line. (In any case, I would recommend not using the 'angle' test, which is unnecessarily complicated and expensive.)

##### Share on other sites
Quote:
 Original post by jykI don't really know how things work in HLSL, but under normal circumstances, the test as you've written it will rarely if ever return true due to floating-point imprecision.In practice, you would use some sort of tolerance test for this, such as testing to see if the point is within a certain distance of the line. (In any case, I would recommend not using the 'angle' test, which is unnecessarily complicated and expensive.)

Hi,

I appreciate you getting back to me. tried playing with the if statement to accomodate the error:

// If angle between two directions is zero
// then pt lies on the start-end line therefore
// return true;
if(abs(angle) < 1.0f) // around 1.85 we start to get results
{
val = true;
}

Obviously this is not ideal and as jyk believes the angle test i am doing to be unnecessarily complicated if anyone can point me onto the right train of thought as to what maths i need to drive this I would appreciate it. Currently I think I may be getting bogged down in the belief that the dot product is needed to solve this problem. If anyone can think of a better solution to check if a texel lies on a line given two points a start and an end also in texture space please mention it.

Cheers,

Mark.

##### Share on other sites
Hi fanaticlatic,

I would be tempted to use a Closest Point on Line equation instead of a simple dot product test, as the dot product test doesn't take the end points into account, and you can't guarantee a consistent line width across the line.

To do this, use the following equation;

t = dot( pt - start, end - start) / dot(end-start,end-start)
(t is the percentage along the line that pt is nearest to)

if t < 0 or > 1 then ignore it as it's past the start or end point respectively. Otherwise, the distance to the line from pt will be the length of (pt - v), where v is;

v = start + (t * (end - start))
(v is the point on the line that pt is closest to)

You can then check this distance to see if it's close enough to draw, with the required test value affecting how wide your line is. There's prob a much more optimised way of doing this, but hope this gets you started!

##### Share on other sites
Quote:
 Original post by MattWhite06Hi fanaticlatic,I would be tempted to use a Closest Point on Line equation instead of a simple dot product test, as the dot product test doesn't take the end points into account, and you can't guarantee a consistent line width across the line.To do this, use the following equation;t = dot( pt - start, end - start) / dot(end-start,end-start)(t is the percentage along the line that pt is nearest to)if t < 0 or > 1 then ignore it as it's past the start or end point respectively. Otherwise, the distance to the line from pt will be the length of (pt - v), where v is;v = start + (t * (end - start)) (v is the point on the line that pt is closest to)You can then check this distance to see if it's close enough to draw, with the required test value affecting how wide your line is. There's prob a much more optimised way of doing this, but hope this gets you started!

Hi,

Thanks for the response.

I started with the solution you suggested MattWhite06 which I found from Real Time Collision Detection by Christer Ericson which I would recommend to everyone. But that didn't work???? So I changed to the angle test. I have now realised my stupid mistake, and why the closest point didn't work.

From OP:

float2 start = float2(100,400);

float2 end = float2(400,400);

note how I am storing the start and end points in screen space co-ords, but I am doing all my maths in the texture co-ordinate space D'OH!

Thanks for all the help folks, I'm off to hang my head in shame lol.

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
14
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633661
• Total Posts
3013226
×