/** Implementation of Runnable interface. DO NOT access this method directly. */
 public void run() {
   GUIUtils.setAnimatedFrameIgnoreRepaint(
       true); // animated frames are updated by this thread so no need to repaint
   long sleepTime = delayTime;
   while (animationThread == Thread.currentThread()) {
     long currentTime = System.currentTimeMillis();
     for (int i = 0; i < stepsPerDisplay; i++) {
       doStep();
       stepCounter++;
       if (animationThread != Thread.currentThread()) {
         break; // check for stop condition
       } else {
         Thread.yield(); // give other threads a chance to run if needed
       }
     }
     org.opensourcephysics.display.GUIUtils.renderAnimatedFrames();
     // adjust the sleep time to try and achieve a constant animation rate
     // some VMs will hang if sleep time is less than 10
     sleepTime = Math.max(10, delayTime - (System.currentTimeMillis() - currentTime));
     try {
       Thread.sleep(sleepTime);
     } catch (InterruptedException ie) {
     }
   }
   GUIUtils.setAnimatedFrameIgnoreRepaint(
       false); // animated frames are updated by this thread so no need to repaint
 }
  public static void main(String args[]) {

    IntensityFeatureScaleSpacePyramidApp<ImageFloat32, ImageFloat32> app =
        new IntensityFeatureScaleSpacePyramidApp<ImageFloat32, ImageFloat32>(
            ImageFloat32.class, ImageFloat32.class);

    //		IntensityFeatureScaleSpacePyramidApp<ImageUInt8, ImageSInt16> app2 =
    //				new
    // IntensityFeatureScaleSpacePyramidApp<ImageUInt8,ImageSInt16>(ImageUInt8.class,ImageSInt16.class);

    java.util.List<PathLabel> inputs = new ArrayList<PathLabel>();

    inputs.add(new PathLabel("shapes", "../data/evaluation/shapes01.png"));
    inputs.add(new PathLabel("sunflowers", "../data/evaluation/sunflowers.png"));
    inputs.add(new PathLabel("beach", "../data/evaluation/scale/beach02.jpg"));

    app.setInputList(inputs);

    // wait for it to process one image so that the size isn't all screwed up
    while (!app.getHasProcessedImage()) {
      Thread.yield();
    }

    ShowImages.showWindow(app, "Feature Scale Space Pyramid Intensity");
  }
  public static void main(String args[]) throws FileNotFoundException {

    DetectCalibrationChessApp app = new DetectCalibrationChessApp();

    //		String prefix = "../data/applet/calibration/mono/Sony_DSC-HX5V_Chess/";
    String prefix = "../data/applet/calibration/stereo/Bumblebee2_Chess/";

    app.loadConfigurationFile(prefix + "info.txt");

    app.setBaseDirectory(prefix);
    //		app.loadInputData(prefix+"images.txt");

    List<PathLabel> inputs = new ArrayList<PathLabel>();

    for (int i = 1; i <= 12; i++) {
      //			inputs.add(new PathLabel(String.format("View
      // %02d",i),String.format("%sframe%02d.jpg",prefix,i)));
      inputs.add(
          new PathLabel(String.format("View %02d", i), String.format("%sleft%02d.jpg", prefix, i)));
    }

    app.setInputList(inputs);

    // wait for it to process one image so that the size isn't all screwed up
    while (!app.getHasProcessedImage()) {
      Thread.yield();
    }

    ShowImages.showWindow(app, "Calibration Target Detection", true);
  }
示例#4
0
  /** The main function for displaying the Life game area. */
  private void paintCanvas(Graphics g) {
    Dimension canvasSize = canvas.getSize();
    int xdelta = canvasSize.width / modelSize;
    if (xdelta == 0) {
      xdelta = 1;
    }
    int ydelta = canvasSize.height / modelSize;
    if (ydelta == 0) {
      ydelta = 1;
    }

    for (int x = 0; x < modelSize; ++x) {
      for (int y = 0; y < modelSize; ++y) {
        int age = theModel.getCell(x, y);
        // System.out.print("("+x+","+y+"): " + age);
        if (generationCount >= 10 && age > 0) {
          age = 1 + 10 * age / generationCount;
        }
        if (age >= 10) {
          age = 9;
        }
        Color c = (age > 0) ? colorMap[age - 1] : Color.black;
        // System.out.println(" " + age + " color: " + c);
        g.setColor(c);
        g.fillRect(x * xdelta, y * ydelta, xdelta, ydelta);
      }
    }
    Thread.yield();
  }
