/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set et sw=2 ts=2: */ /*************************************************************************** * outputwindow.cc * * Sat Aug 4 13:44:41 CEST 2012 * Copyright 2012 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of Kaiman. * * Kaiman is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Kaiman is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Kaiman; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "outputwindow.h" #include #include #include #include OutputWindow::OutputWindow() { resize(1000, 1000); //QTransform t; //t.scale(0.2, 0.2); //kaiman = kaiman.transformed(t, Qt::SmoothTransformation); connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); timer.setSingleShot(true); timer.start(25); reset(); } void OutputWindow::stopScript() { stop = true; } void OutputWindow::loadPen(QString file) { sem.acquire(); penfile = file; loadpen = true; } void OutputWindow::setScale(double s) { scale = s; } double OutputWindow::getScale() const { return scale; } void OutputWindow::setSpeed(int s) { if(s < 1) { speed = 100; } else if(s > 100) { speed = 1; } else { speed = 101 - s; } sem.acquire(); } void OutputWindow::setColour(int r, int g, int b, int a) { colour = QColor(r, g, b, a); sem.acquire(); } double OutputWindow::coordX() { return x; } double OutputWindow::coordY() { return y; } QImage OutputWindow::acquire(bool includePen) { double scale = 2.0; // Minimum picture size is 32x32 double minx = -16; double miny = -16; double maxx = 16; double maxy = 16; for(const auto& line : lines) { maxx = std::max(line.line.p1().x() * scale, maxx); maxx = std::max(line.line.p2().x() * scale, maxx); maxy = std::max(line.line.p1().y() * scale, maxy); maxy = std::max(line.line.p2().y() * scale, maxy); minx = std::min(line.line.p1().x() * scale, minx); minx = std::min(line.line.p2().x() * scale, minx); miny = std::min(line.line.p1().y() * scale, miny); miny = std::min(line.line.p2().y() * scale, miny); } int border = 100 * scale; int width = maxx - minx + border*2; int height = maxy - miny + border*2; QImage img({width, height}, QImage::Format_ARGB32); img.fill(QColor(0,0,0,0)); QPainter painter(&img); paint(painter, {-minx + border, -miny + border}, includePen, scale); return img; } void OutputWindow::timeout() { //x++; //y++; //r++; repaint(); timer.start(25); } void OutputWindow::reset() { speed = 50; penfile = "gfx/kaiman.png"; loadpen = true; lines.clear(); current_points.clear(); x = 0; y = 0; r = 0; colour = QColor(150, 0, 0, 150); stop = false; offset = { width() / 2.0, height() / 2.0 }; while(sem.tryAcquire()) { } } void OutputWindow::mouseMoveEvent(QMouseEvent* event) { if(dragging) { dragOffset = event->pos() - dragOffsetOrigo; } } void OutputWindow::mousePressEvent(QMouseEvent* event) { if(event->button() == Qt::MiddleButton) { dragging = true; dragOffsetOrigo = event->pos(); dragOffset = {}; } } void OutputWindow::mouseReleaseEvent(QMouseEvent* event) { if(event->button() == Qt::MiddleButton) { dragging = false; offset += dragOffset; dragOffset = dragOffsetOrigo = {}; } } void OutputWindow::wheelEvent(QWheelEvent* event) { double delta = event->delta() / 120.0 * scale; scale += delta / 10.0; if(scale < 0.3) { scale = 0.3; } } void OutputWindow::paintEvent(QPaintEvent *) { //sem.acquire(); QPainter painter(this); paint(painter, { offset.x() + dragOffset.x(), offset.y() + dragOffset.y() }, true, scale); sem.release(); } void OutputWindow::paint(QPainter& p, const QPointF& offset, bool includePen, double scale) { if(loadpen) { QPixmap img(penfile); kaiman = img.toImage(); loadpen = false; } if(includePen) { QTransform t; t.rotate(-r + 90); auto m = std::max(kaiman.width(),kaiman.height()); t.scale((100.0 / m * scale), (100.0 / m * scale) ); QImage img = kaiman.transformed(t, Qt::SmoothTransformation); p.drawImage((x * scale) - img.width()/2 + offset.x(), (y * scale) - img.height()/2 + offset.y(), img); } QTransform gt; gt.translate(offset.x(), offset.y()); gt.scale(scale, scale); p.setTransform(gt); QPen pen; pen.setWidth(4); //p.setPen(pen); //p.drawLines(points); for(int i = 0; i < lines.size(); i++) { ColLine l = lines[i]; pen.setColor(l.colour); p.setPen(pen); QLineF line = l.line; line.setP1(line.p1()); line.setP2(line.p2()); p.drawLine(line); } pen.setWidth(2); pen.setStyle(Qt::DotLine); // pen.setCapStyle(Qt::RoundCap); pen.setColor(Qt::black); // pen.setColor(colour); p.setPen(pen); for(int i = 0; i < current_points.size(); i+=2) { QPointF p1 = current_points[i]; QPointF p2 = current_points[i + 1]; p.drawLine(QLineF(p1, p2)); } QColor c = colour; c.setAlpha(c.alpha() / 4); pen.setStyle(Qt::SolidLine); pen.setWidth(4); pen.setColor(c); p.setPen(pen); for(int i = 0; i < current_points.size(); i+=2) { QPointF p1 = current_points[i]; QPointF p2 = current_points[i + 1]; p.drawLine(QLineF(p1, p2)); } } static inline int sign(int x) { if(x > 0) { return 1; } return -1; } void OutputWindow::forward(double dist) { sem.acquire(); float target_x = sin(r * (M_PI / 180.0)) * dist; float target_y = cos(r * (M_PI / 180.0)) * dist; float source_x = x; float source_y = y; int spd = abs(dist * speed) / 60;//28; for(int i = 0; i < spd; i++) { if(stop) return; float d = (float)i / (float)spd; current_points.clear(); current_points.append(QPointF(source_x, source_y)); x = source_x * (1 - d) + (source_x + target_x) * d; y = source_y * (1 - d) + (source_y + target_y) * d; current_points.append(QPointF(x, y)); sem.acquire(); } x = source_x + target_x; y = source_y + target_y; ColLine l; l.colour = colour; l.line = QLine(QPoint(source_x, source_y), QPoint(x, y)); lines.append(l); current_points.clear(); sem.acquire(); } // Turn x degrees void OutputWindow::turn(double x) { double spd = (speed * abs(x) / 80.0); double offset = this->r; sem.acquire(); for(int i = 0; i < spd; i++) { if(stop) { return; } double p = (double)i / spd; this->r = offset + x * p; sem.acquire(); } this->r = offset + x; sem.acquire(); }