public void updateCabin(Cabin cabin, double deltaTime) { if (deltaTime > 0.2) return; if (cabin.isOn()) { switch (cabin.getState()) { case MOVE: double vector = cabin.getVector(); int vectorUnit = (int) (vector / Math.abs(vector)); double motor = motorOutput * earthGravity * deltaTime; // Nm/s (weight) -> kgfm if (motor <= gravity) { logger.debug("motor is too weak or gravity is too strong."); motor = gravity; } Floor target = cabin.getTarget(); double leftVector = target.getPosition() - cabin.getPosition(); int leftVectorUnit = (int) (leftVector / Math.abs(leftVector)); double accel = motor / mass(cabin) * leftVectorUnit; if (Math.abs(cabin.getVelocity()) > 1) accel *= Math.abs(vector * 0.5) < Math.abs(leftVector) ? 1 : -1; // brake on half point if (Double.isNaN(accel)) { accel = vectorUnit; } // logger.debug(String.format("%f -> %f (%f) : %f",cabin.getPosition(), // target.getPosition(),vector,accel)); // logger.debug(String.format("%s->%d, %f, %f, // %f",cabin.getName(),target.getNum(),accel,leftVector,vector*0.5)); updateCabin(cabin, accel, deltaTime); if (Math.abs(leftVector) < CABIN_MOVE_THRESHOLD) { // arrive cabin.setPosition(target.getPosition()); cabin.stop(); // cabin.getQueue().remove(target); logger.debug(String.format("%s->%d done", cabin.getName(), target.getNum())); } break; case STOP: logger.info("cabin({}) arrived", cabin.getName()); for (Floor floor : floors.values()) { if (cabin.getPosition() == floor.getPosition()) { logger.debug("on {}", floor); Iterator<Passenger> it = cabin.getPassengers().iterator(); while (it.hasNext()) { Passenger p = it.next(); if (p.getDest().equals(floor.getNum())) { p.setState(Passenger.State.NO_WAIT); it.remove(); floor.getPassengers().add(p); } } cabin.getQueue().remove(floor); } } if (cabin.getQueue().size() > 0) cabin.move(); // to next queued floor break; } } }
public void updateCabin(Cabin cabin, double accel, double deltaTime) { if (deltaTime > 0.2) return; double vi = cabin.getVelocity(), vf = vi + accel * deltaTime; // vf=vi+ a*dt if (Math.abs(vf) > 20) vf = 0d; double ds = 0.5 * deltaTime * (vf + vi); cabin.setPosition( cabin.getPosition() + ds); // sf=si+integral(dv=vf-vi)=si+dt*(vf-vi)=si+dt*(a*dt)=si+a*dt^2 cabin.setVelocity(vf); double min = floors.get(FloorType.TENTH).getPosition(), max = floors.get(FloorType.UNDER_FIRST).getPosition(); if (cabin.getPosition() > max) { cabin.setPosition(max); } if (cabin.getPosition() < min) { cabin.setPosition(min); } }
private void draw() { Renderer renderer = ui.getRenderer(); Graphics g = renderer.getGraphics(); int fsize = g.getFont().getSize(); JPanel target = ui.getDrawTarget(); g.setColor(Color.GRAY); g.fillRect(0, 0, target.getWidth(), target.getHeight()); Map<CabinType, Integer> xmap = new HashMap<CabinType, Integer>() { { this.put(CabinType.LEFT, Floor.PIXEL_WIDTH + 10); this.put(CabinType.RIGHT, Floor.PIXEL_WIDTH + 10 + Cabin.PIXEL_WIDTH + 30); } }; for (CabinType type : cabins.keySet()) { Integer x = xmap.get(type); Cabin cabin = cabins.get(type); int passengers = cabin.getPassengers().size(); double cabinY = cabin.getPosition() * REAL_TO_PIXEL_RATIO, cabinH = (double) cabin.PIXEL_HEIGHT, cabinW = (double) cabin.PIXEL_WIDTH; g.setColor(Color.WHITE); g.fillRect(x, (int) cabinY, (int) cabinW, (int) cabinH); g.setColor(Color.BLACK); g.drawRect(x, (int) cabinY, (int) cabinW, (int) cabinH); // cabin fullness g.drawString( passengers >= cabinLimitPeople ? passengers > cabinLimitPeople ? "초과" : "만원" : "", (int) (x + cabinW / 2.0 - fsize), (int) (cabinY + cabinH / 2.0 - fsize)); // passengers on cabin g.drawString( String.format("%d명", passengers), (int) (x + cabinW / 2.0 - fsize * 2.0 / 2.0), (int) (cabinY + cabinH / 2.0)); // cabin weight g.drawString(String.format("%.0fkg", mass(cabin)), x, (int) (cabinY + cabinH / 2.0 + fsize)); // cabin speed g.drawString( String.format("%.1fm/s", Math.abs(cabin.getVelocity())), x, (int) (cabinY + cabinH / 2.0 + fsize * 2.0)); } for (Floor floor : floors.values()) { int passengers = floor.getPassengers().size(); double floorY = floor.getPosition() * REAL_TO_PIXEL_RATIO; g.setFont(Font.getFont(Font.SANS_SERIF)); g.setColor(Color.WHITE); g.fillRect(1, (int) floorY, Floor.PIXEL_WIDTH, Floor.PIXEL_HEIGHT); g.setColor(Color.BLACK); g.drawRect(1, (int) floorY, Floor.PIXEL_WIDTH, Floor.PIXEL_HEIGHT); g.drawString(floor.getNum() + "층", 1, (int) floorY + 15); g.drawString( Integer.toString(passengers), (int) (1 + (double) (Floor.PIXEL_WIDTH) / 2.0 - (double) fsize / 2.0), (int) (floorY + (double) Floor.PIXEL_HEIGHT / 2.0)); } if (state >> 1 == CircumstanceType.FIRE.state()) { Floor firedFloor = (Floor) Circumstance.get(CircumstanceType.FIRE).getParameter("floor"); if (null != firedFloor) g.drawString( "화재", Floor.PIXEL_WIDTH / 2 - fsize, (int) (firedFloor.getPosition() * REAL_TO_PIXEL_RATIO + (double) Floor.PIXEL_HEIGHT / 2.0 + fsize * 2.0)); } renderer.flush(); }