Пример #1
0
void SprayBrush::paintMetaballs(KisPaintDeviceSP dev, const KisPaintInformation &info, const KoColor &painterColor) {
    // TODO: make adjustable?
    qreal MIN_TRESHOLD = m_mintresh;
    qreal MAX_TRESHOLD = m_maxtresh;

//    dbgPlugins << "MAX " << MAX_TRESHOLD;
//    dbgPlugins << "MIN " << MIN_TRESHOLD;

    KoColor color = painterColor;
    qreal posX = info.pos().x();
    qreal posY = info.pos().y();

    //int points = m_coverage * (m_radius * m_radius * M_PI);
    qreal ballRadius = m_width * 0.5;

    // generate metaballs
    QList<Metaball> list;
    for (int i = 0; i < m_particlesCount ; i++){
        qreal x = (2 * drand48() * m_radius) - m_radius;
        qreal y = (2 * drand48() * m_radius) - m_radius;
        list.append(
                    Metaball( x, 
                              y ,
                              drand48() *  ballRadius)
                    );
    }

 
    // paint it
    KisRandomAccessor accessor = dev->createRandomAccessor(0, 0);

    qreal sum = 0.0;
    m_computeArea.translate( -qRound(posX), -qRound(posY) );
    for (int y = m_computeArea.y(); y <= m_computeArea.height(); y++){
        for (int x = m_computeArea.x() ; x <= m_computeArea.width(); x++){

            sum = 0.0;        

            for (int i = 0; i < m_particlesCount; i++){
                sum += list[i].equation(x, y );
            }
           
            if (sum >= MIN_TRESHOLD && sum <= MAX_TRESHOLD){
                    if (sum < 0.0) sum = 0.0;
                    if (sum > 1.0) sum = 1.0;

                    color.setOpacity(OPACITY_OPAQUE * sum);
                    accessor.moveTo( x + posX ,y + posY );
                    memcpy(accessor.rawData(), color.data(), dev->colorSpace()->pixelSize() );
            }
        }
    }
    m_computeArea.translate( qRound(posX), qRound(posY) );

#if 0        
        KisPainter dabPainter(dev);
        dabPainter.setFillColor(color);
        dabPainter.setPaintColor(color);
        dabPainter.setFillStyle(KisPainter::FillStyleForegroundColor);

        for (int i = 0; i < m_particlesCount; i++){
                qreal x = list[i].x() + posX;
                qreal y = list[i].y() + posY;
                dabPainter.paintEllipse(x, y, list[i].radius() * 2,list[i].radius() * 2);
        }
#endif

}
Пример #2
0
int GenLagoonZone::makeItRain(int numLakes, int tam){
	int screenN; //actual screen number
	int screenX, screenY;  //coordenadas X Y de la screen Actual
	int tileX, tileY;  //coordenadas X Y sobre el mapa mundi del tile izq-arriba de la matriz de la pantalla
	int numSolids = 0;

	int tilesPerRow = overworld->getTileWorldSizeW();

	//int desp = screenList->size() / numLakes;
	int actualScreen = rand()%screenList->size();
	vector<bool> visited(screenList->size());
	bool foundNew = false;

	for(int i=0; i < numLakes; i++)
	{
		foundNew = false;
		screenN = screenList->at(actualScreen)->getScreenNumber();  //cogemos una screen

		//coordenadas de la screenN dentro del mundo.
		screenX = screenN % overworld->getWorldSizeW();
		screenY = screenN / overworld->getWorldSizeW();

		// coordenada X e Y del tile inicial de pantalla
		tileX = screenX * SCREEN_WIDTH;
		tileY = screenY * SCREEN_HEIGHT;
				
		Metaball meta = Metaball(rand()%SCREEN_WIDTH + tileX, rand()%SCREEN_HEIGHT + tileY, (float)(rand()%tam)+10, SHAPE_BALL);//rand()%3);
		meta.xm = rand()%50 * 0.01f;
		meta.ym = rand()%50 * 0.01f;
		lakes.push_back(meta);
		//actualScreen = (actualScreen + desp) % screenList->size();
		while(!foundNew)
		{
			actualScreen = rand()%screenList->size();
			if (!visited[actualScreen])
			{
				visited[actualScreen] = true;
				foundNew = true;
			}
		}
	}
	
	const float MAX_THRESHOLD = 1.1f;
	const float MIN_THRESHOLD = 0.9f;
	// Value to act as a summation of all Metaballs' fields applied to this particular tile
	float sum;

	// Pasamos por todas las screens de la zona
	for (int j=0; j<(int)screenList->size(); j++)
	{
		screenN = screenList->at(j)->getScreenNumber();
		screenX = screenN % overworld->getWorldSizeW();
		screenY = screenN / overworld->getWorldSizeW();
		// coordenada X e Y del tile inicial de pantalla
		tileX = screenX * SCREEN_WIDTH;
		tileY = screenY * SCREEN_HEIGHT;

		// Iterate over every tile on the screen
		for(int x = 0; x < SCREEN_WIDTH; x++){
			for(int y = 0; y < SCREEN_HEIGHT; y++){
				// Reset the summation
				sum = 0;

				// Iterate through every Metaball in the zone
				for(int i = 0; i < (int)lakes.size(); i++){
					sum += lakes[i].flow(tileX+x,tileY+y);
				}

				// Decide whether to draw a water tile
				if(sum >= MIN_THRESHOLD /*&& sum <= MAX_THRESHOLD*/)
				{
					screenList->at(j)->setSolid(x,y,2); // put water
					numSolids++;
				}
			}
		}
	}

	return numSolids;
}