# Question
Title: How to get the direction to the sky a pixel is facing to draw a sky?
I am drawing an empty texture over a framebuffer with a fragment shader active to try and draw a sky, but I need the direction each pixel is facing in (for correct linear perspective) to draw the right colours.

How can I calculate the direction vector for each fragment (pixel) from coords in the empty texture, aspect ratio, FOV, and camera orientation?

Other approaches I have tried have the sky misalign to the objects in the scene when rotating.

# Answer
The basic idea is that you can construct a vector representing a position in clip space, and then "unproject" it to get that position in "world space", then normalise that vector to get a direction. World space is in quotes because the camera is always at the origin in said "world space". Perhaps sky space would be a better term.

If you construct the unprojected vector in the vertex shader for each vertex of the empty texture you're drawing, and set a varying vec3 to it, you can then let the varying variable be interpolated and normalise it in the fragment shader, cutting out potentially hundreds of thousands of fragment shader matrix multiplications and only have them done for the corners of the screen.

The GLSL vertex shader code, where `VertexTexCoord.st` is the UV coords on the stretched empty texture being drawn (a `vec2`, so it fills both x and y in the `vec4` constructor) and `clipToSky` is the "unprojection matrix" explained below:

```
varying vec3 directionPreNormalise;

// ...

vec3 directionPreNormalise = (
    clipToSky * vec4(
        VertexTexCoord.st * 2.0 - 1.0,
        -1.0,
        1.0
    )
).xyz;

```

And then in the fragment shader, if you even need to normalise it:

```
vec3 direction = normalize(directionPreNormalise);

```

`VertexTexCoord`'s components are in the range 0 to 1, but we want them in the range -1 to 1, since that's what clip space has.

