Package rinde.sim.examples.demo

Source Code of rinde.sim.examples.demo.SwarmDemo$Vehicle

/**
*
*/
package rinde.sim.examples.demo;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.annotation.Nullable;
import javax.measure.Measure;
import javax.measure.unit.NonSI;
import javax.measure.unit.SI;

import org.apache.commons.math3.random.MersenneTwister;
import org.apache.commons.math3.random.RandomAdaptor;
import org.apache.commons.math3.random.RandomGenerator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

import rinde.sim.core.Simulator;
import rinde.sim.core.TickListener;
import rinde.sim.core.TimeLapse;
import rinde.sim.core.graph.Point;
import rinde.sim.core.model.ModelProvider;
import rinde.sim.core.model.ModelReceiver;
import rinde.sim.core.model.road.MovingRoadUser;
import rinde.sim.core.model.road.PlaneRoadModel;
import rinde.sim.core.model.road.RoadModel;
import rinde.sim.core.model.road.RoadUser;
import rinde.sim.ui.View;
import rinde.sim.ui.renderers.ModelRenderer;
import rinde.sim.ui.renderers.PanelRenderer;
import rinde.sim.ui.renderers.PlaneRoadModelRenderer;
import rinde.sim.ui.renderers.ViewPort;
import rinde.sim.ui.renderers.ViewRect;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;

/**
* @author Rinde van Lon <rinde.vanlon@cs.kuleuven.be>
*
*/
public class SwarmDemo {

  /**
   * Starts the demo.
   * @param args No args.
   */
  public static void main(String[] args) {
    final String string = "AgentWise";
    final List<Point> points = measureString(string, 30, 30, 0);
    final RandomGenerator rng = new MersenneTwister(123);
    final Simulator sim = new Simulator(rng, Measure.valueOf(1000L,
        SI.MILLI(SI.SECOND)));
    sim.register(new PlaneRoadModel(new Point(0, 0), new Point(4500, 1200),
        SI.METER, Measure.valueOf(1000d, NonSI.KILOMETERS_PER_HOUR)));
    sim.configure();
    for (final Point p : points) {
      sim.register(new Vehicle(p, rng));
    }
    View.create(sim)
        .with(new PlaneRoadModelRenderer(), new VehicleRenderer(),
            new DemoPanel(string, rng)).show();
  }

  public static ImmutableList<Point> measureString(String string, int fontSize,
      double spacing, int vCorrection) {
    if (string.trim().isEmpty()) {
      return ImmutableList.of();
    }
    final String stringToDraw = string;

    Display display = Display.getDefault();// getCurrent();
    boolean haveToDispose = false;
    if (display == null) {
      display = new Display();
      haveToDispose = true;
    }

    final GC measureGC = new GC(new Image(display, 100, 10));
    final Font initialFont = measureGC.getFont();
    final FontData[] fontData = initialFont.getFontData();
    for (int i = 0; i < fontData.length; i++) {
      fontData[i].setHeight(fontSize);
    }
    final Font newFont = new Font(display, fontData);
    measureGC.setFont(newFont);

    final org.eclipse.swt.graphics.Point extent = measureGC
        .textExtent(stringToDraw);
    measureGC.dispose();

    final Image image = new Image(display, extent.x, extent.y);
    final GC gc = new GC(image);
    gc.setFont(newFont);

    gc.setForeground(new Color(display, new RGB(0, 0, 0)));
    gc.drawText(stringToDraw, 0, 0);

    final ImmutableList.Builder<Point> coordinateBuilder = ImmutableList
        .builder();
    final int white = (int) Math.pow(2, 24) / 2 - 1;
    for (int i = 0; i < image.getBounds().width; i++) {
      for (int j = vCorrection; j < image.getBounds().height; j++) {
        final int color = image.getImageData().getPixel(i, j);
        if (color < white) {
          coordinateBuilder.add(new Point(i * spacing, (j - vCorrection)
              * spacing));
        }
      }
    }
    final ImmutableList<Point> points = coordinateBuilder.build();

    image.dispose();
    if (haveToDispose) {
      display.dispose();
    }
    return points;
  }

  static final class Vehicle implements MovingRoadUser, TickListener {
    Point destPos;
    RandomGenerator rng;

    private Optional<RoadModel> rm;
    double speed;
    boolean active;

    Vehicle(Point p, RandomGenerator r) {
      destPos = p;
      rng = r;
      active = true;
      rm = Optional.absent();
    }

    @Override
    public void initRoadUser(RoadModel model) {
      final Point startPos = model.getRandomPosition(rng);
      model.addObjectAt(this, startPos);

      rm = Optional.of(model);
      setDestination(destPos);
    }