示例#5
0
  /** @see pong.ApplicationState#process(long) */
  @Override
  public boolean process(long dT) {
    backgroundScene.update(dT);
    mainFrame.renderScene();
    Thread.yield();

    return !stopProcessing;
  }
示例#6
0
 public void advance(final int value) {
   try {
     SwingUtilities.invokeAndWait(
         new Runnable() {
           public void run() {
             progress.setValue(progress.getValue() + value);
           }
         });
     Thread.yield();
   } catch (Exception e) {
   }
 }
示例#7
0
  public void run()
        /* The frames of the animation are drawn inside the while loop. */
      {
    long beforeTime, afterTime, timeDiff, sleepTime;
    long overSleepTime = 0L;
    int noDelays = 0;
    long excess = 0L;

    gameStartTime = System.nanoTime();
    beforeTime = gameStartTime;

    running = true;

    while (running) {
      gameUpdate();
      gameRender();
      paintScreen();

      afterTime = System.nanoTime();
      timeDiff = afterTime - beforeTime;
      sleepTime = (period - timeDiff) - overSleepTime;

      if (sleepTime > 0) { // some time left in this cycle
        try {
          Thread.sleep(sleepTime / 1000000L); // nano -> ms
        } catch (InterruptedException ex) {
        }
        overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
      } else { // sleepTime <= 0; the frame took longer than the period
        excess -= sleepTime; // store excess time value
        overSleepTime = 0L;

        if (++noDelays >= NO_DELAYS_PER_YIELD) {
          Thread.yield(); // give another thread a chance to run
          noDelays = 0;
        }
      }

      beforeTime = System.nanoTime();

      /* If frame animation is taking too long, update the game state
      without rendering it, to get the updates/sec nearer to
      the required FPS. */
      int skips = 0;
      while ((excess > period) && (skips < MAX_FRAME_SKIPS)) {
        excess -= period;
        gameUpdate(); // update state but don't render
        skips++;
      }
    }
    System.exit(0); // so window disappears
  } // end of run()
示例#8
0
  /**
   * Sets one or more icons for the Display.
   *
   * <ul>
   *   <li>On Windows you should supply at least one 16x16 icon and one 32x32.
   *   <li>Linux (and similar platforms) expect one 32x32 icon.
   *   <li>Mac OS X should be supplied one 128x128 icon
   * </ul>
   *
   * The implementation will use the supplied ByteBuffers with image data in RGBA and perform any
   * conversions nescesarry for the specific platform.
   *
   * @param icons Array of icons in RGBA mode
   * @return number of icons used.
   */
  public int setIcon(ByteBuffer[] icons) {
    boolean done_small = false;
    boolean done_large = false;
    int used = 0;

    int small_icon_size = 16;
    int large_icon_size = 32;
    for (ByteBuffer icon : icons) {
      int size = icon.limit() / 4;

      if ((((int) Math.sqrt(size)) == small_icon_size) && (!done_small)) {
        long small_new_icon = createIcon(small_icon_size, small_icon_size, icon.asIntBuffer());
        sendMessage(hwnd, WM_SETICON, ICON_SMALL, small_new_icon);
        freeSmallIcon();
        small_icon = small_new_icon;
        used++;
        done_small = true;
      }
      if ((((int) Math.sqrt(size)) == large_icon_size) && (!done_large)) {
        long large_new_icon = createIcon(large_icon_size, large_icon_size, icon.asIntBuffer());
        sendMessage(hwnd, WM_SETICON, ICON_BIG, large_new_icon);
        freeLargeIcon();
        large_icon = large_new_icon;
        used++;
        done_large = true;

        // Problem: The taskbar icon won't update until Windows sends a WM_GETICON to our window
        // proc and we reply. But this method is usually called
        // on init and it might take a while before the next call to nUpdate (because of resources
        // being loaded, etc). So we wait for the next
        // WM_GETICON message (usually received about 100ms after WM_SETICON) to make sure the
        // taskbar icon has updated before we return to the user.
        // (We wouldn't need to do this if the event loop was running continuously on its own
        // thread.)
        iconsLoaded = false;

        // Track how long the wait takes and give up at 500ms, just in case.
        long time = System.nanoTime();
        long MAX_WAIT = 500L * 1000L * 1000L;
        while (true) {
          nUpdate();
          if (iconsLoaded || MAX_WAIT < System.nanoTime() - time) break;

          Thread.yield();
        }
      }
    }

    return used;
  }
示例#9
0
 protected void scroll(int sx, int sy) {
   int ox = xSrcStart + (int) (sx / magnification); // convert to offscreen coordinates
   int oy = ySrcStart + (int) (sy / magnification);
   // IJ.log("scroll: "+ox+" "+oy+" "+xMouseStart+" "+yMouseStart);
   int newx = xSrcStart + (xMouseStart - ox);
   int newy = ySrcStart + (yMouseStart - oy);
   if (newx < 0) newx = 0;
   if (newy < 0) newy = 0;
   if ((newx + srcRect.width) > imageWidth) newx = imageWidth - srcRect.width;
   if ((newy + srcRect.height) > imageHeight) newy = imageHeight - srcRect.height;
   srcRect.x = newx;
   srcRect.y = newy;
   // IJ.log(sx+"  "+sy+"  "+newx+"  "+newy+"  "+srcRect);
   imp.draw();
   Thread.yield();
 }
  public static void main(String args[]) {
    Class imageType = ImageFloat32.class;
    Class derivType = GImageDerivativeOps.getDerivativeType(imageType);

    VisualizeAssociationMatchesApp app = new VisualizeAssociationMatchesApp(imageType, derivType);

    List<PathLabel> inputs = new ArrayList<PathLabel>();

    inputs.add(
        new PathLabel(
            "Cave",
            "../data/evaluation/stitch/cave_01.jpg",
            "../data/evaluation/stitch/cave_02.jpg"));
    inputs.add(
        new PathLabel(
            "Kayak",
            "../data/evaluation/stitch/kayak_02.jpg",
            "../data/evaluation/stitch/kayak_03.jpg"));
    inputs.add(
        new PathLabel(
            "Forest",
            "../data/evaluation/scale/rainforest_01.jpg",
            "../data/evaluation/scale/rainforest_02.jpg"));
    inputs.add(
        new PathLabel(
            "Building",
            "../data/evaluation/stitch/apartment_building_01.jpg",
            "../data/evaluation/stitch/apartment_building_02.jpg"));
    inputs.add(
        new PathLabel(
            "Trees Rotate",
            "../data/evaluation/stitch/trees_rotate_01.jpg",
            "../data/evaluation/stitch/trees_rotate_03.jpg"));

    app.setPreferredSize(new Dimension(1000, 500));
    app.setSize(1000, 500);
    app.setInputList(inputs);

    // wait for it to process one image so that the size isn't all screwed up
    while (!app.getHasProcessedImage()) {
      Thread.yield();
    }

    ShowImages.showWindow(app, "Associated Features");
  }
  public static void main(String args[]) {
    DemoBinaryImageOpsApp app = new DemoBinaryImageOpsApp(GrayF32.class);

    java.util.List<PathLabel> inputs = new ArrayList<>();
    inputs.add(new PathLabel("particles", UtilIO.pathExample("particles01.jpg")));
    inputs.add(new PathLabel("shapes", UtilIO.pathExample("shapes/shapes01.png")));

    app.setInputList(inputs);

    // wait for it to process one image so that the size isn't all screwed up
    while (!app.getHasProcessedImage()) {
      Thread.yield();
    }

    ShowImages.showWindow(app, "Binary Image Ops", true);

    System.out.println("Done");
  }
