1
\$\begingroup\$

So i have a simulation I am trying to make where there is a grid. Each dot will be connected to the dot Above, below, left, or right (If such dot exists) via a logical grid.

Theoretically when I create a disturbance it will react slightly like cloth.

My problem is it is going all wrong! I didnt know which way to subtract to get the delta so I gave you two samples.

Issue one Detract: This one is probably the wrong one but it might help. Basically when you cause a disturbance it causes everything to fly away. Its pretty cool looking.

Issue two Attract: This one is probably using the correct delta, however when left on its own the grid eventually groups in on top of itself. Ignore the diagonal ones at the very beginning those are just an error, I removed them since recording that video.

Below is excerpts from the code that causes this. This system works entirely on a 1d array (because they arent always even close to a grid) and as a result I have a bunch of functions that find the index of next-door points. I am not showing their implementation unless that is likely to be the error.

The velocity resulting from the spring is stored in a variable springV.

Each frame the interaction displacement and resulting spring velocity is calculated through function transfer. Then after all of that is calculated it is applied to the positions through function resolveGridS. Transfer() is run on each particle one by one in an order, then resolveGridS is run after that.

Theoretically the correct force given from having a spring from the nextdoor point is calculated in the function resolveGridS and added to the total.

The "Resting" distance of the grid is about 30.

 var springV = Point()
    func transfer()
    {
        if (excluded) {return} //Gets rid of points not on the grid, they dont get to be springs


        let touch = MT.getFirstFinger()
    if (touch.down)
    {
        let location = getPosition()
        let dist2p = Math.dist2P(location, touch.location) / Storage.bounds.rb
        let angle = Math.calculateAngle(location, touch.location)
        pointTowords(touch.location)
        direction += 180
        let calc = (-dist2p * dist2p) + 1.0
        if (circleIndex == 0) {print(calc)}
        moveBy(calc / 5)
    }


    let id = Int(circleIndex / 5) //Get the 1d array location of this particle

    //Get the 1d array index of each of the next door points
    let above = moveDirection(id, Direction.Up)
    let below = moveDirection(id, Direction.Down)
    let left = moveDirection(id, Direction.Left)
    let right = moveDirection(id, Direction.Right)

    //Drag
    springV.x /= 1.1
    springV.y /= 1.1

    if (left.1 == -1) //This check just deals with edge cases
    {
        SpringC(Storage.particles[left.0].getPosition())
    }

    if (right.1 == -1)
    {
        SpringC(Storage.particles[right.0].getPosition())
    }

    if (below.1 == -1)
    {
        SpringC(Storage.particles[below.0].getPosition())
    }

    if (above.1 == -1)
    {
        SpringC(Storage.particles[above.0].getPosition())
    }
}


func resolveGridS()
{
    Storage.circles[circleIndex] += springV.x
    Storage.circles[circleIndex + 1] += springV.y
}

  func SpringC(loc: Point)
  {
        let pos = Point(x: Storage.circles[circleIndex], y: Storage.circles[circleIndex + 1])
        let delta = Math.subtract(loc, pos)
        let dist = Math.dist2P(delta)
        let norm = Math.multiply(delta, 1 / dist)

        springV.x += norm.x * 0.01 * abs(dist - 30)
        springV.y += norm.y * 0.01 * abs(dist - 30)

    }

NOTE: I really dont know how you are supposed to deal with physics when one object has multiple springs connected to it. I made the assumption that you just calculate the force each spring gives for each object. And then after all of the forces are calculated you apply it. That could be wrong.

\$\endgroup\$

0

You must log in to answer this question.

Browse other questions tagged .