    @Override
    public double getSpeed() {
      return speed;
    }

    @Override
    public void tick(TimeLapse timeLapse) {
      rm.get().moveTo(this, destPos, timeLapse);
    }

    @Override
    public void afterTick(TimeLapse timeLapse) {}

    /**
     * Change the destination of the vehicle.
     * @param dest The new destination.
     */
    public void setDestination(Point dest) {
      active = true;
      doSetDestination(dest);
    }

    private void doSetDestination(Point dest) {
      destPos = dest;
      speed = Point.distance(rm.get().getPosition(this), destPos)
          / (30 + 40 * rng.nextDouble());
    }

    /**
     * Moves the vehicle to a point on the border of the plane.
     */
    public void setInactive() {
      if (active) {
        active = false;
        final List<Point> bounds = rm.get().getBounds();
        final Point p = rm.get().getRandomPosition(rng);
        if (rng.nextBoolean()) {
          doSetDestination(new Point(bounds.get(rng.nextInt(2)).x, p.y));
        } else {
          doSetDestination(new Point(p.x, bounds.get(rng.nextInt(2)).y));
        }
      }
    }
  }

  static class DemoPanel implements PanelRenderer, Listener, ModelReceiver {
    Optional<RoadModel> rm;
    Set<Vehicle> vehicles;

    final String startString;
    RandomGenerator rng;

    DemoPanel(String s, RandomGenerator r) {
      startString = s;
      rng = r;
      vehicles = newHashSet();
      rm = Optional.absent();
    }

    @Override
    public void initializePanel(Composite parent) {
      final FillLayout rl = new FillLayout();
      parent.setLayout(rl);
      final Text t = new Text(parent, SWT.SINGLE | SWT.ICON_CANCEL | SWT.CANCEL);
      t.setText(startString);

      final int chars = 30;
      final GC gc = new GC(t);
      final FontMetrics fm = gc.getFontMetrics();
      final int width = chars * fm.getAverageCharWidth();
      final int height = fm.getHeight();
      gc.dispose();
      t.setSize(t.computeSize(width, height));
      t.addListener(SWT.DefaultSelection, this);
      t.addListener(SWT.Modify, this);

    }

    @Override
    public int preferredSize() {
      return 30;
    }

    @Override
    public int getPreferredPosition() {
      return SWT.TOP;
    }

    @Override
    public String getName() {
      return "Demo";
    }

    @Override
    public void handleEvent(@Nullable Event event) {
      checkNotNull(event);
      final Iterator<Point> points = measureString(
          ((Text) event.widget).getText(), 30, 30d, 0).iterator();
      final List<Vehicle> vs = newArrayList(vehicles);
      if (event.type == SWT.DefaultSelection) {
        Collections.shuffle(vs, new RandomAdaptor(rng));
      }
      for (final Vehicle v : vs) {
        if (points.hasNext()) {
          v.setDestination(points.next());
        } else {
          v.setInactive();
        }
      }
    }

    @Override
    public void registerModelProvider(ModelProvider mp) {
      rm = Optional.fromNullable(mp.getModel(RoadModel.class));
      vehicles = rm.get().getObjectsOfType(Vehicle.class);
    }
  }

  static final class VehicleRenderer implements ModelRenderer {
    private Optional<RoadModel> rm;

    VehicleRenderer() {
      rm = Optional.absent();
    }

    @Override
    public void renderDynamic(GC gc, ViewPort vp, long time) {
      final int radius = 2;
      gc.setBackground(new Color(gc.getDevice(), 255, 0, 0));
      final Map<RoadUser, Point> objects = rm.get().getObjectsAndPositions();
      synchronized (objects) {
        for (final Entry<RoadUser, Point> entry : objects.entrySet()) {
          final Point p = entry.getValue();
          gc.fillOval((int) (vp.origin.x + (p.x - vp.rect.min.x) * vp.scale)
              - radius, (int) (vp.origin.y + (p.y - vp.rect.min.y) * vp.scale)
              - radius, 2 * radius, 2 * radius);
        }
      }
    }

    @Override
    public void renderStatic(GC gc, ViewPort vp) {}

    @Nullable
    @Override
    public ViewRect getViewRect() {
      return null;
    }

    @Override
    public void registerModelProvider(ModelProvider mp) {
      rm = Optional.fromNullable(mp.getModel(RoadModel.class));
    }
  }

}
TOP

Related Classes of rinde.sim.examples.demo.SwarmDemo$Vehicle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.