示例#12
0
  public void testRequiredLayoutTriggeredWhilePerformingLayoutStillGetsRegistered()
      throws Exception {
    for (int i = 0; i < 100; i++) panel.add(new PropPanel(new MockProp()));
    panel.markAsNeedingLayout();
    Thread thread =
        new Thread(
            new Runnable() {
              public void run() {
                panel.doLayout();
              }
            });
    thread.start();

    while (panel.getChildren().get(0).needsLayout()) Thread.yield();
    panel.markAsNeedingLayout();
    thread.join();

    assertEquals(true, panel.needsLayout());
  }
示例#13
0
  public static void main(String args[]) {
    FourierVisualizeApp app = new FourierVisualizeApp(ImageDataType.F32);
    //		FourierVisualizeApp app = new FourierVisualizeApp(ImageTypeInfo.F64);

    java.util.List<PathLabel> inputs = new ArrayList<PathLabel>();
    inputs.add(new PathLabel("lena", "../data/evaluation/standard/lena512.bmp"));
    inputs.add(new PathLabel("boat", "../data/evaluation/standard/boat.png"));
    inputs.add(new PathLabel("fingerprint", "../data/evaluation/standard/fingerprint.png"));
    inputs.add(new PathLabel("shapes", "../data/evaluation/shapes01.png"));
    inputs.add(new PathLabel("sunflowers", "../data/evaluation/sunflowers.png"));

    app.setInputList(inputs);

    // wait for it to process one image so that the size isn't all screwed up
    while (!app.getHasProcessedImage()) {
      Thread.yield();
    }

    ShowImages.showWindow(app, "Discrete Fourier Transform");
  }
  public void evaluate(String dataName, TldTracker<T, ?> tracker) {
    System.out.println("Processing " + dataName);

    String path = "data/track_rect/TLD/" + dataName;

    Rectangle2D_F64 initial = UtilTldData.parseRectangle(path + "/init.txt");
    Rectangle2D_F64 found = new Rectangle2D_F64();

    TldVisualizationPanel gui = null;

    String imageType = new File(path + "/00001.jpg").exists() ? "jpg" : "png";

    int imageNum = 0;
    while (true) {
      String imageName = String.format("%s/%05d.%s", path, imageNum + 1, imageType);
      BufferedImage image = UtilImageIO.loadImage(imageName);
      if (image == null) break;

      input.reshape(image.getWidth(), image.getHeight());
      ConvertBufferedImage.convertFrom(image, input, true);

      boolean detected;

      if (imageNum == 0) {
        gui = new TldVisualizationPanel(this);
        gui.setFrame(image);
        gui.setSelectRectangle(false);
        ShowImages.showWindow(gui, dataName);
        tracker.initialize(
            input, (int) initial.p0.x, (int) initial.p0.y, (int) initial.p1.x, (int) initial.p1.y);
        detected = true;
      } else {
        detected = tracker.track(input);
        found.set(tracker.getTargetRegion());
      }

      if (!detected) {
        System.out.println("No Detection");
      } else {
        System.out.printf(
            "Detection: %f,%f,%f,%f\n", found.p0.x, found.p0.y, found.p1.x, found.p1.y);

        Graphics2D g2 = image.createGraphics();

        int w = (int) found.getWidth();
        int h = (int) found.getHeight();

        g2.drawRect((int) found.p0.x, (int) found.p0.y, w, h);
      }

      gui.setFrame(image);
      gui.update(tracker, detected);
      gui.repaint();

      imageNum++;

      while (paused) {
        Thread.yield();
      }

      //			BoofMiscOps.pause(30);
    }
    System.out.println();
  }
示例#15
0
  public void run() {
    running = true;
    try {
      startGame();
    } catch (Exception exception) {
      exception.printStackTrace();
      onMinecraftCrash(new UnexpectedThrowable("Failed to start game", exception));
      return;
    }
    try {
      long l = System.currentTimeMillis();
      int i = 0;
      do {
        if (!running) {
          break;
        }
        try {
          if (mcApplet != null && !mcApplet.isActive()) {
            break;
          }
          AxisAlignedBB.clearBoundingBoxPool();
          Vec3D.initialize();
          if (mcCanvas == null && Display.isCloseRequested()) {
            shutdown();
          }
          if (isGamePaused && theWorld != null) {
            float f = timer.renderPartialTicks;
            timer.updateTimer();
            timer.renderPartialTicks = f;
          } else {
            timer.updateTimer();
          }
          long l1 = System.nanoTime();
          for (int j = 0; j < timer.elapsedTicks; j++) {
            ticksRan++;
            try {
              runTick();
              continue;
            } catch (MinecraftException minecraftexception1) {
              theWorld = null;
            }
            changeWorld1(null);
            displayGuiScreen(new GuiConflictWarning());
          }

          long l2 = System.nanoTime() - l1;
          checkGLError("Pre render");
          RenderBlocks.fancyGrass = gameSettings.fancyGraphics;
          sndManager.func_338_a(thePlayer, timer.renderPartialTicks);
          GL11.glEnable(3553 /*GL_TEXTURE_2D*/);
          if (theWorld != null) {
            theWorld.updatingLighting();
          }
          if (!Keyboard.isKeyDown(65)) {
            Display.update();
          }
          if (thePlayer != null && thePlayer.isEntityInsideOpaqueBlock()) {
            gameSettings.thirdPersonView = false;
          }
          if (!skipRenderWorld) {
            if (playerController != null) {
              playerController.setPartialTime(timer.renderPartialTicks);
            }
            entityRenderer.updateCameraAndRender(timer.renderPartialTicks);
          }
          if (!Display.isActive()) {
            if (fullscreen) {
              toggleFullscreen();
            }
            Thread.sleep(10L);
          }
          if (gameSettings.showDebugInfo) {
            displayDebugInfo(l2);
          } else {
            prevFrameTime = System.nanoTime();
          }
          guiAchievement.updateAchievementWindow();
          Thread.yield();
          if (Keyboard.isKeyDown(65)) {
            Display.update();
          }
          screenshotListener();
          if (mcCanvas != null
              && !fullscreen
              && (mcCanvas.getWidth() != displayWidth || mcCanvas.getHeight() != displayHeight)) {
            displayWidth = mcCanvas.getWidth();
            displayHeight = mcCanvas.getHeight();
            if (displayWidth <= 0) {
              displayWidth = 1;
            }
            if (displayHeight <= 0) {
              displayHeight = 1;
            }
            resize(displayWidth, displayHeight);
          }
          checkGLError("Post render");
          i++;
          isGamePaused =
              !isMultiplayerWorld() && currentScreen != null && currentScreen.doesGuiPauseGame();
          while (System.currentTimeMillis() >= l + 1000L) {
            debug =
                (new StringBuilder())
                    .append(i)
                    .append(" fps, ")
                    .append(WorldRenderer.chunksUpdated)
                    .append(" chunk updates")
                    .toString();
            WorldRenderer.chunksUpdated = 0;
            l += 1000L;
            i = 0;
          }
        } catch (MinecraftException minecraftexception) {
          theWorld = null;
          changeWorld1(null);
          displayGuiScreen(new GuiConflictWarning());
        } catch (OutOfMemoryError outofmemoryerror) {
          func_28002_e();
          displayGuiScreen(new GuiErrorScreen());
          System.gc();
        }
      } while (true);
    } catch (MinecraftError minecrafterror) {
    } catch (Throwable throwable) {
      func_28002_e();
      throwable.printStackTrace();
      onMinecraftCrash(new UnexpectedThrowable("Unexpected error", throwable));
    } finally {
      shutdownMinecraftApplet();
    }
  }
