• Create Account

Finalspace

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

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

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
- 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?

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:

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;

```

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