If you want to understand the effect of the z, and whether it should be -1.0 or 0.0 for you: The -1.0 z coordinate can be anything, and this still works. The XY-aligned plane in clip space based on your stretched texture is transformed into a (where XYZ are aligned with the view frustum) XY-aligned plane in the view frustum, and the Z coordinate of that output plane depends on the Z coordinate in clip space pre-transformation. The relationship is nonlinear. -1.0 corresponds to a position on the near plane\* (which I feel is non-arbitrary), **assuming your graphics API has clip space go from -1 to 1 on the z axis.** Having a z of -2.0 pre-transform also works for -1 to 1 clip spaces, so you should be OK to use whatever still, but 0.0 would more likely correspond to your near plane if you want something non-arbitrary (I haven't used an API like that). The XY-aligned plane in the view frustum grows as you increase the pre-transform z, "sliding along the edges of the view frustum", at such a rate that `direction` in the code above doesn't change with the pre-transform z.

\*Note that the use of `.xyz` with no division by the w coordinate means that `directionPreNormalise` is no longer a position on the near plane, but it all still works fine.

The 1.0 w coordinate is just for homogenous coordinates. Changing it appears to have a FOV-changing effect.

The "unprojection matrix" would be, in Lua code using my maths library:

`mat4.inverse(projectionMatrix * cameraMatrixStationary)`

Where `projectionMatrix` is the matrix that takes vectors from camera space to clip space (which is where FOV and aspect ratio come in) and `cameraMatrixStationary` is a world space -\> camera space matrix constructed from your camera orientation quaternion, **but the position is set to the origin.** If it is off the origin, the sky that gets rendered gets offset in a curious fashion.

Source for the research: I made a matrix visualiser and I used it to draw various wireframe graphics representing matrices, planes, the clip space cube, etc to see exactly what was going on. (It was originally intended for something else.)
> 0 votes

---
Tags: shaders, graphics, skybox, sky
---


# Question
Title: How do I target a tank turret with an offset barrel?
I have a tank model consisting of multiple parts, a body, a turret and the barrel of the gun. The turret is offset from the body origin and can rotate around the Y axis(up). The barrel is connected to the turret and can rotate around the X axis of its connecting point to the turret.

I was wondering, given a target in 3d space and the position of the tank, how to calculate the correct rotations to give to the parts in order for the barrel to align itself to fire at the target.

The position of the tank cannot change, only the rotations given to the turret and the barrel. I would know how to solve this if the barrel is aligned with the z axis of the turret but I am having difficulty solving this problem if parts are offset from each other. Eventually I want to expand this so that multiple joined parts can get the end part (firing point) facing a target. I am using XNA C#.

EDIT:

Below is an example of what I mean, a turret connected to the body at the blue point. The barrel is connected to the turret at the red point:

# Answer
*Terminology*

i call your "left/right rotation point of turret" joint "horizontal joint" and your "Up/down rotation point of barrel" joint "vertical joint".

Calculate with Forward kinematic (transformations leading to (previously unknown) orientation/position) the Position and Upvector and Forwardvector (this vector points from the horizontal joint forward).

*Inverse Part* After that use the Position and the Upvector and the Forwardvector to calculate the vertical and horizontal target rotations.

**Formulas for the inverse Part** of the case when the horizontal joint is directly on the vertical joint

(Pseudocode - untested)

```
// input
Vector3f UpVector; // upvector (normalized)
Vector3f ForwardVector; // (normalized)
Vector3f TargetPosition; // (absolute target position
Vector3f FKPosition; // forward kinematic Position of the turret
                     // is the absolute position in worldspace of the turret head

// temp
Vector3f SideVector; (normalized)

Vector3f TargetDiffUnnormalized; // difference to the target
Vector3f TargetDiff; // (normalized)

// output
float HorizontalRotationRawRad;
float VerticalRotationRawRad;

// calculation

// first we calculate the sidevector which is perpendicular to the up and ForwardVector
SideVector = UpVector.Cross(ForwardVector).normalized();

TargetDiffUnnormalized = TargetPosition - FKPosition;
TargetDiff = TargetDiffUnnormalized.normalize();

// we "project" the TargetDiff vector to the Plane which is described by the ForwardVector and SideVector

float ProjectedForward = ForwardVector.dot(TargetDiff)
float ProjectedSide    = SideVector.dot(TargetDiff)

// now we need to normalize the 2d Vector which is described by ProjectedForward and ProjectedSide because the length of it is not 1.0 and we would get wrong results

Vector2f ProjectedHorizontal = new Vector2f(ProjectedForward, ProjectedSide);
ProjectedHorizontal = ProjectedHorizontal.normalized();

// NOTE< here the components _could_ be wrong and the multiplication _could_ be wrong, depending on the direction of rotation and so on >
HorizontalRotationRawRad = acos(ProjectedHorizontal.Y);

if( ProjectedHorizontal.X < 0.0f )
{
   HorizontalRotationRawRad *= -1.0f;
}

//-----

Vector3f HorizontalDirection = ForwardVector.scale(ProjectedHorizontal.X) + SideVector.scale(ProjectedHorizontal.Y)

// NOTE< HorizontalDirection should be normalized, check if wanted with assertion to make sure >

VerticalRotationRawRad = acos(HorizontalDirection.dot(TargetDiff));

```

---

**Edit 1**

The math and code and the description for the case if the horizontal joint is not on the vertical joint (the more general case) follows here.

If you look at the 2d case from above (so to say on the plane of the horizontal joint in the 3d world) you notice that when you rotate your horizontal joint the vertical joint spins on a circle.

So now we search the rotation offset, because you need to add the rotation to the `HorizontalRotationRawRad` variable to get the real rotation.

To archive this you need to project the target point in the 3d space to the horizontal joint plane (you can archive this with the calculation of the intersection between the plane and a ray which starts at the target point and points in the direction of the normal of the plane).

I call this point you get as the result of the intersection `PlaneTarget`.

Now you can calculate the distance from `FKPosition` to `PlaneTarget` and i call it `c`.

For the following calculation you need to calculate only once on gameloading or on the construction time of the tank or whenever only the distance from the horizontal joint to the vertical joint and the angle of the two (from 90 to 180 degrees) and the side of the vertical joint.

To calculate the offset angle we use the law of cosines:

We know c and b and gamma and we search alpha.

after some math...

```
c² = a² +b² - 2ab cos(gamma)
rearanging->
c² = a² + b² - a * 2b cos(gamma)

this is a quadratic equation, solve it with some math or a solver which you wrote to get c

```

we know a, notice to catch the cases if the target is inside the circle (c \< b) because it wouldn't make much sense.

now we need to calculate the angle alpha with some more math...

```
a² = b² + c² - 2bc cos(alpha) | + 2bc cos(alpha) | - a²
2bc cos(alpha) = b² + c² - a²

alpha = acos(b² + c² - a² / 2bc)

```

now we can add/subtract alpha from/to VerticalRotationRawRad to get the correct angle for the horizontal joint.

The calculation of the vertical joint is a bit easier, use the angle of the horizontal joint to rotate the point of the vertical joint in worldspace.

Then just do a dot product between the normalized direction of the barrel and the difference to the target position (of course the result doesn't have a sign, if it should have one just use the horizontal plane and look if the target position is above or below it).
> 5 votes

# Answer
Here I am over 10 years later providing another answer, hopefully this will help someone.

If we look at the tank image below, we know we can calculate the angle A° pretty easily with atan2. Rotating the turret by this amount will point the turret itself at the target, however the barrel will still be shooting to the left of the target due to the offset.

```
A° = atan2(to_target.y, to_target.x);

```

The trick is to imagine extending the length of the barrel such that the tip of the barrel would touch the target if we rotated the turret to the correct position.

If R is the distance from the pivot point to the target, and O is the barrel offset, then X is some distance which is less than R which is the exact length required for our "extended barrel" to be able to touch the target after we've rotated, and these form a right triangle.

We can also see that the correct angle we need to rotate by is C°, and this is relatively straightforward to calculate once we know B, which is also simple trigonometry. So the full solution is:

```
R = length(to_target);
B° = acos(O / R);
C° = A° + (90° - B°);

```

We could also calculate the (90° - B°) directly sin asin() which is less intuitive but a little cleaner. So here is the copy-paste solution:

```
float aim_the_turret(float offset, vec2 to_target)
{
    // returns angle to aim turret to so that
    // barrel is pointed at the target
    return atan2(to_target.y, to_target.x)
      + asin(offset / length(to_target));
}

```

Note: when calculating the barrel offset O, we calculate just the lateral offset which is perpendicular to the forward direction of the turret. The intuitive explanation for this is that if we shift the position of the barrel forward or backward, it will still be aiming in the exact same direction. All that matters is the lateral offset from the pivot point.
> 2 votes

# Answer
I would try to do it like this:

```
Vector3 dir = target.pos - tank.pos;
dir.normalise();
RadianAngle turretYaw = acos(dir.x);
RadianAngle barrelPitch = asin(dir.y);

```

Now you just clear the turret and barrel rotations and apply these new. Not sure if it will work, but it's worth a try!
> 0 votes

# Answer
The up/down rotation of the barrel works like this:

*x* is the distance to the target and *y* is the difference in altitude to the target

You need to rotate the gun up by *alpha*, which is *atan2(y, x)*

This is in side view. In your 3D-world where *z* is pointing up, *x* would be *sqrt(xx + yy)* and *y* would be *z*.

If you don't know what *atan2* is, google it. It's the most helpful thing ever and C# has it too.

---

The left/right rotation of the turret works like this:

Your tank's gun is offset from the turret's origin by a vector *v* (red arrow).

So to hit your target, you need to rotate your turret by *beta* so that it (the *turret*, not the gun!) points at a spot that is offset from the target by *minus v* (green arrow). Makes sense? The rest is just basic trigonometry again (which I suck at, so use with caution).

---

Here's some pseudo-code that assumes that all the tank's component's positions are relative to their parents' (tank-\>turret-\>gun):

```
// first the turret's rotation:
vec3 absoluteTurretPosition = tank.position + turret.position;

vec3 pointToAimAt = target.position - gun.position;

vec3 delta = pointToAimAt - absoluteTurretPosition;

float desiredRotation = Math.Atan2(delta.x, delta.y);

turret.rotate(desiredRotation);

// now the gun's rotation:
vec3 absoluteGunPosition = absoluteTurretPosition + gun.position;

delta = target.position - absoluteGunPosition;

float x = Math.sqrt(delta.x * delta.x + delta.y * delta.y);

desiredRotation = Math.Atan2(x, delta.z);

gun.rotate(desiredRotation);

```
> 0 votes

---
Tags: 3d, xna-4.0, geometry
---


title: Get closest point on box to line

text:
# Question
Title: Get closest point on box to line
Eventually this problem will be 3D, so I would like a solution that works in 3D.

My player is looking forwards. There is an axis-aligned box on the screen (FOV is guaranteed to be 90, so boxes behind the player aren't considered.)

I want to get the coordinates of the point on box that is closest to the player's looking direction.

I.e., if the player turned towards the box, which point of the box would intersect with their line of vision first?

# Answer
> 3 votes
I wasn't happy with any of the answers here, as I wanted an answer for the 3D case, so I went ahead and wrote a shadertoy which demonstrates how to query the closest point between a line and a box.

Here's a link to the shadertoy code, as well as an image of the output:

Code:

```
// The MIT License
// Copyright © 2024 Nate Morrical
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// The below is a collection of functions to compute the closest point between
// a point / line / segment and a box / face.

// Returns the closest point from a 3D point to a 3D box
// The box is axis aligned, and centered at the origin
//   o - the query origin
//   b - the box radius (3 half side lengths)
vec3 pointBoxQuery( vec3 o, vec3 b ) {
    vec3 closest = o;
    for (int i = 0; i < 3; ++i) {
        if (o[i] < -b[i])
            closest[i] = -b[i];
        else if (o[i] > b[i])
            closest[i] = b[i];
    }
    return closest;
}

// Returns the closest point from an infinite 3D line to 3D box face, plus the closest "t" along o+t*d
// Based on https://www.geometrictools.com/Documentation/DistanceLine3Rectangle3.pdf
// The box is axis aligned, centered at the origin, and d is expected to point towards
// the first octant (reflected s.t. all d components are positive).
//   i - the indirection indices for the face
//   o - the origin of the segment
//   d - the direction along the segment (which does not need to be normalized)
//   b - the box radius (3 half side lengths)
vec4 lineFaceQuery(ivec3 i, vec3 o, vec3 d, vec3 b)
{
    vec3 PmE = o - b;
    vec3 PpE = o + b;

    vec3 bi = vec3(b[i[0]], b[i[1]], b[i[2]]);
    vec3 oi = vec3(o[i[0]], o[i[1]], o[i[2]]);
    vec3 di = vec3(d[i[0]], d[i[1]], d[i[2]]);
    vec3 PmEi = vec3(PmE[i[0]], PmE[i[1]], PmE[i[2]]);
    vec3 PpEi = vec3(PpE[i[0]], PpE[i[1]], PpE[i[2]]);

    vec4 c;
    if (di[0] * PpEi[1] >= di[1] * PmEi[0])
    {
        if (di[0] * PpEi[2] >= di[2] * PmEi[0])
        {
            // v[i1] >= -e[i1], v[i2] >= -e[i2] (distance = 0)
            c = vec4(bi[0], oi[1] - di[1] * PmEi[0] / di[0], oi[2] - di[2] * PmEi[0] / di[0], -PmEi[0] / di[0]);
        }
        else
        {
            // v[i1] >= -e[i1], v[i2] < -e[i2]
            float lenSqr = di[0] * di[0] + di[2] * di[2];
            float tmp = lenSqr * PpEi[1] - di[1] * (di[0] * PmEi[0] + di[2] * PpEi[2]);
            if (tmp <= 2. * lenSqr * bi[1])
            {
                float t = tmp / lenSqr;
                lenSqr += di[1] * di[1];
                tmp = PpEi[1] - t;
                float delta = di[0] * PmEi[0] + di[1] * tmp + di[2] * PpEi[2];
                c = vec4(bi[0], t - bi[1], -bi[2], -delta / lenSqr);
            }
            else
            {
                lenSqr += di[1] * di[1];
                float delta = di[0] * PmEi[0] + di[1] * PmEi[1] + di[2] * PpEi[2];
                c = vec4(bi[0], bi[1], -bi[2], -delta / lenSqr);
            }
        }
    }
    else
    {
        if (di[0] * PpEi[2] >= di[2] * PmEi[0])
        {
            // v[i1] < -e[i1], v[i2] >= -e[i2]
            float lenSqr = di[0] * di[0] + di[1] * di[1];
            float tmp = lenSqr * PpEi[2] - di[2] * (di[0] * PmEi[0] + di[1] * PpEi[1]);
            if (tmp <= 2. * lenSqr * bi[2])
            {
                float t = tmp / lenSqr;
                lenSqr += di[2] * di[2];
                tmp = PpEi[2] - t;
                float delta = di[0] * PmEi[0] + di[1] * PpEi[1] + di[2] * tmp;
                c = vec4(bi[0], -bi[1], t - bi[2], -delta / lenSqr);
            }
            else
            {
                lenSqr += di[2] * di[2];
                float delta = di[0] * PmEi[0] + di[1] * PpEi[1] + di[2] * PmEi[2];
                c = vec4(bi[0], -bi[1], bi[2], -delta / lenSqr);
            }
        }
        else
        {
            // v[i1] < -e[i1], v[i2] < -e[i2]
            float lenSqr = di[0] * di[0] + di[2] * di[2];
            float tmp = lenSqr * PpEi[1] - di[1] * (di[0] * PmEi[0] + di[2] * PpEi[2]);
            if (tmp >= 0.)
            {
                // v[i1]-edge is c
                if (tmp <= 2. * lenSqr * bi[1])
                {
                    float t = tmp / lenSqr;
                    lenSqr += di[1] * di[1];
                    tmp = PpEi[1] - t;
                    float delta = di[0] * PmEi[0] + di[1] * tmp + di[2] * PpEi[2];
                    c = vec4(bi[0], t - bi[1], -bi[2], -delta / lenSqr);
                }
                else
                {
                    lenSqr += di[1] * di[1];
                    float delta = di[0] * PmEi[0] + di[1] * PmEi[1] + di[2] * PpEi[2];
                    c = vec4(bi[0], bi[1], -bi[2], -delta / lenSqr);
                }
            }
            else {
                lenSqr = di[0] * di[0] +
                di[1] * di[1];
                tmp = lenSqr * PpEi[2] - di[2] * (di[0] * PmEi[0] + di[1] * PpEi[1]);
                if (tmp >= 0.)
                {
                    // v[i2]-edge is c
                    if (tmp <= 2. * lenSqr * bi[2])
                    {
                        float t = tmp / lenSqr;
                        lenSqr += di[2] * di[2];
                        tmp = PpEi[2] - t;
                        float delta = di[0] * PmEi[0] + di[1] * PpEi[1] + di[2] * tmp;
                        c = vec4(bi[0], -bi[1], t - bi[2], -delta / lenSqr);
                    }
                    else
                    {
                        lenSqr += di[2] * di[2];
                        float delta = di[0] * PmEi[0] + di[1] * PpEi[1] + di[2] * PmEi[2];
                        c = vec4(bi[0], -bi[1], bi[2], -delta / lenSqr);
                    }
                }
                else {
                    // (v[i1],v[i2])-corner is c
                    lenSqr += di[2] * di[2];
                    float delta = di[0] * PmEi[0] + di[1] * PpEi[1] + di[2] * PpEi[2];
                    c = vec4(bi[0], -bi[1], -bi[2], -delta / lenSqr);
                }
            }
        }
    }

    ivec3 map;
    map[i[0]] = 0;
    map[i[1]] = 1;
    map[i[2]] = 2;
    return vec4(c[map[0]], c[map[1]], c[map[2]], c.w);
}

// Returns the closest point from an infinite 3D line to a 3D box,  plus the closest "t" along o+t*d
//   o - the origin of the segment
//   d - the direction along the segment (which does not need to be normalized)
//   b - the box radius (3 half side lengths)
vec4 lineBoxQuery( vec3 o, vec3 d, vec3 b )
{
    vec4 closest;

    // Transform the line direction to the first octant using reflections.
    bvec3 reflected = lessThan(d, vec3(0.));
    o = mix(o, -o, reflected);
    d = mix(d, -d, reflected);

    // point minus extent
    vec3 PmE = o - b;

    // face indices
    ivec3 i;

    // line intersects planes x or z
    if (d[1] * PmE[0] >= d[0] * PmE[1])
        // line intersects x = e0 if true, z = e2 if false
        i = (d[2] * PmE[0] >= d[0] * PmE[2]) ? ivec3(0, 1, 2) : ivec3(2, 0, 1);
    // line intersects planes y or z
    else
        // line intersects y = e1 if true, z = e2 if false
        i = (d[2] * PmE[1] >= d[1] * PmE[2]) ? ivec3(1, 2, 0) : ivec3(2, 0, 1);

    // Query closest point on face
    closest = lineFaceQuery(i, o, d, b);

    // Account for previously applied reflections.
    closest.xyz = mix(closest.xyz, -closest.xyz, reflected);
    return closest;
}

// Returns the closest point from a finite 3D segment to a 3D box, plus the closest "t" along o+t*d
//   s - the start of the segment
//   e - the end of the segment
//   b - the box radius (3 half side lengths)
vec4 segmentBoxQuery( vec3 s, vec3 e, vec3 b ) {
    vec3 o = s;
    vec3 d = e - s;
    vec4 lbOutput = lineBoxQuery(o, d, b);
    // If closest is within the segment, return that result directly
    if (lbOutput.w >= 0. && lbOutput.w <= 1.)
        return lbOutput;

    // Otherwise, compute the closest point to either side of the segment
    float parameter = (lbOutput.w < 0.) ? 0. : 1.;
    vec3 pbOutput = pointBoxQuery(o + d * parameter, b);
    return vec4(pbOutput, parameter);
}

//------------------------------------------------------------

// https://iquilezles.org/articles/distfunctions
float sdBox( vec3 p, vec3 b )
{
    vec3 d = abs(p) - b;
    return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}

// https://iquilezles.org/articles/distfunctions
float sdSphere( vec3 p, vec3 cen, float rad )
{
    return length(p-cen)-rad;
}

// https://iquilezles.org/articles/distfunctions
float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
{
    vec3 pa = p-a, ba = b-a;
    float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
    return length( pa - ba*h ) - r;
}

// https://iquilezles.org/articles/distfunctions
float sdBoxFrame( vec3 p, vec3 b, float e )
{
       p = abs(p  )-b;
  vec3 q = abs(p+e)-e;

  return min(min(
      length(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),
      length(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),
      length(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));
}

// https://iquilezles.org/articles/distfunctions
float sdCone(vec3 p, vec3 a, vec3 b, float ra, float rb)
{
    float rba  = rb-ra;
    float baba = dot(b-a,b-a);
    float papa = dot(p-a,p-a);
    float paba = dot(p-a,b-a)/baba;

    float x = sqrt( papa - paba*paba*baba );

    float cax = max(0.0,x-((paba<0.5)?ra:rb));
    float cay = abs(paba-0.5)-0.5;

    float k = rba*rba + baba;
    float f = clamp( (rba*(x-ra)+paba*baba)/k, 0.0, 1.0 );

    float cbx = x-ra - f*rba;
    float cby = paba - f;

    float s = (cbx < 0.0 && cay < 0.0) ? -1.0 : 1.0;

    return s*sqrt( min(cax*cax + cay*cay*baba,
                       cbx*cbx + cby*cby*baba) );
}

//------------------------------------------------------------
const vec3 box_rad = vec3(0.5,0.4,0.3);

vec2 map( in vec3 pos, bool showBox, bool showCapsule, in vec3 sampleLineStart, in vec3 sampleLineStop )
{
    // compute closest point to the segment on the surace of the box
    vec4 result = segmentBoxQuery(sampleLineStart, sampleLineStop, box_rad );
    vec3 closestPointOnLine = mix(sampleLineStart, sampleLineStop, result.w);
    vec3 closestPointOnBox = result.xyz;

    vec2 res = vec2(1e38f);

    // query line
    {
    float d = sdCapsule( pos, sampleLineStart, sampleLineStop, 0.015 );
    if( d<res.x ) res =  vec2( d, 1.0 );
    }

    // closest point on line
    {
    float d = sdSphere( pos, closestPointOnLine, 0.06 );
    if( d<res.x ) res = vec2( d, 1.0 );
    }

    // Closest point on box
    {
    float d = sdSphere( pos, closestPointOnBox, 0.06 );
    if( d<res.x ) res = vec2( d, 4.0 );
    }

    // box (semi-transparent)
    if( showBox )
    {
    float d = sdBox( pos, box_rad );
    if( d<res.x ) res =  vec2( d, 5.0 );
    }

    // segment from line to box
    {
    float d = sdCapsule( pos, closestPointOnLine, closestPointOnBox, 0.015 );
    if( d<res.x ) res =  vec2( d, 4.0 );
    }

    // box edges
    {
    float d = sdBoxFrame( pos, box_rad, 0.01 );
    if( d<res.x ) res =  vec2( d, 5.0 );
    }

    // Capsule demonstrating correctness.
    if (showCapsule){
    float radius = distance(closestPointOnBox, closestPointOnLine);
    float d = sdCapsule( pos, sampleLineStart, sampleLineStop, radius );
    if( d<res.x ) res =  vec2( d, 1.0 );
    }

    return res;
}

// https://iquilezles.org/articles/normalsSDF
vec3 calcNormal( in vec3 pos, in bool showBox, in bool showCapsule, in vec3 sampleLineStart, in vec3 sampleLineStop )
{
    vec2 e = vec2(1.0,-1.0)*0.5773;
    const float eps = 0.0005;
    return normalize( e.xyy*map( pos + e.xyy*eps, showBox, showCapsule, sampleLineStart, sampleLineStop ).x +
                      e.yyx*map( pos + e.yyx*eps, showBox, showCapsule, sampleLineStart, sampleLineStop ).x +
                      e.yxy*map( pos + e.yxy*eps, showBox, showCapsule, sampleLineStart, sampleLineStop ).x +
                      e.xxx*map( pos + e.xxx*eps, showBox, showCapsule, sampleLineStart, sampleLineStop ).x );
}

// https://iquilezles.org/articles/rmshadows
float calcSoftShadow( vec3 ro, vec3 rd, bool showBox, bool showCapsule, in vec3 sampleLineStart, in vec3 sampleLineStop )
{
    float res = 1.0;
    const float tmax = 2.0;
    float t = 0.001;
    for( int i=0; i<64; i++ )
    {
        float h = map(ro + t*rd, showBox, showCapsule, sampleLineStart, sampleLineStop).x;
        res = min( res, 64.0*h/t );
        t += clamp(h, 0.01,0.5);
        if( res<-1.0 || t>tmax ) break;

    }
    res = max(res,-1.0);
    return 0.25*(1.0+res)*(1.0+res)*(2.0-res); // smoothstep, in [-1,1]
}

#if HW_PERFORMANCE==0
#define AA 1
#else
#define AA 2
#endif

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec3 tot = vec3(0.0);
    #if AA>1
    for( int m=0; m<AA; m++ )
    for( int n=0; n<AA; n++ )
    {
        // pixel coordinates
        vec2 o = vec2(float(m),float(n)) / float(AA) - 0.5;
        vec2 p = (2.0*(fragCoord+o)-iResolution.xy)/iResolution.y;
        // pixel sample
        ivec2 samp = ivec2(fragCoord)*AA + ivec2(m,n);
        // time sample
        float td = 0.5+0.5*sin(fragCoord.x*114.0)*sin(fragCoord.y*211.1);
        float time = iTime - 0.5*(1.0/60.0)*(td+float(m*AA+n))/float(AA*AA-1);
        #else
        // pixel coordinates
        vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y;
        // pixel sample
        ivec2 samp = ivec2(fragCoord);
        // time sample
        float time = iTime;
        #endif

        // animate camera
        float an = 0.25*time + 6.283185*iMouse.x/iResolution.x;
        vec3 ro = vec3( 2.4*cos(an), 0.7, 2.4*sin(an) );
        vec3 ta = vec3( 0.0, -0.15, 0.0 );

        // camera matrix
        vec3 ww = normalize( ta - ro );
        vec3 uu = normalize( cross(ww,vec3(0.2,1.0,0.0) ) );
        vec3 vv = normalize( cross(uu,ww));

        // animate query line
        vec3 sampleLineStart = -sin(time*0.5*vec3(1.0,1.1,1.2)+vec3(4.0,2.0,1.0));
        vec3 sampleLineStop  = -cos(time*0.5*vec3(1.0,1.1,1.2)+vec3(4.0,2.0,1.0));

        // make box transparent
        bool showBox = ((samp.x+samp.y)&1)==0;     // 50% opaque
        bool showCapsule = ((samp.x+samp.y+1)&1)==0;

        // create view ray
        vec3 rd = normalize( p.x*uu + p.y*vv + 1.5*ww );

        // raycast
        const float tmax = 5.0;
        float t = 0.0;
        float m = -1.0;
        for( int i=0; i<256; i++ )
        {
            vec3 pos = ro + t*rd;
            vec2 hm = map(pos,showBox,showCapsule,sampleLineStart, sampleLineStop);
            m = hm.y;
            if( hm.x<0.0001 || t>tmax ) break;
            t += hm.x;
        }

        // shade background
        vec3 col = vec3(0.05)*(1.0-0.2*length(p));

        // shade objects
        if( t<tmax )
        {
            // geometry
            vec3  pos = ro + t*rd;
            vec3  nor = calcNormal(pos,showBox,showCapsule,sampleLineStart, sampleLineStop);

            // color
            vec3  mate = 0.55 + 0.45*cos( m + vec3(0.0,1.0,1.5) );

            // show distance isolines on box
            if( abs(m-5.0)<0.5 )
            {
                vec4 result = segmentBoxQuery(sampleLineStart, sampleLineStop, box_rad);
                vec3 closestPointOnLine = mix(sampleLineStart, sampleLineStop, result.w);
                vec3 closestPointOnBox = result.xyz;

                float dref = sdBox( closestPointOnLine, box_rad );
                float dsam = length(pos-closestPointOnLine);
                mate += smoothstep(0.8,0.9,sin((dsam-dref)*80.0))*exp2(-12.0*(dsam-dref)*(dsam-dref));
            }
            // Show distance isolines on open capsule
            if( abs(m-1.0)<0.6 )
            {
                vec4 result = segmentBoxQuery(sampleLineStart, sampleLineStop, box_rad);
                vec3 closestPointOnLine = mix(sampleLineStart, sampleLineStop, result.w);
                vec3 closestPointOnBox = result.xyz;

                float dref = sdCapsule( closestPointOnBox, sampleLineStart, sampleLineStop, .1 );
                float dsam = length(pos-closestPointOnBox);
                mate += smoothstep(0.8,0.9,sin((dsam-dref)*80.0))*exp2(-12.0*(dsam-dref)*(dsam-dref));
            }

            // lighting
            col = vec3(0.0);
            {
              // key light
              vec3  lig = normalize(vec3(0.3,0.7,0.2));
              float dif = clamp( dot(nor,lig), 0.0, 1.0 );
              if( dif>0.001 ) dif *= calcSoftShadow(pos+nor*0.001,lig,showBox,showCapsule,sampleLineStart,sampleLineStop);
              col += mate*vec3(1.0,0.9,0.8)*dif;
            }
            {
              // dome light
              float dif = 0.5 + 0.5*nor.y;
              col += mate*vec3(0.2,0.3,0.4)*dif;
            }
        }

        // gamma
        col = pow( col, vec3(0.4545) );
        tot += col;
    #if AA>1
    }
    tot /= float(AA*AA);
    #endif

    // cheap dithering
    tot += sin(fragCoord.x*114.0)*sin(fragCoord.y*211.1)/512.0;

    fragColor = vec4( tot, 1.0 );
}

```

I believe the implementation is relatively optimized, although it's a bit branchy... (Suggestions are welcome :)). The relevant implementation would be 'segmentBoxQuery'

The idea is to compute the distance from the line to only the closest box face. We first transform the box such that its origin is at 0, then to represent the box through its extents relative to 0. Then to make determining which face is closest to the segment, we reflect the direction of the segment to fall into the first octant (and reflect back once we have the closest point).

From there, we determine which box face to test against by doing a couple line-plane intersection tests.

For querying the closest point on the plane, we break up the test into 9 cases, as explained in greater depth here):

> **Table 3**. The regions of the partitioning. Each table entry contains the region name, the algebraic constraints defining the region, the rectangle point closest to \\$P = C + x\_0U\_0 + x\_1U\_1 + x\_2U\_2\\$ and the squared distance from the rectangle to \\$P\\$.

$$\small \begin{array}{c|c|c} \begin{array}{c} R\_{−+}, x\_0 \< −e\_0, x\_1 \> e\_1 \\ C − e\_0U\_0 + e\_1U\_1 \\ (x\_0 + e\_0)^2 + (x\_1 − e\_1)^2 + x^2\_2 \end{array} & \begin{array}{c} R\_{0+}, |x\_0| ≤ e\_0, x\_1 \> e\_1 \\ C + x\_0U\_0 + e\_1U\_1 \\ (x\_1 − e\_1)^2 + x^2\_2 \end{array} & \begin{array}{c} R\_{++}, x\_0 \> e\_0, x\_1 \> e\_1 \\ C + e\_0U\_0 + e\_1U\_1 \\ (x\_0 - e\_0)^2 + (x\_1 − e\_1)^2 + x^2\_2 \end{array} \\\hline \begin{array}{c} R\_{−0}, x\_0 \< −e\_0, |x\_1| ≤ e\_1 \\ C − e\_0U\_0 + x\_1U\_1 \\ (x\_0 + e\_0)^2 + x^2\_2 \end{array} & \begin{array}{c} R\_{00}, |x\_0| ≤ e\_0, |x\_1| ≤ e\_1 \\ C + x\_0U\_0 + x\_1U\_1 \\ x^2\_2 \end{array} & \begin{array}{c} R\_{+0}, x\_0 \> e\_0, |x\_1| ≤ e\_1 \\ C + e\_0U\_0 + x\_1U\_1 \\ (x\_0 - e\_0)^2 + x^2\_2 \end{array} \\\hline \begin{array}{c} R\_{−-}, x\_0 \< −e\_0, x\_1 \< -e\_1 \\ C − e\_0U\_0 - e\_1U\_1 \\ (x\_0 + e\_0)^2 + (x\_1 + e\_1)^2 + x^2\_2 \end{array} & \begin{array}{c} R\_{0-}, |x\_0| ≤ e\_0, x\_1 \< -e\_1 \\ C + x\_0U\_0 - e\_1U\_1 \\ (x\_1 + e\_1)^2 + x^2\_2 \end{array} & \begin{array}{c} R\_{+-}, x\_0 \> e\_0, x\_1 \< -e\_1 \\ C + e\_0U\_0 - e\_1U\_1 \\ (x\_0 - e\_0)^2 + (x\_1 + e\_1)^2 + x^2\_2 \end{array} \end{array} $$

# Answer
> 2 votes
You could decompose that test into four separate tests:

For each edge **AB**, **BC**, **CD**, **DA** in the box **ABCD**, determine the distance to the ray. The closest of all four tests is your solution.

For the edge vs ray test, you could do segment-vs-segment, and just pretend the ray is a really long segment.

I found this 2D segment vs segment test that you can use for this.

Note that if multiple edges have distance 0 to the ray, you need to compute the actual intersections, and pick the one closest to the ray origin.

# Answer
> 0 votes
**2D Solution**

This is pretty easy if you divide this into two cases: line intersects object, and line doesn't intersect.

For the intersect case, as you've shown it's just a matter of finding the intersection closest to the viewer - something I assume won't be that hard to figure out.

And for the case of no intersection, a bit of illustrated rotation can help show how this can be figured out easily...

First, here is the scenario with your image...

Now rotate it so that your view vector is zero degrees and the viewer is at the origin (0,0)...

Now, all you have to do is find the corner with the smallest absolute value Y coordinate, and that is your intersection point.

There is one edge case (literally) where the view vector is parallel to an edge, and two points are equally close. I'm guessing for your requirements, you would choose the furthest from the viewer. Here's an illustration...

**3D Solution**

The concept is somewhat similar with 3D as follows...

First, if the line intersects the 3D shape, then choose the point of intersection as your answer.

If the line does not intersect, then you must find the point that is closest to your view line. Since you have stated that you are only solving this for rectangular solids (meaning there are only 12 edge vectors), I would probably just brute force calculate the closest distance from each edge vector to the view vector, and choose the smallest one, and the coordinate of that closest point. Rather than explain it here, I'll point to a Mathematics stack post that discusses finding the shortest distance between lines - https://math.stackexchange.com/questions/2213165/find-shortest-distance-between-lines-in-3d. There are probably other solutions online to be found.

# Answer
> 0 votes
First thing to note is that you only need to consider corners. The player will almost always see a corner of the box before an edge. In the rare cases where the alignment is just right, the player will see an edge and a corner at the same time (because every edge obviously contains corners). So it's enough to only consider corners.

The problem can be solved with linear algebra easily in 2-D, the generalisation to 3-D needs a bit more maths but nothing particularly advanced. The basic algorithm is:

1) From the position of the player and the angle of the line, create a linear equation y = m\*x + c which defines the line.

2) The minimum distance between a point and a line is given by the length of a line segment perpendicular to the original line which reaches the point. So, from y = m\*x + c construct a unit vector u perpendicular to it.

