⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mandelbrotdisplay.java

📁 This "zip" archive contains a complete copy of the web site. It should be usable on almost any compu
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
      if (ct < 0)    // Only -1 is possible, representing the Mandelbrot set.         return 0;  // RGB code for black      else if (paletteLength == 0)         return palette[ct];      else {         ct = ct % paletteLength;         return palette[ct];      }   }         /**    * Applies current palette to the image, or to any part of the image    * that has been completed, if a computation is in progress.    */   synchronized private void recomputeColors() {      if (OSC == null)         return;      if (palette == null)         createPalette();      for (int i = 0; i < iterationCounts.length; i++) {         if (iterationCounts[i] != null) {            for (int j = 0; j < imageWidth; j++)               rgb[j] = getColorForIterationCount(iterationCounts[i][j]);            OSC.setRGB(0, i, imageWidth, 1, rgb, 0, imageWidth);         }      }      repaint();   }   /**    * This is called to abort the current computation, if any.  Note that this method    * calls applyFinishedJobsToImage() to get the data from any outstanding finished    * jobs and apply it to the image.    */   synchronized private void stopComputing() {      if (!computing || OSC == null)         return;      applyJobsToImageTimer.stop();      applyFinishedJobsToImage();      finishedJobs = null;      computing = false;      setStatus(STATUS_READY);   }         /**    * This is called to start a new computation.    *    */   synchronized private void startComputing()  {      if (OSC == null)         return;      stopComputing();      Graphics g = OSC.getGraphics();      g.setColor(Color.LIGHT_GRAY);      g.fillRect(0,0,getWidth(),getHeight());      g.dispose();      repaint();      int processCount = Runtime.getRuntime().availableProcessors();      if (workerThreads == null) {         System.out.println("Creating " + processCount + " threads.");         workerThreads = new ComputeThread[processCount];         int priority = Thread.currentThread().getPriority() - 1;         for (int i = 0; i < processCount; i++) {            workerThreads[i] = new ComputeThread();            try {  // By setting the thread to be a "daemon" means that the                  // program can terminate even if this thread is still running.               workerThreads[i].setDaemon(true);            }            catch (Exception e) {               System.out.println("Can't set thread to daemaon.");            }            try {  // By reducing the priority of the thread, we ensure that                  // the user interface thread will be responsive.  Threads                   // of lower priority only run when no thread of higher                  // priority wants to run.               workerThreads[i].setPriority(priority);            }            catch (Exception e) {               System.out.println("Can't reduce worker thread priority?");            }            workerThreads[i].start();         }      }      checkAspect();      computationNumber++;      jobs = iterationCounts.length;      jobsAssigned = 0;      jobsCompleted = 0;      computing = true;      finishedJobs = new LinkedList<Job>();      for (int i = 0; i < iterationCounts.length; i++)         iterationCounts[i] = null;      notifyAll();      applyJobsToImageTimer.start();      setStatus(STATUS_WORKING);   }         /**    * Adjusts the xy limits to fit the aspect ratio of the display.  If the shape of    * the requested region in the plane does not match the shape of the display,    * then either the range of x values or the range of y values will be increased    * to make the shapes match.  Note that the full requested ranges are always shown.    * There just might be some extra parts of the plane visible on the top and bottom    * or sides.    */   private void checkAspect() {      xmin = xmin_requested;      xmax = xmax_requested;      if (xmax < xmin) {         double temp = xmin;         xmin = xmax;         xmax = temp;      }      ymin = ymin_requested;      ymax = ymax_requested;      if (ymax < ymin) {         double temp = ymax;         ymax = ymin;         ymin = temp;      }      double width = xmax - xmin;      double height = ymax - ymin;      double aspect = width/height;      double windowAspect = (double)getWidth()/(double)getHeight();      if (aspect < windowAspect) {         double newWidth = width*windowAspect/aspect;         double center = (xmax + xmin)/2;         xmax = center + newWidth/2;         xmin = center - newWidth/2;      }      else if (aspect > windowAspect) {         double newHeight = height*aspect/windowAspect;         double center = (ymax+ymin)/2;         ymax = center + newHeight/2;         ymin = center - newHeight/2;      }      dx = (xmax - xmin) / (getWidth() - 1);      dy = (ymax - ymin) / (getHeight() - 1);   }         /**    * Builds the array that holds the palette colors, based on current settings.    */   private void createPalette() {      if (paletteLength == 0)         palette = new int[maxIterations+1];      else         palette = new int[paletteLength];      for (int i = 0; i < palette.length; i++) {         float fraction = ((float)i)/(palette.length-1);         Color color;         switch (paletteType) {         case PALETTE_GRADIENT:            float r1 = gradientPaletteColor1.getRed()/255.0F;            float r2 = gradientPaletteColor2.getRed()/255.0F;            float r = Math.max(0,Math.min(1,r2*fraction + r1*(1-fraction)));            float g1 = gradientPaletteColor1.getGreen()/255.0F;            float g2 = gradientPaletteColor2.getGreen()/255.0F;            float g = Math.max(0,Math.min(1,g2*fraction + g1*(1-fraction)));            float b1 = gradientPaletteColor1.getBlue()/255.0F;            float b2 = gradientPaletteColor2.getBlue()/255.0F;            float b = Math.max(0,Math.min(1,b2*fraction + b1*(1-fraction)));            color = new Color(r,g,b);            break;         case PALETTE_SPECTRUM:            color = Color.getHSBColor(0.95F*fraction, 1, 1);            break;         case PALETTE_PALE_SPECTRUM:            color = Color.getHSBColor(0.95F*fraction, 0.6F, 1);            break;         case PALETTE_GRAYSCALE:            color = new Color(0.9F*fraction,0.9F*fraction,0.9F*fraction);            break;         default:            color = new Color(1-0.9F*fraction,1-0.9F*fraction,1-0.9F*fraction);            break;         }         palette[i] = color.getRGB();      }   }         /**    * Called by worker threads to get the next available job.  Computation of an    * image is broken up into a set of jobs that are performed by worker threads.    * This method is used to assign a new jobs to a thread each time it completes    * a job.  When no jobs are available (between computations or before any computation    * is begun), this method will block, which will keep the threads idle.    * @return    */   synchronized private Job getNextJob() {      while (!computing && !shutDown) {         try {            wait();         }         catch (InterruptedException e) {         }      }      if (shutDown)         return null;      else if (jobsAssigned >= jobs)         return null;      else {         Job job = new Job();         job.rowNumber = jobsAssigned;         job.xmin = xmin;         job.dx = dx;         job.y = ymax - jobsAssigned*dy;         job.maxIterations = maxIterations;         job.count = imageWidth;         job.computationNumber = computationNumber;         jobsAssigned++;         return job;      }   }         /**    * This is called by a worker thread when it finished a job.  The job is added to    * the queue of finished jobs.  If all jobs have been completed, the stopComputing()    * method is called.    */   synchronized private void finish(Job job) {      if (job.computationNumber != computationNumber)         return;      finishedJobs.addLast(job);      jobsCompleted++;      if (jobsCompleted == jobs)         stopComputing();   }         /**    * This class represents one job, which consists of doing the Mandelbrot computation     * loop and counting the iterations for each pixel in one row of pixels.  All the    * data necessary for the computation is stored in the job object.  The    * computationNumber identifies which computation this job is part of.  The output    * of the jobs, consisting of an array of iteration counts, is stored in the    * iterationCounts instance variable when the job finishes.    */   private class Job {      double xmin;      double dx;      double y;      int count;      int maxIterations;      int rowNumber;      int computationNumber;      int[] iterationCounts;      void compute() {         iterationCounts = new int[count];         for (int i = 0; i < count; i++) {            double x0 = xmin + i * dx;            double y0 = y;            double a = x0;            double b = y0;            int ct = 0;            while (a*a + b*b < 4.1) {               ct++;               if (ct > maxIterations) {                  ct = -1;                  break;               }               double newa = a*a - b*b + x0;               b = 2*a*b + y0;               a = newa;            }            iterationCounts[i] = ct;         }      }   }         /**    * Class that defines the worker threads.  The thread is very simple.  It just    * loops forever, getting jobs to do and carrying out each job.     */   private class ComputeThread extends Thread {      public void run() {         while (true) {            Job job = getNextJob();  // blocks until a job is available.            if (shutDown)               break;            if (job != null) {               job.compute();  // does the work.               finish(job);            }         }      }   }   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -