123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /*
- * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
- *
- * See the LICENSE file for terms of use.
- */
- #include <math.h>
- #include <stdio.h>
- #include <fstream>
- #include <iostream>
- #include <Wt/WResource>
- #include <Wt/WImage>
- #include <Wt/WPainter>
- #include <Wt/WPen>
- #include <Wt/WRasterImage>
- #include <Wt/Http/Response>
- #include "MandelbrotImage.h"
- namespace {
- class MandelbrotResource : public WResource
- {
- public:
- MandelbrotResource(MandelbrotImage *img,
- int64_t x, int64_t y, int w, int h)
- : img_(img),
- x_(x), y_(y), w_(w), h_(h)
- { }
- virtual ~MandelbrotResource() {
- beingDeleted();
- }
- void handleRequest(const Http::Request& request,
- Http::Response& response) {
- WRasterImage image("png", w_, h_);
- img_->generate(x_, y_, &image);
- image.handleRequest(request, response);
- }
- private:
- MandelbrotImage *img_;
- int64_t x_, y_;
- int w_, h_;
- };
- }
- MandelbrotImage::MandelbrotImage(int width, int height,
- int64_t virtualWidth,
- int64_t virtualHeight,
- double bx1, double by1,
- double bx2, double by2,
- WContainerWidget *parent)
- : WVirtualImage(width, height, virtualWidth, virtualHeight, 256, parent),
- bx1_(bx1), by1_(by1),
- bwidth_(bx2 - bx1), bheight_(by2 - by1),
- maxDepth_(50),
- bailOut2_(30*30)
- {
- enableDragging();
- redrawAll();
- scroll(width*2, virtualHeight/2 - height);
- }
- void MandelbrotImage::zoomIn()
- {
- resizeImage(imageWidth() * 2, imageHeight() * 2);
- scrollTo(currentTopLeftX() * 2 + viewPortWidth()/2,
- currentTopLeftY() * 2 + viewPortHeight()/2);
- }
- void MandelbrotImage::zoomOut()
- {
- scrollTo(currentTopLeftX() / 2 - viewPortWidth()/4,
- currentTopLeftY() / 2 - viewPortHeight()/4);
- resizeImage(std::max((int64_t)viewPortWidth(), imageWidth() / 2),
- std::max((int64_t)viewPortHeight(), imageHeight() / 2));
- }
- WResource *MandelbrotImage::render(int64_t x, int64_t y, int w, int h)
- {
- return new MandelbrotResource(this, x, y, w, h);
- }
- void MandelbrotImage::generate(int64_t x, int64_t y, WRasterImage *img)
- {
- int w = img->width().toPixels();
- int h = img->height().toPixels();
- std::cerr << "rendering: (" << x << "," << y << ") ("
- << x+w << "," << y+h << ")" << std::endl;
- for (int i = 0; i < w; ++i)
- for (int j = 0; j < h; ++j) {
- double bx = convertPixelX(x + i);
- double by = convertPixelY(y + j);
- double d = calcPixel(bx, by);
- int lowr = 100;
- int r, g, b;
- if (d == maxDepth_)
- r = g = b = 0;
- else {
- r = lowr + (int)((d * (255-lowr))/maxDepth_);
- g = 0 + (int)((d * 255)/maxDepth_);
- b = 0;
- }
- img->setPixel(i, j, WColor(r, g, b));
- }
- }
- double MandelbrotImage::convertPixelX(int64_t x) const
- {
- return bx1_ + ((double) (x) / imageWidth() * bwidth_);
- }
- double MandelbrotImage::convertPixelY(int64_t y) const
- {
- return by1_ + ((double) (y) / imageHeight() * bheight_);
- }
- double MandelbrotImage::currentX1() const
- {
- return convertPixelX(currentTopLeftX());
- }
- double MandelbrotImage::currentY1() const
- {
- return convertPixelY(currentTopLeftY());
- }
- double MandelbrotImage::currentX2() const
- {
- return convertPixelX(currentBottomRightX());
- }
- double MandelbrotImage::currentY2() const
- {
- return convertPixelY(currentBottomRightY());
- }
- double MandelbrotImage::calcPixel(double x, double y)
- {
- double x1 = x;
- double y1 = y;
- for (int i = 0; i < maxDepth_; ++i) {
- double xs = x1 * x1;
- double ys = y1 * y1;
- double x2 = xs - ys + x;
- double y2 = x1 * y1 * 2 + y;
- x1 = x2;
- y1 = y2;
- double z = xs + ys;
- if (xs + ys > bailOut2_)
- return (double)i + 1 - log(log(sqrt(z)))/log(2.0);
- }
- return maxDepth_;
- }
|