3) For each corner of rectangle p, find the value t such that p + t*u lies on y = m*x + c.

4) If all the t's are the same sign, it means that you are on the same side of all the corners. The distance to the rectangle is therefore min(abs(t)), and the corner you will see first is the one which gave that t. If some of the t's are positive and some negative, that means that you are clockwise of some corners and anticlockwise of others, and are therefore inside the rectangle.

**EDIT**: I did the maths on the back of an envelope. The value of \\$t\\$ is $$ t = \cos(\theta) (p\_y-y\_0) - \sin(\theta)(p\_x-x\_0) $$

Where \\$(x\_0, y\_0)\\$ is the coordinate of the player, \\$\theta\\$ is the angle from the horizontal \\$+x\\$ axis (measured by the direction towards the \\$+y\\$ axis) and \\$(p\_x, p\_y)\\$ is the coordinate of a corner. This is a shockingly simple result, if I was you I would redo the maths just to double check, it's only 6 or 7 lines of algebra.

The extension in 3-D depends on how the viewer works. Is the vision of the player a wedge or a cone?

---
Tags: mathematics, geometry, raycasting
---


# Question
Title: To fix an item duplication glitch, I created an item deletion glitch
* The item type is based on `button.icon.texture`
* The item quantity is based on `button.quantity`
* If item quantity reaches 0, the `icon.texture` is set to empty.png. There's also the option to set it to null, so I made an elif statment just in case I need to use null.

The problem:

When adding items of the same type together, they stack, which is good. But when adding items of different types, they swap. Technically only the texture swaps, the quantities don't... the quantity is zeroed out and thus the texture is set to empty.png.

Removing this:

```
elif quantity == 0:
        quantity_label.text = ""
        icon.texture = preload("res://UI/graphics/SkillIcons/empty.png")
        print("zeroed out")

```

shows that in fact the textures are being swapped correctly, but the quantity isn't.

```
extends TextureButton

var DRAG_PREVIEW = preload("res://Sprite.tscn")
onready var icon = $Icon
onready var quantity_label = $Quantity

var quantity = rand_range(0, 25)
var item = "null"

func _ready():
    displayQuantity()
    matchItemTypeToIcon()

func _physics_process(delta):
    displayQuantity()

func displayQuantity():
    if quantity != 0:
        quantity_label.text = str(round(quantity))
    elif quantity == 0:
        quantity_label.text = ""
        icon.texture = preload("res://UI/graphics/SkillIcons/empty.png")
        print("zeroed out")

func get_drag_data(position: Vector2):
    matchItemTypeToIcon()

    var slot = get_parent().get_name()
    var data = {
        "origin_node": self,
        "origin_slot": slot,
        "origin_texture": icon.texture,
        "origin_quantity": quantity,
        "origin_item": item
    }
    var dragPreview = DRAG_PREVIEW.instance()
    dragPreview.texture = icon.texture
    add_child(dragPreview)

    # Remove the icon from its original place
    icon.texture = preload("res://UI/graphics/SkillIcons/empty.png")
    quantity = 0
    displayQuantity()
    print("Item type:", item)
    return data

func can_drop_data(position, data):
    matchItemTypeToIcon()
    var target_slot = get_parent().get_name()
    data["target_texture"] = icon.texture
    data["target_quantity"] = quantity
    data["target_item"] = item
    return true

func drop_data(position, data):
    matchItemTypeToIcon()
    displayQuantity()
    var origin_texture = data["origin_texture"]
    var target_texture = icon.texture
    var origin_item = data["origin_item"]
    var target_item = item
    var origin_quantity = data["origin_quantity"]
    var target_quantity = quantity

    data["origin_node"].get_node("Icon").texture = target_texture
    icon.texture = origin_texture

    if origin_item == target_item:
        # Only combine the quantities if target_texture and origin_texture are the same
        quantity += data["origin_quantity"]

        data["origin_node"].get_node("Icon").texture = preload("res://UI/graphics/SkillIcons/empty.png")
    else:
        # Swap the quantities if the textures are different
        quantity = origin_quantity
        data["origin_quantity"] = target_quantity

func matchItemTypeToIcon():
    var icon_texture = icon.texture
    if icon_texture == preload("res://UI/graphics/mushrooms/PNG/background/1.png"):
        item = "mushroom 1"
    elif icon_texture == preload("res://UI/graphics/mushrooms/PNG/background/2.png"):
        item = "mushroom 2"
    elif icon_texture == null:
        item = "empty"
    elif icon_texture == preload("res://UI/graphics/SkillIcons/empty.png"):
        item = "empty"
    else:
        # Default item type if the texture doesn't match known types
        item = "unknown"

```

# Answer
> 0 votes
fixed the problem by storing quantities in a temporary variable at temp\_quantity

here's the full edited script

```
 extends TextureButton

var DRAG_PREVIEW = preload("res://Sprite.tscn")
onready var icon = $Icon
onready var quantity_label = $Quantity

var quantity = rand_range(0, 25)
var item = "null"
var type = "item"
func _ready():
    displayQuantity()
    matchItemTypeToIcon()

func _physics_process(delta):
    displayQuantity()

func displayQuantity():
    if quantity != 0:
        quantity_label.text = str(round(quantity))
    elif quantity == 0:
        quantity_label.text = ""
        icon.texture = null
        print("zeroed out")

    if icon.texture == null:
        quantity = 0
        quantity_label.text = ""

func get_drag_data(position: Vector2):
    matchItemTypeToIcon()

    var slot = get_parent().get_name()
    var data = {
        "origin_node": self,
        "origin_slot": slot,
        "origin_texture": icon.texture,
        "origin_quantity": quantity,
        "origin_item": item,
        "type": type
    }
    var dragPreview = DRAG_PREVIEW.instance()
    dragPreview.texture = icon.texture
    add_child(dragPreview)

    # Remove the icon from its original place
    #icon.texture = null
    #quantity = 0
    displayQuantity()
    print("Item type:", item)
    return data

func can_drop_data(position, data):
    matchItemTypeToIcon()
    displayQuantity()
    var target_slot = get_parent().get_name()
    data["target_texture"] = icon.texture
    data["target_quantity"] = quantity
    data["target_item"] = item
    if data["type"] != "skill":
        return true
    else:
        return false

func drop_data(position, data):
    matchItemTypeToIcon()
    displayQuantity()
    var origin_texture = data["origin_texture"]
    var target_texture = icon.texture
    var origin_item = data["origin_item"]
    var target_item = item
    var origin_quantity = data["origin_quantity"]
    var target_quantity = quantity
    var origin_node = data["origin_node"]
    var origin_icon = origin_node.get_node("Icon")

    origin_icon.texture = target_texture
    icon.texture = origin_texture

    if origin_item == target_item:
        # Combine quantities if items are the same
        quantity += data["origin_quantity"]
        origin_node.quantity = 0  # Reset the origin quantity
    else:
        # Swap quantities if items are different
        var temp_quantity = quantity
        quantity = origin_quantity
        origin_node.quantity = temp_quantity

    # Update the display
    displayQuantity()

func matchItemTypeToIcon():
    var texture_to_item = {
        preload("res://UI/graphics/mushrooms/PNG/background/1.png"): "mushroom 1",
        preload("res://UI/graphics/mushrooms/PNG/background/2.png"): "mushroom 2",
        preload("res://UI/graphics/SkillIcons/empty.png"): "empty"
    }

    if icon.texture in texture_to_item:
        item = texture_to_item[icon.texture]
    elif icon.texture == null:
        item = "empty"
    else:
        item = "unknown"

```

The entire system is based off godot's **built in** drag and drop functionaly, better explained in this video : https://www.youtube.com/watch?v=IaAqhIC5DaI&ab\_channel=Artindi

---
Tags: gui, godot-3, inventory
---


# Question
Title: How to tell when calculating an Intercept Point between two moving objects, when it will never intercept?
I'm not a maths person and the formulas you see on maths type questions/answer with all the symbols is completely beyond me - I'm sorry. However I had help about 18 months ago to turn a provided formula into lua script to make the calculation for two aircraft to intercept each other. I will admit, I don't know why that formula works, and I wouldn't know how to change it to make it do other things; I need to get this working for a flight sim project, but learning all the maths for this one problem would take too long and I have no-one who could teach me. (I don't learn well from books). Please be understanding and not too critical of my lack of maths skills.

The premise is one aircraft will maintain it's course (target) and the other (interceptor) will alter it's course to intercept with the target aircraft at some point in the future.

The formula/code I made for that is this (It was based on a simulation page tutorial on calculating lead shots for firing a bullet in an FPS and where it will hit a moving target - obviously that works in an FPS as you intend to only shoot when pointing at a target, but here there is a non-negligible chance of the player asking for an intercept that could never happen):

```
    -- Point intercept(Point const &shooter, double bullet_speed, Point const &target, Vector const &target_velocity)
    -- {
    --     double a = bullet_speed*bullet_speed - target_velocity.dot(target_velocity);
    --     double b = -2*target_velocity.dot(target-shooter);
    --     double c = -(target-shooter).dot(target-shooter);

    --     return target+largest_root_of_quadratic_equation(a,b,c)*target_velocity;
    -- }

  local targetMINUSInterceptor   = TVF.VecSubtract(interceptorVec3Point, targetVec3Point)
  local targetVelocityDotProduct = TVF.VecDot(targetVelocityAsVec3, targetVelocityAsVec3)

  local a = interceptorSpeedAsNumber * interceptorSpeedAsNumber - targetVelocityDotProduct
  local b = -2 * TVF.VecDot(targetVelocityAsVec3, targetMINUSInterceptor)
  local c = -TVF.VecDot(targetMINUSInterceptor, targetMINUSInterceptor)

  local result = TVF.VecAdd(targetVec3Point, (TVF.MultiplyVectorByNumber(targetVelocityAsVec3, TVF.GetLargestRootOfQuadraticEquation(a,b,c))))

```

Now, that all works perfectly, but only IF both aircraft are travelling in directions and speeds that CAN intercept (even with required turns for the Interceptor).

However, if you have, for example, the target aircraft heading West, and East of that target you have the Interceptor aircraft heading East (i.e. moving away from each other and already are tail to tail to each other), and allowing for the fact that the interceptor can't go fast enough to catch up and overtake the target aircraft, then the above calculation/formula still gives a position vector, however it's either 'off the map' or in some weird direction and massive magnitude that makes no practical sense.

I need to know when this calculation (or a modified version of it) gives a DEFINITE interception point, and also when it CANNOT give an interception point.

This will allow me to make a branching decision in my code to warn the players when an interception is not possible and the target aircraft would have to change it's direction and/or speed and try again.

Could someone please help? My maths level is very basic trig, so I'd really appreciate it if you could spell it out for me or give me the corrected formula with explanations words for all the terms please.

**EDIT: In response to the great answer below, I wanted to add this.**

This is the quadratic equation I'm using to calculate the intercept point.

```
function TVF.GetLargestRootOfQuadraticEquation(A, B, C) -- A, B, C are all doubles (floats)

  return (B + math.sqrt(B * B - 4 * A * C)) / ( 2 * A)

end

```

I notice that the only difference I can see between my quadratic and the answer below is that mine starts with a positive b and the answer below starts with a negative b.

The thing that confuses me about this, is that if it's possible for the two aircraft to intercept, my maths/code calculates it correctly.

It just gives a weird answer when they definitely can't.

This is confusing. After testing, if I change B to -B at the start, then the 'intercept point' doesn't work anymore and the point it thinks it's going to is way 'off the map' - just like when using that same equation on an interceptor that can't intercept.

So is it just that if the result is \< 0 then it can't intercept and if it's \> 0 it can?

# Answer
From your description of the behaviour it sounds like your quadratic equation solver is breaking down. $$\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$ For example, if a is 0 (which will happen if the interceptor speed is the same as the target speed) then applying the quadratic formula will result in a divide by zero.

Or, if a is positive (which will happen if the interceptor speed is smaller than the target speed) then the term \\$b^2 - 4ac\\$ might also be negative. And if that happens, then the result of the square root will be an imaginary number.

I have a solution that doesn't use the quadratic formula. Instead it uses basic trig to give you the angle you need to pursue. I have explained it here: https://github.com/LSBUSGP/AimAhead

If you can get an intercept direction vector \\$Iv\\$ (it's possible that you can't if you are going slower than the target) you can dot it with the target motion vector \\$Tv\\$ to see if travelling at your speed \\$Is\\$ you will catch the target.

If \\$Tv \cdot Iv \< Is\\$ you will intercept. Note you need to be careful with the lengths of these vectors. I am assuming the length of \\$Tv\\$ to be the speed of the target, whereas the length of \\$Iv\\$ is 1. Alternatively, if they are both movement vectors with lengths corresponding to their speeds then you can compare against the square of the speed of the interceptor: \\$Tv \cdot Iv \< Is^2\\$.
> 1 votes

---
Tags: vector, linear-algebra, intersection
---


# Question
Title: Using D&D maps as a reference for my indie game
I've been considering using existing D&D battle maps for a commercial indie game I'm developing. I will use them as reference: I will create the same layout with my own assets.

I want to ensure that this practice is respectful to the original creators and the community.

Could you advise on the ethical implications and best practices for this approach?

# Answer
I would personally start with maps that are specifically intended for commercial use. For instance:

Sticking to these resources is likely your safest route - there's no moral ambiguity or creative legal interpretation. That said, read the licensing information carefully; some may have attribution requirements.

And as mentioned in the comments, in some cases you might be able to contact the cartographers directly. The WotC books list cartographers on the credits page that precedes the table of contents.
> 3 votes

---
Tags: legal, level-design, copyright, intellectual-property
---


title: Decal render layer not working

text:
# Question
Title: Decal render layer not working
I’m projecting a pee decal on hydrant but its reflecting also on player body. Tried to set decal render layers on projector and meshes but it doesn’t change anything.

Here is a few pictures of my configs. Am I doing something wrong?

# Answer
Solved by re-installing and re-configuring URP renderer from scratch.
> 0 votes

---
Tags: unity
---


# Question
Title: 1px Font size too big for pixel art game - how to deal with this?
I have a pixel art kinda game that I'm building in Godot. I'm a newbie to both game dev and art. I have 32px high character sprites, with objects and the world scaled to be proportionate to those characters. The debug game window is set to 1080p, with Stretch properties of mode:viewport, aspect:expand, scale:5, scale mode:fractional. When using any text labels in the game, with a font size set to 1px, they still appear WAY too big.

In terms of design, how do I deal with this? Are my characters and objects too small?

# Answer
> 1 votes
As suggested by @Theraot, I used a secondary viewport implementation with the following steps.

Created a new scene, added a SubViewportContainer that held a SubViewport. On this SubViewport I set the appropriate scale and stretch properties that I wanted for my game level scene. I then added the game level scene under the SubViewport.

For any UI elements where I wanted the smaller and more crisp text, I added those UI elements to a CanvasLayer under the root of the new scene so it would be used in the primary viewport, outside of the SubViewportContainer.

I then set the scale property on the primary viewport to 1 (compared to SubViewportContainer Scale of 5) to achieve the scaling I wanted.

---
Tags: godot, godot-4
---


# Question
Title: Mirroring a Character's Position In a Shadow After Rotating 180 Degrees
**Description:**

I am creating a 2.5D RPG.

When my character moves from left to right, they rotate 180 degrees to face the new direction. Just like this example.

They also have a blob shadow sprite that follows their X position.

It's rotated 90 degrees in the X-axis to lay flat underneath them.

---

**Goal:**

Because my character is asymmetrical, I came up with the idea of having their shadow extend the same distance past each foot.

(In the example below, each foot is 18 pixels from the edge of the shadow)

This way, even if the character was rotated 180 degrees and the shadow did not move, they would look exactly the same but mirrored. The example below is exactly what I want.

---

**Issue:**

My problem is that once my character rotates 180 degrees, they're positioned very differently on their shadow. Which makes sense due to their asymmetrical shape. I believe the issue here is the origin/pivot point being used to rotate the character.

---

**What I've Tried:**

To resolve this I tried creating a parent object for my character's sprite. That way I could set an offset in the X-axis to sort of "fake" changing the pivot point.

The Hierarchy looks like this:

Though, it still doesn't look good and is far from precise because I'm just making rough estimates of how much of an offset to use. Is there a formula that can be used to figure this out?

If I'm going about this the wrong way, I am completely open to a different way of achieving this.

# Answer
> 1 votes
Cache the shadow's authored horizontal offset from the sprite either at edit time or on spawn:

```
Start() {
    shadowOffset = shadowTransform.position.x - spriteTransform.position.x;
}

```

Each frame during a rotation, apply that offset or its mirror image, according to the rotation of the sprite:

```
void Update() {
    // 1x for 0°, -1x for 180°, smoothly varying in between.
    float side = Mathf.Cos(rotationAngle * Mathf.Deg2Rad);

    var shadowPosition = shadowTransform.position;
    shadowPosition.x = spriteTransform.position.x + side * shadowOffset;
    shadowTransform.position = shadowPosition;
}

```

This assumes your shadow's pivot is in its center, which shouldn't be too onerous.

---

If you'd rather keep the shadow in-place and rotate the character inside it:

1. Create a new empty child under the shadow. Ensure it's centered on the shadow. Call this "Pivot Parent".
2. Drag this parent out from under the shadow, to be a sibling to the character's body object in the transform hierarchy. Set its z depth to the same as the character body's.
3. Drag the character into this parent object. Unity will by default adjust its local position inside the parent to maintain its world position unchanged.
4. Change any scripts that rotate the character body to rotate "Pivot Parent" instead. Since you arranged it to have its pivot point centered on the shadow, this will keep the character in the right relationship as it rotates, even if it's shifted off-center to some degree. If the shadow was following the character body in a script, change it to follow the pivot parent instead.

---
Tags: unity, mathematics, graphics
---


# Question
Title: Game Physics Engine : Euler integration : why body under gravity is not covering 9.8 meters/second?
I am working on very basic physics engine and I used euler interation which works like below,

```
acceleration = GRAVITY; //9.8 m/s
velocity += acceleration * deltaTime;
position += velocity * deltaTime;

```

but when I calculate how much distance (in meters) it covers in a second. Its less than 9.8 m/s (around 5 meters). Please help me understand what's wrong in this euler integration.

Thanks.

# Answer
> 1 votes
the speed of the object after 1 second will be 9.81 m/s.

However it starts at 0 and increases to 9.81 m/s. So all that time in that first second the speed of the object is less than 9.81.

---
Tags: physics, physics-engine, integration, euler-method
---


title: Creating a pinch distortion shader

text:
# Question
Title: Creating a pinch distortion shader
I'm attempting to recreate this effect using a shader in Unity, using version 2023 with HDRP:

The effect appears to be pinching pixels behind the object the shader is applied to and dragging them towards the center like this:

Below is an attempt to create a transparent distortion using the twirl node in a shader graph as a first step:

The result is very jagged, I suspect this might be because the Normal from Height texture is very pixelated. I did try to reduce the strength of the effect but then the effect became too minimal to notice. You can see below the shader is breaking the lines in the background:

I'd appreciate any advice on how to implement this effect. I'm currently using the twirl node as a start because I don't quite understand how to implement this pinching distortion effect yet. I'm new to shaders, so perhaps I'm using the wrong method for this kind of effect?

I've also posted this question on the offcial Unity forums here but did not receive any replies.

# Answer
You could do something like this:

Where you use the difference between the UV coordinates of the fragment and (0.5, 0.5) as the offset, but flippling the magnitude so it is strongest at the center and 0 at the edge.
> 2 votes

---
Tags: shaders, unity-shader-graph
---


title: Path3d Offset from GlobalPosition

text:
# Question
Title: Path3d Offset from GlobalPosition
my path3d node is several meters away from the global position.My transform are not changed from their base setting.    Code:

```
 [Export]
 Node3D Start { get; set; }
 [Export]
 Node3D End { get; set; }
 [Export]
 float LineRadius = 0.1f;
 [Export]
 int LineResolution = 8;
 [Export]
 CsgPolygon3D Polygon3D;
 int ArrayLenght;
 [Export]
 Path3D LinePath;
 bool Update;
 [Export]
 bool test;
 public override void _Ready()//use pathfollow to over the player over the path:) //end and start point get more twisted the heavier the player is
 {
     base._Ready();

     var count = LinePath.Curve.PointCount;
     if(Start != null)
     {
         LinePath.Curve.SetPointPosition(0, Start.GlobalPosition);
         GD.Print("Setting First Point to Point 1 Position");
     }
     if(End != null)
     {
         LinePath.Curve.SetPointPosition(count-1, End.GlobalPosition);
         GD.Print("Setting the Last point to Point 2 Position");
     }
     MeshUpdate();

 }
 public override void _Process(double delta)
 {
     base._Process(delta);
     if (Update == true)
     {
         MeshUpdate();
         Update= false;
     }

     if (test == true)
     {
         Update = true;
         test = false;
     }
 }
 public void MeshUpdate()
 {
     var cirle = new Vector2[LineResolution];

     for (int i = 0; i < LineResolution; i++)//circle is empty
     {
         float X = LineRadius * Mathf.Sin((Mathf.Pi * 2 * i) / LineResolution);
         float Y = LineRadius * Mathf.Cos((Mathf.Pi * 2 * i) / LineResolution);
         Vector2 coords = new Vector2(X, Y);
         cirle[i] = coords;

     }
     Polygon3D.Polygon = cirle;
     if(Start!=null && End != null)
     {
         UpdateOrientation();
     }
 }
 public void OnPathChanged()
 {
     Update = true;
 }
 public void UpdateOrientation()
 {
     Vector3 direction=Start.GlobalPosition- End.GlobalPosition;
     Vector3 linePosition = Start.GlobalPosition + (direction / 2);
     direction = direction.Normalized();
     Basis LineBasis = GlobalBasis;
     LineBasis.Z = direction;
     LineBasis.Y = direction.Cross(LineBasis.X);
     LineBasis.X = direction.Cross(LineBasis.Y);
     GlobalBasis = LineBasis;

 }

```

# Answer
The problem was that the curve3d got their position from another scene which is why it presented itself in another position.There is no way to fix this as this is just visual and does not effect the game. if it bothers you,remove the tool line.
> 0 votes

---
Tags: godot, 3d-meshes, path
---


# Question
Title: How hard to brake to perfectly smoothly reach the destination?
# Goal

I want the get the required minimum deceleration to perfectly smoothly reach a target.

(The car's AI should know how hard it has to brake to be the perfect valet.)

# Research

# Conditions

* Solution can be 1D or 2D
* There is no friction
* There is an object `o` (e.g. car) and a target `t` (e.g. parking spot)
* Inclusion of object's mass would be nice to have
* The target is static and at a known distance `d`
* The object has a current known velocity `v`
* Brake strength is infinite
* No lerping, it should be (somewhat) physically accurate (I later want to add overshoot, impulses, etc.)

# Question

What would be the formula to know how hard you had to brake right now to exactly reach 0 velocity at the target?

# Answer
> 13 votes
When an object brakes with a constant deceleration, then its velocity over time looks like this:

Distance traveled is velocity multiplied with time. So the orange area in the graph above actually represents the distance traveled. And the area of a right triangle is half that of a square with the same width and height. So:

$$ distance = (velocity * time) / 2 $$

And the time it takes to get from the current velocity to 0 is the velocity divided by the deceleration, so:

$$ distance = (velocity * velocity / deceleration) / 2 $$

But we know the distance and need the deceleration. So we need to rearrange the formula:

$$ distance * deceleration = (velocity * velocity ) / 2 $$ $$ deceleration = (velocity * velocity ) / ( 2 * distance ) $$

There you have it.

However, this formula assumes that you are using a physics engine that is able to model acceleration by integration. Some physics engines unfortunately just assume that velocities are constant during physics ticks and then changes the velocity between ticks. So in reality the deceleration curve in your engine might actually look like this:

The math still *mostly* works out over the long term, but can lead to inaccurate results in the short-term. Especially when the engine operates on a variable tick-rate. So if you are using a physics engine that works like that, you might receive results that are "good enough" but not perfectly accurate.

# Answer
> 3 votes
This is a methodology I adopted when designing an automated model train system where the train had to stop at a signal. The physics is much the same as Philipp explains, although I took a slightly different tack to what he describes.

The relevant equation I used was a rearrangement of

`distance=(velocity∗velocity/deceleration)/2`

Which can be rearranged to give:

`velocity*velocity = 2 * distance * deceleration`

or

`velocity = sqrt(2 * distance * deceleration)`

Obviously, you would set this as an upper bound; if your vehicle is travelling less than the target speed (ie a long way from the target), then the vehicle maintains its speed.

Each time I updated the velocity of the train (about 8 times per second) I used that formula to calculate the speed it should be. Since you are allowing acceleration to be infinite, you simply change the velocity by the necessary amount, up to infinity. Any inaccuracies are corrected for in subsequent update steps, so it should converge quite well.

I found this gave a reasonable smooth and realistic-looking stop.

# Answer
> 3 votes
# The simpler approach, but still somewhat smooth

By approximation, we could create such a braking curve and this would work for a kind of "smooth" braking:

$$ f(t) = \begin{cases} 2t-2, &t \ge \frac{1}{2} \\ -2t, &t \< \frac{1}{2} \end{cases} $$

The disadvantage here is that at the kinks \\$(0, 0.5, 1)\\$ there will be some noticeable not-"smooth"-ness and braking will not be really "smooth"... but it will be almost perfect.

This would be the acceleration with the velocity plotted:

The area of the acceleration for \\$t \in \[0,1\]\\$ is easily calculated with the following expression:

$$ v(t) = \frac{cos(\pi t)}{2} - \frac{1}{2} $$

But for the purposes of calculating the maximum deceleration, we know that the "area" (velocity \\$v\\$) here is equal to \\$-1\\$ (this function will "remove" this much velocity).

This means that we can just input the velocity as the amplitude when we brake in stop time \\$t\_{stop}\\$.

#### When the physics engine works by simulating acceleration/deceleration (probably?)

$$ f(t, t\_{stop}, v\_0) = \begin{cases} k \cdot v\_0 \cdot \left(2 \frac{t}{t\_{stop}}-2 \right), &\frac{t}{t\_{stop}} \ge \frac{1}{2} \\ k \cdot v\_0 \cdot \left(-2 \frac{t}{t\_{stop}} \right), &\frac{t}{t\_{stop}} \< \frac{1}{2} \end{cases} $$

where \\$v\_0\\$ is the initial velocity and \\$k\\$ is some factor.

#### When the physics engine works by simulating the velocity, not the change in speed

$$ v(t, t\_{stop}, v\_0) = v\_0 + v\_0 \cdot \left(\frac{cos \left(\pi \frac{t}{t\_{stop}} \right)}{2} - \frac{1}{2} \right) $$

But this will result in jerk, as the "kink" in the graph means the derivative is discontinuous:

# The difficult approach, but smooth

If we want smooth braking, I would advise such an acceleration/deceleration curve:

It's not important to know, but this curve consists of three parts (left, middle, right):

$$ f(t) = \begin{cases} \frac{-cos(\pi t)}{\pi} + \frac{1}{\pi}, &t \in \[0,1) \qquad(1) \\ \frac{-2cos(\pi t)}{\pi}, &t \in \[1,2) \qquad(2) \\ \frac{-cos\pi}{\pi} - \frac{1}{\pi}, &t \in \[2,3) \qquad(3) \\ \end{cases} $$

The identified requirements from these three parts start with the first and last parts and consist of:

1. The requirement is a smooth jerkless start.
2. Any kinks in this acceleration/deceleration pattern would introduce jerk.
3. The function must keep decreasing the slope when nearing the zero points.

The middle part is there to just connect the motion into one whole jerkless movement. This would require another chapter in this answer (brake from positive acceleration). For now, I will focus on braking (decelerating) when the acceleration is zero already.

To make this go smoothly, the wanted deceleration curve would approximate this:

It's not important, but the formula used here is

$$f(t) = \frac{-cos(\pi (2t-1))}{\pi} - \frac{1}{\pi}$$

as a basis, to normalize the braking from \\$0\\$ to \\$1\\$.

The information we have is:

* The distance \\$d\\$.
* The current speed \\$v\\$.

And the question that we have is: what are the parameters (time, amplitude) of the deceleration function, so that the interpolation of that function, equals the speed?

To make this question easier, let's assume that the deceleration curve is calculated, and saved, at one point in time, and is not recalculated.

To make this even easier, let's assign one variable already: time (in how much time we want to stop, stop\_time).

Let us just calculate the time from:

$$t\_{stop} = \frac{d}{v}$$

We already normalized the brake function for \\$t \in \[0,1\]\\$, so we need to divide \\$t\\$ by the stop time \\$t\_{stop}\\$ to get the curve that fits within the wanted stop time:

$$ f(t, t\_{stop}) = \frac{-cos\left(\pi \left(2\left(\frac{t}{stop\\\_time}\right)-1\right)\right)}{\pi}-\frac{1}{\pi} $$

A car that is going faster obviously needs a higher braking force to stop the same distance (i.e. remove "more" velocity).

To calculate the velocity this function would "remove" we take the integral (from Wolfram Alpha):

$$ \int f(t, t\_{stop}) = -\frac{2\left(\frac{t}{2}-\frac{t\_{stop} \cdot sin\left(\frac{2 \pi t}{t\_{stop}}\right)}{4 \pi}\right)}{\pi} $$

Now, how much velocity does this function remove in total for \\$\frac{t}{t\_{stop}} = 1\\$?

We can see it's around \\$\frac{1}{3}\\$. Solving it numerically yields \\$-\frac{1}{\pi}\\$

That's how much velocity this deceleration function is able to remove, so this is our factor for the initial velocity.

# For an engine that is velocity-based (already simplified)

$$ v(t, t\_{stop}, v\_0) = v\_0 + v\_0 \cdot \left(-2\left(\frac{t}{2}-\frac{t\_{stop} \cdot sin\left(\frac{2 \pi t}{t\_{stop}}\right)}{4 \pi}\right)\right) $$

Resulting in:

for a stop time \\$t\_{stop}\\$ of `1.0` and initial velocity `10.0`.

---

In all formulas, \\$t\\$ would then be supplied as the time since braking started, and the result can be split into the corresponding `x`, `y`, and `z` components according to the normalized speed vectors of your moving object.

---
Tags: physics, mathematics, movement, ai
---


# Question
Title: Why are Quaternions better than Euler-Angles for Godot (when to use which)?
Sorry about the click-bait, I know there are many many reasons why Quaternions and Bases are better than using Euler-Angles. Anyone on a 5 second google search could easily know why!

But I am trying my hardest to use Quaternions, and most the time I love them! They are a dream! But in specific instances like I am having now, I keep wondering "Are there times I can use Euler-Angles over Quaternions?".

I set up the logic for the rotation of a compass in the UI two ways. One way with Euler-Angles that took just a second and is short, and the other way with Quaternions that took me a while longer to set-up because I kept having problems with the discontinuity of interpolation angles. And so the compass would jump from `160` to `-160` instead of going from `160 -> 180 -> -160` (the interpolation was taking the long way around).

I would like you to take a look at the code, and tell me if this would be a time that using semi-Euler's is better than Quaternions, or if the way I set up my Quaternion rotations is in-efficient or needlessly complex! I am really trying my hardest to use Quaternions and Bases for everything because I see their benefits!

P.S.: I still get the jumping between `160` and `-160` degrees, any help there would be appreciated.

**EULER-ANGLES:**

```
float compassAngle = Vector3.Forward.SignedAngleTo(playerCamera.GlobalTransform.Basis.X, Vector3.Up);
compassInst.Rotation = new Vector3(0, compassAngle, 0);

```

**QUATERNIONS/BASES:**

Quaternion forwardRot = new Quaternion(Vector3.Forward, 0.0f).Normalized();
Quaternion playerCamRot = playerCamera.GlobalTransform.Basis.GetRotationQuaternion().Normalized();

if(playerCamRot.Dot(forwardRot) < 0){
    forwardRot = -forwardRot;
}

Quaternion targertRotComp = playerCamRot.Slerp(forwardRot, 0.1f);

compassInst.GlobalTransform = new Transform3D(new Basis (targertRotComp), compassInst.GlobalTransform.Origin);
```

# Answer
**Simple rule:** If you're only rotating on one axis, use Euler angles.

If you're using multiple axes, then the decision is a bit less simple.

---

Assuming your Euler code is correct, then I think that code doesn't work because it's using Slerp incorrectly. That function gives you a value between two rotations, but you don't want an intermediate rotation. You just want the target rotation.

I think the correct quaternion solution would be to transform the quat from player space into UI space (`Vector3.Forward.SignedAngleTo(...)` is doing a similar transformation for Euler). Likely something that uses operator\*:

> Composes these two quaternions by multiplying them together. This has the effect of rotating the second quaternion (the child) by the first quaternion (the parent).

Possibly something like `compassInst.GlobalTransform = Basis.FLIP_Z * playerCamera.GlobalTransform.Basis.GetQuaternion()` but I'm not certain what rotation you should rotate by the camera rotation.
> 0 votes

# Answer
I only suggest doing euler angles for an first person camera, where your pitch is clamped and your roll is always zero. You keep the pitch and header separately and combine them every frame. (Though I would recommend to keep them as sin/cos pairs instead of actual angles so you never have to deal with the wrapping point for the heading).

You get the long way around because the quaternions you were interpolating between were nearly a full turn apart. Each 3D orientation has 2 possible quaternions that can represent it (sometimes called double cover). If you always want the shortest (in 3D) rotation between objects then you will need to check the dot product between the quaternions and if it is negative (meaning the orientations are more than half a turn apart) you negate one of the quaternions.
> 0 votes

---
Tags: c#, rotation, quaternion, godot-4, euler-angles
---


title: How do Entity Component Systems work?

text:
# Question
Title: How do Entity Component Systems work?
In the project I am working on, I recently ran into a problem of software architecture:

I created a base entity class that displays a world object. Then I added functionality for the entity to have a visible piece of text attached to it.

That text is part and its supporting variables are part of the entity class. And the render class asks for these variables during the rendering part of the gameloop to render the text.

Got all of that to work. Then I started writing a derived class of the entity class to have an entity that only needs the text stuff.

That is where I started wondering whether it is better to have a text class to be entirely separate from the entity class, because there are situations where I have text that is always there with entities and sometimes I only need text without entities, however the code is almost the same.

Then I read about entity component systems. And I don't get how they work on a high level. How does the "attaching" of components work in the code?

# Answer
> 0 votes
What you've described, where each piece of behaviour is coded directly into the entity class or a derived subclass of entity, is *not* an Entity Component System. That's just a regular inheritance hierarchy.

Those are fine for some games, especially when the number of different "kinds" of entity you need to support is small and well-defined.

But this type of inheritance hierarchy can easily get into a combinatoric explosion as the number of variations of things in your game increases, and it can be brittle to modify. A level designer who wants a new combination of behaviours for a one-off puzzle/encounter needs to wait on a programmer to make a subclass with that behaviour, or needs to use a class with a superset of all the behaviour they want plus some stuff they don't (maybe they just need a time countdown but no text, but everything deriving from entity has memory/processing cycles devoted to updating this blank text anyway). And when you want an object that combines behaviours from two disparate branches of the inheritance tree, you either need to duplicate code, move it to a point closer to the root (where it will be inherited by a lot of objects that don't need it), or use complicated "multiple inheritance" strategies that make code harder to reason about.

Component-based solutions aim to avoid these problems using the principle of "composition over inheritance". Instead of baking behaviours into the specific subclass a given entity "is", we build behaviours into modular components that an entity can "have".

A simple example of this concept is to define a base `Component` class with a virtual method like `Update(Entity me, float deltaTime)`, then implement subclasses for each modular behaviour you might want to give an entity, like a `TextRenderer` component that stores and renders text.

The `Entity` class then becomes a barebones container, holding a vector of `Component` instances "attached to" that entity. When updating the entity, you iterate that collection of components and call `Update(this, deltaTime)` on each.

The `Entity` class can expose a public interface including `AddComponent` / `RemoveComponent` / `GetComponentOfType` methods to attach, detach, or address components it has. You can build new permutations of behaviour on the fly by plugging-together different modular component types, without defining a new subclass that implements all those behaviours in one type.

A good example of this strategy can be found in the Unity engine, where `GameObject` is a general-purpose "entity" that holds a list of `Component` instances. You could try downloading Unity and working through a few tutorials to get a sense of what it's like working with this kind of system, what kinds of behaviour it makes sense to separate into component types, and how the code structure looks. That way you can see how you like this before you commit to the effort of building your own implementation from scratch.

This would normally not be called an "entity component system" because the component types include both data and code to process that data themselves. In an ECS, components are often "plain old data structures", and the behaviour is separated into "systems" that iterate over all entities with a set of components matching some specific signature.

In some such implementations, "entity" ceases to exist as its own data type or object at all. Instead, you end up with big buffers of component data, linked by index, where the transform component at index 5 of the transform buffer, the renderer component at index 5 of the renderer buffer, etc. are all understood to be "owned by" "entity number 5". The entity becomes implicit in the data layout, rather than needing its own separate memory.

This is a data-oriented ECS using structure-of-arrays storage, and it lets system code like a "text rendering system" process batches of matching components very efficiently. It's useful when you want to process thousands of game entities as efficiently as possible, by making the data layout and execution order very cache-friendly and convenient to parallelize across worker threads.

Unity's new DOTS (Data Oriented Technology Stack) works this way, if you want to use that as a testing ground to see how you like this style.

As you can probably tell from the description above, it's more abstract and tricky to reason about this data-oriented version for someone new to the concept, and takes some more complex engineering to support. So if you don't need to squeeze absolute maximum throughput from your chips, you can probably afford to use the conceptually simpler version for starters, to get used to coding in terms of modular components. Then you can profile it and evaluate whether you really need the performance edge that a data-oriented refactor can bring.

---
Tags: c++, entity-component-system
---


title: Graphics2D.drawImage not working

text:
# Question
Title: Graphics2D.drawImage not working
I'm trying to come up with my own game using Java AWT after watching a few video tutorials. However, I encountered a problem where I cannot draw an external image file that I loaded using the BufferedImage object.

The problem seems to be on the method that I'm using to draw the image on the screen, where I'm using *Graphics2D.drawImage()* method to draw.

---

Here is part of my code (I modified and skipped parts that seemed irrelevant to the topic):

**Window Class**

```
public class Window extends JPanel{
    public Window(int width, int height) {
        JFrame frame = new JFrame("Zerro's Game");

        frame.setPreferredSize(new Dimension(width, height));

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);
        frame.pack();
    }
}

```

**Game Class**

```
public class Game extends JFrame implements Runnable {
    // Dimension for Main Frame
    private static final int WIDTH = 640;
    private static final int HEIGHT = 480;

    // Image
    private BufferedImage image;
    private Graphics2D g;

    public void run() {
        this.requestFocus();

        // For rendering purposes
        image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        g = (Graphics2D) image.getGraphics();

        //Game Loop
        long now;
        long updateTime;
        long wait;

        final int TARGET_FPS = 60;
        final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;

        while (isRunning) {
            now = System.nanoTime();

            update();
            render();

            updateTime = now - System.nanoTime();
            wait = (OPTIMAL_TIME - updateTime) / 1000000;

            try {
                Thread.sleep(wait);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void render() {
        if(gameState == STATE.GAME) {
            handler.render(g);
        } else if(gameState == STATE.MENU) {
            menu.render(g);
        }
    }

```

**Menu Class**

```
public class Menu extends KeyAdapter{
    private BufferedImage image;

    public void render(Graphics2D g) {
        try {
            image = ImageIO.read(getClass().getResource("/Pixel_Background.png"));
            g.drawImage(image, 0, 0, null);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

```

---

This code results in making empty frame without any content inside. I confirmed that it properly loads an image by using *System.out.println(image.getHeight())* which prints out the exact height of an image that I'm using.

I've seen some comments in the internet that I need to use paintComponent() method. However, I'm just wondering if it's not a good idea to use paintComponent() in game development as the video tutorials (3 of them) that I watched didn't use such method to draw images.

Also, I'm wondering about the reason why we pass in the Graphics2D object as parameter in all the render() methods.

# Answer
> 0 votes
You never actually draw the image you draw the loaded image on onto the screen. The data won't get magically transferred to the screen. That's why people use the paintComponent method, it provides you with the graphics component of the panel.

Also, when you're learning a language, it's not the best idea to jump into gamedev with it, since most tutorials won't teach you the basics you need to know (like OO programming). Some background knowledge would answer your question about passing the graphics object to other methods. If you don't pass it, then you simply can't use it.

# Answer
> 0 votes
You may need to add the game to the JFrame. New code: Window.java:

```
public class Window extends JPanel{
    public Window(int width, int height, Game game) {
        JFrame frame = new JFrame("Zerro's Game");

        frame.setPreferredSize(new Dimension(width, height));

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.pack();
        frame.add(game);
        frame.setVisible(true);
    }
}

```

then just add the word "this" as an input (not a string just the word without quotes) to wherever you're making the window

# Answer
> 0 votes
Both existing answers point us to the solution because

1. You are rendering to BufferedImage you created. That does not automatically show on screen, it is just image in memory. As @Bálint pointed out
2. Even if you used graphics of the Game you are not showing this JFrame, instead creating new JFrame in Window class. As @BigmancozmoPlayz pointed out

Since Game class is already JFrame, we do not need to create a new JFrame. For simplicity I also removed Window (since JFrame can be shown by itself). I also called Game.run() method.

```
public class GameLauncher {

    public static final int WIDTH = 640;
    public static final int HEIGHT = 480;

    public static void main(String[] args) throws HeadlessException, IOException {
        Game frame = new Game();
        frame.setTitle("Zerro's Game");
        frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);
        frame.pack();
        frame.run();
    }
}

```

Then to the rendering part. We do not know when window is really painted to screen (it would be waste of resources to paint UI all the time) so we need to ask for it to be repainted and do our painting in overriden paint method:

```
private BufferedImage buffer = new BufferedImage(GameLauncher.WIDTH, GameLauncher.HEIGHT, BufferedImage.TYPE_INT_RGB);
private Graphics bufferGraphics = buffer.getGraphics();

...

update();
render();
repaint();

...

@Override
public void paint(Graphics g) {
    g.drawImage(buffer, 0, 0, null);
}

```

Here we are using buffer image because you want to separate painting from showing it and I believe your tutorials meant to do so. (Reaslistically you need at least two buffers/images, one where result is being prepared and one with result ready to be shown, to prevent showing incomplete rendering result)

And now we need to render what we want to buffer (it is wise for image to be already loaded):

```
private void render(){
    bufferGraphics.drawImage(image, 0, 0, null);
    bufferGraphics.drawString(System.currentTimeMillis() + " render!", 10, GameLauncher.HEIGHT - 20);
}

```

With this, image is shown plus nice timer showing we are updating buffer.

Here is whole Game class to have runnable example (with GameLanucher class):

```
public class Game extends JFrame implements Runnable {
    private static final long serialVersionUID = 1L;
    // Dimension for Main Frame
    private boolean isRunning = true;
    // Image
    private BufferedImage image = ImageIO.read(getClass().getResource("/Pixel_Background.png"));
    private BufferedImage buffer = new BufferedImage(GameLauncher.WIDTH, GameLauncher.HEIGHT, BufferedImage.TYPE_INT_RGB);
    private Graphics bufferGraphics = buffer.getGraphics();

    public Game() throws HeadlessException, IOException {

    }

    @Override
    public void run() {
        this.requestFocus();

        // Game Loop
        long now;
        long updateTime;
        long wait;

        final int TARGET_FPS = 60;
        final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;

        while (isRunning) {
            now = System.nanoTime();

            update();
            render();
            repaint();

            updateTime = now - System.nanoTime();
            wait = (OPTIMAL_TIME - updateTime) / 1000000;

            try {
                Thread.sleep(wait);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void update() {
        // TODO Auto-generated method stub
    }

    @Override
    public void paint(Graphics g) {
        g.drawImage(buffer, 0, 0, null);
    }

    private void render(){
        bufferGraphics.drawImage(image, 0, 0, null);
        bufferGraphics.drawString(System.currentTimeMillis() + " render!", 10, GameLauncher.HEIGHT - 20);
    }
}

```

---
Tags: java, rendering, graphics
---


# Question
Title: Get Impulse force needed for parabolic projectile launch
I want to create a projectile that fires upwards and in a sense falls down onto the player, like this:

I found through some research I needed to use a "parabolic" equation. However it wasnt very clear how to implement this.

Also a lot of the posts used these 4 variables

* Gravitational Constant
* Time to hit target
* Initial pos
* End pos

However these are the variables I have

* Gravitational Constant (marked G)
* Force upwards (marked T, measured as a number not in specific units) (for example if I want the projectile to go much higher and then fall down much more vertically)
* Start pos (marked a)
* End pos (marked b)

Can someone please clarify how I can do this in Unity? (Without telling me some huge equation like every other post did)

# Answer
> 2 votes
Unity will actually do all of the simulation for you. Given you are providing the vertical component \\$T\\$ of the force, all you need is the horizontal component \\$\vec{H}\\$, So all you need to do is re-arrange the equations so that, given your inputs, you get that component:

$$\vec{F} = \vec{H} + T \vec{up}$$

In Unity: `Vector3 F = H + T * Vector3.up;`. With that you can apply the force in Unity with `rigidbody.AddForce(F, ForceMode.Impulse);`.

To get the horizontal force \\$\vec{H}\\$, you will need the mass of your projectile \\$m\\$ and the horizontal velocity \\$\vec{h}\\$ that you want to achieve:

$$\vec{H} = \vec{h}m$$

The mass you can get from `rigidbody.mass` but the horizontal velocity you will need to calculate, and for that, you will need to know the travel time \\$t\\$ and the vector \\$\vec{AB}\\$ from \\$a\\$ to \\$b\\$:

$$\vec{h} = \frac{\vec{AB}}{t}$$

You can find \\$\vec{AB}\\$ in Unity with `Vector3 AB = b - a`. But to find the travel time \\$t\\$ (how long the projectile is in the air) you need to know the upward velocity \\$u\\$ and your gravity \\$g\\$:

$$t = \frac{2u}{g}$$

Nearly there. To find the upward velocity \\$u\\$ you need again the mass \\$m\\$ of your projectile and the upward force \\$T\\$ that you are supplying:

$$u = \frac{T}{m}$$

And so finally your code would be:

```
        float u = T / rigidbody.mass;
        float t = 2 * u / Physics.gravity.magnitude;
        Vector3 AB = b - a;
        Vector3 h = AB / t;
        Vector3 H = h * rigidbody.mass;
        Vector3 F = H + T * Vector3.up;
        rigidbody.AddForce(F, ForceMode.Impulse);

```

---
Tags: unity, 2d, projectile
---


# Question
Title: Understanding transform.forward vs. Converting World Space Forward to Local Space for Ray Drawing
I'm working in Unity and trying to visualize the forward direction of a GameObject. I came across two approaches:

**Using transform.forward:**

```
Debug.DrawRay(transform.position, transform.forward, Color.blue);

```

**Converting world space forward to local space:**

```
Debug.DrawRay(transform.position, transform.InverseTransformPoint(new Vector3(0, 0, 1)), Color.red);

```

Video: https://singh101404-gmail.tinytake.com/msc/OTM4NDQxOF8yMjk1ODg4Ng

I would expect both approaches to draw a ray in the same direction, representing the object's local forward direction. However, I'm observing some differences:

1. When using transform.InverseTransformPoint(), the ray does not rotate with the object and seems stuck in one direction.
2. The ray behaves as expected when using transform.forward, rotating with the object and representing its local forward direction.

Since I am creating a Vector representing the forward direction and then converting to local space relative to the cube shouldn't it produce the same result as trasnform.forward?

# Answer
> 1 votes
The problem here is that you're transforming a forward *direction* as though it were a *point* in space one unit "forward" from the origin.

`Transform.TransformPoint()` and `Transform.InverseTransformPoint()` are for transforming points, so they use the object's translation in addition to its rotation/scale. If your object is any distance away from the origin, that distance will tend to dominate over the piddly 1.0 in the input vector, and you end up with a vector that mostly points from the world origin toward the object, or from the object toward the world origin (for the inverse).

To transform a direction, you want to ignore the object's translation and scale and only use its rotation. `Transform.TransformDirection()` and `Transform.InverseTransformDirection()` do that.

Here you want the non-inverse case, because you're transforming a vector from the object's local space into world space, not the reverse.

So the corrected code would be:

```
Debug.DrawRay(
   transform.position,
   transform.TransformDirection(Vector3.forward),
   Color.red);

```

or the equivalent:

```
Debug.DrawRay(
   transform.position,
   transform.rotation * Vector3.forward,
   Color.red);

```

---
Tags: unity, c#, 3d, unityscript
---