示例#16
0
  /**
   * This starts the main game loop. This is the guts of the game. When the loop starts it checks to
   * see if the player has any lives left, if not, it prints "Game Over" and resets the game. If
   * there are lives left, it decides what the ghosts next move will be, detects any collisions, and
   * acts accordingly, and also gets input from the player
   */
  public void start() {
    Globals.state = ENEMY_HUNTER_STATE;
    Globals.game.setPlayer(new Player());
    player = Globals.game.getPlayer();
    player.setCenter(board.getPlayerStartPoint());
    newGame();
    paused = false;
    waiting = true;
    Point regenDoorPoint = board.getRegenDoor();
    Point regenPoint = board.getRegenPoint();
    Point playerPoint = player.getCenter();
    while ((this.isVisible()) && (player.getLives() >= 0)) {
      if (paused) {
        paintPauseScreen();
      }
      while (paused || stopped || waiting) {
        Thread.yield();
      }

      if (Globals.blipsLeft <= 0) {
        Globals.speed *= SPEED_MOD;
        resetCanvas();
        board.reset();
        Globals.blipsLeft = board.getBlipCount();
      }
      // now we need to see if the current state is enemy hunted
      if (Globals.state == ENEMY_HUNTED_STATE) {
        // now we need to see if we should go out of it
        if (Globals.timeUntilLeaveingHuntedState <= 0) {
          Globals.state = ENEMY_HUNTER_STATE;
          Globals.timeUntilLeaveingHuntedState = TIME_IN_HUNTED_STATE;
        } else {
          // we shouldn't, so we decrement the counter
          Globals.timeUntilLeaveingHuntedState -= Globals.speed;
        }
      }
      // move the player
      player.move(board.getMoveOptions(player), playerChoice);
      if (Globals.aiMode == FSA_AI_MODE) {
        // now updated the enemy movements
        for (int i = 0; i < enemies.length; i++) {
          // these are put here to reduce program jumping and cache misses as well
          Enemy enemy = enemies[i];
          int moveOptions = board.getMoveOptions(enemy);
          // first, we need to take apporpriate actions if we're on a regen tile
          if (board.getCurrentTile(enemy).isRegen()) {
            // first check to see if the enemy is alive
            if (!enemy.isAlive()) {
              // it's not, so we make it alive
              enemy.setAlive(true);
            }
            // now we tell the enemy to move towards the the door
            enemy.move(moveOptions, regenDoorPoint, true);
          } else {
            // We're not in the regen pen, so now we check if the enemy is alive
            if (!enemy.isAlive()) {
              // it's not, so we want to go towards the regen point
              enemy.move(moveOptions, regenPoint, false);
            } else {
              // the enemy is alive, so we tell it towards/away from the player
              enemy.move(moveOptions, playerPoint, false);
            }
          }
        }
      } else if (Globals.aiMode == ANN_AI_MODE) {
        // Globals.game.getNet().process(ANNTools.getBoardCondition(board, enemies, player));
        player.setInputValues(board);
        for (Enemy enemy : enemies) {
          enemy.setInputValues(board);
        }
        Globals.game.getNet().generateActivations();
        for (int i = 0; i < enemies.length; i++) {
          // Last 2 values don't matter here
          enemies[i].move(
              board.getMoveOptions(enemies[i]),
              board.getRegenDoor(),
              board.getCurrentTile(enemies[i]).isRegen());
        }
      }

      // no we check for collisions and act appropriately
      checkCollision();
      // check to see if we should notify the game that we have stepped
      if (Globals.trainingMode != TRAINING_MODE_OFF) {
        // we should, so we do.
        Globals.game.step();
      }
      // And now we sleep. The sleep time is the current speed
      try {
        Thread.sleep(Globals.speed);
      } catch (InterruptedException e) {
        break;
      }
      // no update the screen
      update();
    }
    if (player.getLives() <= 0) {
      paintGameOver();
      try {
        Thread.sleep(2500);
      } catch (InterruptedException e) {
        // DO nothing
      }
      newGame();
      start();
    }
  }
