Пример #1
0
    public DEMParticles simulate(DEMParticles particles, float t)
    {
        Vector2[] forces = particles.forces;
        List<Vector2> positions = particles.positions;
        List<Vector2> velocities = particles.velocities;
        List<float> massesInv = particles.massesInv;

        for (int iTarget = 0; iTarget < particles.length; iTarget++) {
            AABB boundingBox = particles.buildAABB(iTarget);
            int[] neighborIndices = spacePartitioner.search(boundingBox);
            forces[iTarget] = estimateForce(particles, iTarget, neighborIndices, t);
        }

        for (int iTarget = 0; iTarget < particles.length; iTarget++) {
            forces[iTarget] += boundaryForce.calcForce(particles, iTarget, t);
        }

        for (int iTarget = 0; iTarget < particles.length; iTarget++) {
            Vector2 accel = forces[iTarget] * massesInv[iTarget];
            Vector2 velocity = velocities[iTarget];

            positions[iTarget] += t * velocity;
            velocities[iTarget] += t * accel;
        }

        return particles;
    }
Пример #2
0
    public Vector2 estimateForce(DEMParticles particles, 
			int iTarget, int[] neighbors, float t)
    {
        Vector2 resForce = externalForce.calcForce(particles, iTarget, t);

        Vector2 targetPosition = particles.positions[iTarget];
        Vector2 targetVelocity = particles.velocities[iTarget];
        float targetRadius = particles.radii[iTarget];

        for (int i = 0; i < neighbors.Length; i++) {
            int iNeighbor = neighbors[i];
            if (iTarget == iNeighbor)
                continue;

            Vector2 pos = targetPosition - particles.positions[iNeighbor];
            Vector2 v = targetVelocity - particles.velocities[iNeighbor];
            float r12 = particles.radii[iNeighbor] + targetRadius;

            float dist2 = Vector2.SqrMagnitude(pos);
            if (dist2 >= (r12 * r12) || dist2 <= Mathf.Epsilon)
                continue;

            float dist = Mathf.Sqrt((float)dist2);
            float dxCoeff = ((r12 - dist) / dist);
            resForce += (kn * dxCoeff * pos - cn * v);
        }
        return resForce;
    }
    public Vector2 calcForce(DEMParticles particles, int iParticle, float dt)
    {
        Vector2 position = particles.positions[iParticle];
        Vector2 velocity = particles.velocities[iParticle];

        Vector2 dx = new Vector2(
            Mathf.Min(0, position.x - boundary[0]) + Mathf.Max(0, position.x - boundary[2]),
            Mathf.Min(0, position.y - boundary[1]) + Mathf.Max(0, position.y - boundary[3]));
        Vector2 dv = new Vector2((dx.x == 0 ? 0 : velocity.x), (dx.y == 0 ? 0 : velocity.y));
        return - kn * dx - cn * dv;
    }
    // Use this for initialization
    void Start()
    {
        this.particles = new DEMParticles();
        this.spacePartitioner = new GridSP<int>(
            boundBL, boundTR, 20, 20, new IntEqualityComparer());
        this.gravitationalForce = new GravitationalForce(new Vector2(0, -9.8f));
        this.boundaryForce = new BoundaryForce(
            kn, cn, boundBL.x, boundBL.y, boundTR.x, boundTR.y);
        this.dem = new DEM(spacePartitioner, gravitationalForce, boundaryForce);

        spheres = new GameObject[nParticles];
        for (int i = 0; i < nParticles; i++) {
            GameObject s = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            s.transform.localScale = new Vector3(diameter, diameter, diameter);
            s.transform.position = new Vector3(
                Random.Range(boundBL.x, boundTR.x),
                Random.Range(boundBL.y, boundTR.y),
                0);
            Destroy(s.collider);
            spheres[i] = s;
        }

        int length = spheres.Length;
        float[] radii = new float[length];
        float[] masses = new float[length];
        Vector2[] positions = new Vector2[length];
        Vector2[] velocities = new Vector2[length];
        for (int i = 0; i < length; i++) {
            GameObject sphere = spheres[i];
            float radius = 0.5f * sphere.transform.localScale.x;
            radii[i] = radius;
            masses[i] = mass; //(rho * Mathf.PI * radius);
            positions[i] = new Vector2(
                sphere.transform.position.x, sphere.transform.position.y);
            velocities[i] = Vector2.zero;
        }

        particles.addParticle(masses, radii, positions, velocities);
        for (int i = 0; i < length; i++) {
            spacePartitioner.add(particles.buildAABB(i), i);
        }
    }
 public Vector2 calcForce(DEMParticles particles, int iParticle, float dt)
 {
     return Vector2.zero;
 }
 public Vector2 calcForce(DEMParticles particles, int iParticle, float dt)
 {
     return particles.masses[iParticle] * gravity;
 }