0
\$\begingroup\$

I've created a 2d gradient shader which uses an absolute start/end point to determine how an arbitrary amount of colors are positioned along the gradient line. I now am creating an api to create a gradient with an angle to describe the direction the linear gradient gets drawn, and calculating the start/end points of the gradient based on that angle & the bounds of a quad. Running into an issue here finding those same start/end points which I'm struggling to solve..

problem

This is a visual of the problem I'm trying to solve. I need to determine x,y & x2, y2 based on any two (opposite) vectors. The vectors will always originate from the center of the rectangle, and can be in any direction (opposite of each other). Could also think of it as one line segment from x,y -> x2,y2. I've tried a trigonometry based approach here which almost kind of works but fails as the angle approaches the corner of the bounds. Hoping for a more clean solution using vector math which will be more efficient.

My initial thoughts are just to represent the rectangle as 4 axis-aligned line segments and attempt to calculate intersection that way, but struggling to figure out how to go about this.. I only have an angle right now that I'm using with the center point to calculate a unit vector in the proper direction. Any help appreciated!

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Imagine we're firing a bullet from E with velocity v. At some time t, the point E + v*t will hit the horizontal line joining A-B or the vertical line joining B-D (or their mirror images in the negative case). We want the earliest such intersection - the value of t closest to zero.

Since we know the distance the ray has to cross for each case, vertically and horizontally, and the speed expressed by v in each axis, we can find the time it takes to cross those gaps with two divisions:

float2 gap = B - E;
float2 hitTime = abs(gap/v);
// That's component-wise division:
// float2(gap.x/v.x, gap.y/v.y)

float t = min(hitTime.x, hitTime.y);

float2 intersection = E + v * t;
float2 otherIntersection = E - v * t;

(If v is a unit vector, then you can also think of t as the length we're travelling in direction v)

\$\endgroup\$
1
  • \$\begingroup\$ This is such a simple & elegant solution! I was tearing my hair out from this for hours. Thank you so much! It works perfectly!! And your explanation was great! :-) Yes the vector is a unit vector, so this is very precise! \$\endgroup\$ Commented Dec 8, 2022 at 3:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .