Jump to content

  • Log In with Google      Sign In   
  • Create Account

Finalspace

Member Since 29 Mar 2012
Offline Last Active Today, 09:34 AM

Topics I've Started

How to calculate aabb for a circle segment

18 December 2015 - 04:16 AM

Hi,

 

i have a circle segment, defined with the following parameters:

 

- Center

- Start angle in radians

- End angle in radians

- Radius

 

How do i calculate an axis aligned bounding which will exactly fit the segment in?


Tilebased Platformer prototype

17 December 2015 - 08:31 AM

I am not sure where this post belong, but i want to give something back to this awesome community - so i made a tiny tile-based platformer prototype using a robust physics system based on speculative contacts - including pushing of blocks and stacking ;-)
 
Here is the full javascript commented sourcecode without any dependencies at all - you can do whatever you want with it.
 
 
Its far from complete, but here are some easy additions you can make:
 
- Apply friction to get a real platformer experience
- More solver iterations / accumulate impulses to get a more robust experience (Faster convergence for dynamic vs dynamic)
- Edit tilemap while you are playing
- Load and save tilemap (would require at least a simple webservice to call on)
- Jump through platforms
- Elevators
- Enemies
- Ladders
- Spikes
- Doors
- Rendering sprites
 
Much harder, but really useful additions:
 
- Support for circles
- Support for line segments
- Support for polygons
- Support for local rotations
- Switch to a real rigid body dynamics simulation - requires to generate two contacts in some cases
 
Merry christmas,
Finalspace

Lerp vs fastLerp

27 November 2015 - 03:09 AM

We all know what lerps does and how it works - but there are two ways to implement lerps:

 

lerp = a * (1 - t) + b * t (2 multiplys, one substraction, one addition)

 

fastLerp = a + (b - a) * t (one multiply, one substraction, one addition)

 

In practice, i have never seen any differences between the both.

 

If i write unit tests for - both have the same result for the same combinations:

        // lerp
        assert.strictEqual(math.lerp(0, 100, -1), -100, "lerp for 0 / 100 / -1.0");
        assert.strictEqual(math.lerp(0, 100, -0.75), -75, "lerp for 0 / 100 / -0.75");
        assert.strictEqual(math.lerp(0, 100, -0.5), -50, "lerp for 0 / 100 / -0.50");
        assert.strictEqual(math.lerp(0, 100, -0.25), -25, "lerp for 0 / 100 / -0.25");
        assert.strictEqual(math.lerp(0, 100, 0), 0, "lerp for 0 / 100 / 0.0");
        assert.strictEqual(math.lerp(0, 100, 0.25), 25, "lerp for 0 / 100 / 0.25");
        assert.strictEqual(math.lerp(0, 100, 0.5), 50, "lerp for 0 / 100 / 0.5");
        assert.strictEqual(math.lerp(0, 100, 0.75), 75, "lerp for 0 / 100 / 0.75");
        assert.strictEqual(math.lerp(0, 100, 1), 100, "lerp for 0 / 100 / 1.0");
        assert.strictEqual(math.lerp(100, 0,  -1), 200, "lerp for 100 / 0 / -1.0");
        assert.strictEqual(math.lerp(100, 0, -0.75), 175, "lerp for 100 / 0 / -0.75");
        assert.strictEqual(math.lerp(100, 0, -0.5), 150, "lerp for 100 / 0 / -0.5");
        assert.strictEqual(math.lerp(100, 0, -0.25), 125, "lerp for 100 / 0 / -0.25");
        assert.strictEqual(math.lerp(100, 0, 0), 100, "lerp for 100 / 0 / 0.0");
        assert.strictEqual(math.lerp(100, 0, 0.25), 75, "lerp for 100 / 0 / 0.25");
        assert.strictEqual(math.lerp(100, 0, 0.5), 50, "lerp for 100 / 0 / 0.5");
        assert.strictEqual(math.lerp(100, 0, 0.75), 25, "lerp for 100 / 0 / 0.75");
        assert.strictEqual(math.lerp(100, 0,  1), 0, "lerp for 100 / 0 / 1.0");

        // lerpFast
        assert.strictEqual(math.lerpFast(0, 100, -1), -100, "lerpFast for 0 / 100 / -1.0");
        assert.strictEqual(math.lerpFast(0, 100, -0.75), -75, "lerpFast for 0 / 100 / -0.75");
        assert.strictEqual(math.lerpFast(0, 100, -0.5), -50, "lerpFast for 0 / 100 / -0.50");
        assert.strictEqual(math.lerpFast(0, 100, -0.25), -25, "lerpFast for 0 / 100 / -0.25");
        assert.strictEqual(math.lerpFast(0, 100, 0), 0, "lerpFast for 0 / 100 / 0.0");
        assert.strictEqual(math.lerpFast(0, 100, 0.25), 25, "lerpFast for 0 / 100 / 0.25");
        assert.strictEqual(math.lerpFast(0, 100, 0.5), 50, "lerpFast for 0 / 100 / 0.5");
        assert.strictEqual(math.lerpFast(0, 100, 0.75), 75, "lerpFast for 0 / 100 / 0.75");
        assert.strictEqual(math.lerpFast(0, 100, 1), 100, "lerpFast for 0 / 100 / 1.0");
        assert.strictEqual(math.lerpFast(100, 0,  -1), 200, "lerpFast for 100 / 0 / -1.0");
        assert.strictEqual(math.lerpFast(100, 0, -0.75), 175, "lerpFast for 100 / 0 / -0.75");
        assert.strictEqual(math.lerpFast(100, 0, -0.5), 150, "lerpFast for 100 / 0 / -0.5");
        assert.strictEqual(math.lerpFast(100, 0, -0.25), 125, "lerpFast for 100 / 0 / -0.25");
        assert.strictEqual(math.lerpFast(100, 0, 0), 100, "lerpFast for 100 / 0 / 0.0");
        assert.strictEqual(math.lerpFast(100, 0, 0.25), 75, "lerpFast for 100 / 0 / 0.25");
        assert.strictEqual(math.lerpFast(100, 0, 0.5), 50, "lerpFast for 100 / 0 / 0.5");
        assert.strictEqual(math.lerpFast(100, 0, 0.75), 25, "lerpFast for 100 / 0 / 0.75");
        assert.strictEqual(math.lerpFast(100, 0,  1), 0, "lerpFast for 100 / 0 / 1.0");

