Re: Sphere to rectangle
Fabian Giesen <[email protected]>
| Newsgroups | gmane.games.devel.algorithms |
|---|---|
| Message-ID | <[email protected]> |
Benjamin Rouveyrol wrote:
> Hi,
>
> The way I solved this (but a bit math heavy):
> If R is the light Radius and D the distance between the camera and the
> light:
> NewR = D * tan(asin(R/D))
>
> Then you compute Up and right vectors based on the camera and light
> positions (and the camera Up).
> You end up with 4 corners: LightCenter +|- Up * NewR +|- Right * NewR
>
>
> You can project them and this should give you your bounding rectangle.
> If someone has a simpler solution, I'd be most interested ^_^
Eric Lengyel explains one way to solve this on the last page of his "The
Mechanics of Robust Stencil Shadows" article:
http://www.gamasutra.com/view/feature/2942/the_mechanics_of_robust_stencil_.php?page=6
I derived an alternative method for some hobby project around 2004 that
is somewhat more straightforward. I don't have the original derivation
anymore, but I remember that it was fairly straightforward trig:
// Calculates bounding rectangle in normalized device coordinates for
// the view-space sphere with center "center" and radius "r". "zoom"
// contains the first two diagonal entries of your projection matrix
// (which is assumed to be perspective). You should do a rough rejection
// test of the sphere against the frustum first.
static void CalcSphereBounds(const Vector& center, float r, const float
zoom[2], float minb[2], float maxb[2])
{
// by default, assume that full screen covered
minb[0] = minb[1] = -1.0f;
maxb[0] = maxb[1] = 1.0f;
// once for x, once for y
for(int i=0;i<2;i++)
{
float x = center[i];
float z = center.z;
float ds = x*x + z*z;
float l = ds - r * r;
if(l > 0.0f)
{
float s,c;
l = sqrt(l);
s = x * l - z * r; // ds*sin(alpha)
c = x * r + z * l; // ds*cos(alpha)
if(z*ds > -r*s) // left/top intersection has positive z
minb[i] = max(-1.0f, s*zoom[i]/c);
s = z * r + x * l; // ds*sin(beta)
c = z * l - x * r; // ds*cos(beta)
if(z*ds > r*s) // right/bottom intersection has positive z
maxb[i] = min(1.0f, s*zoom[i]/c);
}
}
}
I'll try to re-derive this so as not to leave a bunch of unexplained
formulas standing in the room, but it's a relatively short solution and
it's worked fine for me, so I guess it's of interest.
Kind regards,
-Fabian
------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev
_______________________________________________
GDAlgorithms-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gdalgorithms-list
Archives:
http://sourceforge.net/mailarchive/forum.php?forum_name=gdalgorithms-list