C++ (Qt)void TransitionClock( const QImage & src1, const QImage & src2, QImage & dst, qreal clock_angle_in_radian ){// все 3 имеджа должны быть ARGB 32 и иметь одинаковый размер int width = src1.width(), height = src1.height(); qreal cntrX = width * 0.5, cntrY = height * 0.5; for (int y = 0; y < height; ++y) { const quint32 * p1 = (quint32 *) src1.scanLine(y); const quint32 * p2 = (quint32 *) src2.scanLine(y); quint32 * p3 = (quint32 *) dst.scanLine(y); for (int x = 0; x < width; ++x) { qreal pt_angle = atan2(cntrY - y, x - cntrX); pt_angle = PI * 0.5 - pt_angle; // rotate direction = clockwise, start = north if (pt_angle < 0) pt_angle += PI * 2; // to range [0..PI *2] p3[x] = (pt_angle < clock_angle_in_radian) ? p2[x] : p1[x]; } }}
C++ (Qt)// start, end определяют треугольник, в пределах которого нужно обновить изображениеvoid BackgroundCanvas::rayMoved(qreal start, qreal end){ // deg => rad start *= .01745329252; end *= .01745329252; // определить фрагмент изображения для обновления QPoint rayA = PPointF::toCartesian(start, qMin(m_height,m_width)/2).toPoint(); // полярные координаты QPoint rayB = PPointF::toCartesian(end, qMin(m_height,m_width)/2).toPoint(); int x1 = qMin(0, qMin(rayA.x(), rayB.x())) + m_height/2; int x2 = qMax(0, qMax(rayA.x(), rayB.x())) + m_height/2; int y1 = qMin(0, qMin(rayA.y(), rayB.y())) + m_height/2; int y2 = qMax(0, qMax(rayA.y(), rayB.y())) + m_height/2; int x, y; for(y=y1; y<y2; ++y) { const quint32 *src = (quint32*) m_source->scanLine(y); quint32 *dst = (quint32*) m_destination->scanLine(y); for(x=x1; x<x2; ++x) { qreal angle_p = atan2(y-m_y0, x-m_x0); if( angle_p < 0 ) angle_p += 2. * M_PI; dst[x] = ( start < angle_p && angle_p <= end ) ? src[x] : dst[x] ; if( start > end ) dst[x] = ( ( start <= angle_p && angle_p <= 2 * M_PI ) || ( 0. <= angle_p && angle_p <= end ) ) ? src[x] : dst[x]; } }}