示例#17
0
  public void run() {
    Thread me = Thread.currentThread();
    while (getSize().width <= 0) {
      try {
        anim.sleep(500);
      } catch (InterruptedException e) {
        return;
      }
    }

    Graphics2D g2d = null;
    Graphics2D BufferG2D = null;
    Graphics2D ScreenG2D = null;
    BasicStroke solid = new BasicStroke(9.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 9.0f);
    GeneralPath gp = new GeneralPath(GeneralPath.WIND_NON_ZERO);
    int rule = AlphaComposite.SRC_OVER;
    AlphaComposite opaque = AlphaComposite.SrcOver;
    AlphaComposite blend = AlphaComposite.getInstance(rule, 0.9f);
    AlphaComposite set = AlphaComposite.Src;
    int frame = 0;
    int frametmp = 0;
    Dimension oldSize = getSize();
    Shape clippath = null;
    while (anim == me) {
      Dimension size = getSize();
      if (size.width != oldSize.width || size.height != oldSize.height) {
        img = null;
        clippath = null;
        if (BufferG2D != null) {
          BufferG2D.dispose();
          BufferG2D = null;
        }
        if (ScreenG2D != null) {
          ScreenG2D.dispose();
          ScreenG2D = null;
        }
      }
      oldSize = size;

      if (img == null) {
        img = (BufferedImage) createImage(size.width, size.height);
      }

      if (BufferG2D == null) {
        BufferG2D = img.createGraphics();
        BufferG2D.setRenderingHint(
            RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT);
        BufferG2D.setClip(clippath);
      }
      g2d = BufferG2D;

      float[] ctrlpts;
      for (int i = 0; i < animpts.length; i += 2) {
        animate(animpts, deltas, i + 0, size.width);
        animate(animpts, deltas, i + 1, size.height);
      }
      ctrlpts = animpts;
      int len = ctrlpts.length;
      gp.reset();
      int dir = 0;
      float prevx = ctrlpts[len - 2];
      float prevy = ctrlpts[len - 1];
      float curx = ctrlpts[0];
      float cury = ctrlpts[1];
      float midx = (curx + prevx) / 2.0f;
      float midy = (cury + prevy) / 2.0f;
      gp.moveTo(midx, midy);
      for (int i = 2; i <= ctrlpts.length; i += 2) {
        float x1 = (midx + curx) / 2.0f;
        float y1 = (midy + cury) / 2.0f;
        prevx = curx;
        prevy = cury;
        if (i < ctrlpts.length) {
          curx = ctrlpts[i + 0];
          cury = ctrlpts[i + 1];
        } else {
          curx = ctrlpts[0];
          cury = ctrlpts[1];
        }
        midx = (curx + prevx) / 2.0f;
        midy = (cury + prevy) / 2.0f;
        float x2 = (prevx + midx) / 2.0f;
        float y2 = (prevy + midy) / 2.0f;
        gp.curveTo(x1, y1, x2, y2, midx, midy);
      }
      gp.closePath();

      g2d.setComposite(set);
      g2d.setBackground(backgroundColor);
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);

      if (bgChanged || bounds == null) {
        bounds = new Rectangle(0, 0, getWidth(), getHeight());
        bgChanged = false;
      }
      // g2d.clearRect(bounds.x-5, bounds.y-5, bounds.x + bounds.width + 5, bounds.y + bounds.height
      // + 5);
      g2d.clearRect(0, 0, getWidth(), getHeight());

      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.setColor(outerColor);
      g2d.setComposite(opaque);
      g2d.setStroke(solid);
      g2d.draw(gp);
      g2d.setPaint(gradient);

      if (!bgChanged) {
        bounds = gp.getBounds();
      } else {
        bounds = new Rectangle(0, 0, getWidth(), getHeight());
        bgChanged = false;
      }
      gradient =
          new GradientPaint(
              bounds.x,
              bounds.y,
              gradientColorA,
              bounds.x + bounds.width,
              bounds.y + bounds.height,
              gradientColorB,
              true);
      g2d.setComposite(blend);
      g2d.fill(gp);

      if (g2d == BufferG2D) {
        repaint();
      }
      ++frame;
      Thread.yield();
    }
    if (g2d != null) {
      g2d.dispose();
    }
  }