Which one is better?

 

 

Thanks in advance


Move side of a polygon

26 November 2015 - 08:09 AM

I am building a level editor for my game and doing the implementation for resizing (moving of two vectors by a given delta) of polygons right now. Grabing the side of a polygon and moving the vertices along the given delta works already, so the only problem i have right now is to doing the repositioning so that the body center match the new local center.

 

How do i calculate the new body center and delta for offseting my local vertices?

 

See picture for better understanding:

 

resize%20delta.png

 

 


How to combine polygon and circle local/world transformation?

20 October 2015 - 03:00 PM

I have a rigid body, it have a world position and rotation.

The rigid body may have multiple shapes, each shape may have a local rotation and offset.

 

Maybe one shape is a polygon and another is a circle - so its a combined thing.

Each of that has its local offset to some extend - so that its not on the body center anymore.

 

When i for example want to draw a polygon in world space with all the transformation applied i do it like this:

Mat2f localRotation(0.05f);
Vec2f localOffset(100, 0);

Mat2f worldRotation(0.15f);
Vec2f worldPosition(0, 0);

for (int i = 0; i < numVerts; i++) {
  v2 p0 = (V2(localVertices[i]) * localRotation + localOffset) * worldRotation + worldPosition;
  v2 p1 = (V2(localVertices[i < numVerts - 1 ? i + 1 : 0]) * localRotation + localOffset) * worldRotation + worldPosition;
  drawLine(p0, p1);
}

But what about circle shapes? They will change the position when the local offset is not zero.

//Mat2f localRotation(0f); // Circles dont have a local rotation at all
Vec2f localOffset(-100, 0);

Mat2f worldRotation(0.15f);
Vec2f worldPosition(0, 0);

Vec2f pos = V2(localOffset) * worldRotation + worldPosition;

drawCircle(pos, radius);

This seems to be a totally different way than the implementation above.

 

Is there a nice way to change the polygon drawing to use this way - so that it uses a rotated position and of course, includes the vertex rotation as well ?

 

It must be really easy, but right now i dont see it at all... 


PARTNERS