void WarpPerspectiveBilinear::keyDown( KeyEvent &event )
{
	if( !isEditModeEnabled() )
		return;
	if( mSelected >= mPoints.size() )
		return;

	switch( event.getCode() ) {
	case KeyEvent::KEY_UP:
	case KeyEvent::KEY_DOWN:
	case KeyEvent::KEY_LEFT:
	case KeyEvent::KEY_RIGHT:
		// make sure cursor keys are handled by 1 warp only
		if( !isCorner( mSelected ) )
			mWarp->keyDown( event );
		if( !event.isHandled() )
			WarpBilinear::keyDown( event );
		break;
	case KeyEvent::KEY_F9:
	case KeyEvent::KEY_F10:
		// let only the Perspective warp handle rotating
		mWarp->keyDown( event );
		break;
	case KeyEvent::KEY_F11:
	case KeyEvent::KEY_F12:
		// let only the Bilinear warp handle flipping
		WarpBilinear::keyDown( event );
		break;
	default:
		// let both warps handle the other keyDown events
		mWarp->keyDown( event );
		WarpBilinear::keyDown( event );
		break;
	}
}
void FieldWall::init()
{
	mType=FieldType::FIELD_WALL;

	if(isCorner())
	{
		static int howManyCorners = 0;

		mFieldSprite.setTexture(ResourceManager::getTexture(ResourceManager::FIELD_WALL_CORNER));
		
		sf::IntRect subTexture(0, 0, gi::FIELD_WIDTH, gi::FIELD_HEIGHT); // always 4 corners

		subTexture.top = gi::FIELD_HEIGHT * howManyCorners++;

		mFieldSprite.setTextureRect(subTexture);
	}
	else if(getPosition().x == 0 || getPosition().x == gi::WINDOW_WIDTH - gi::FIELD_WIDTH) //vertical walls
	{
		mFieldSprite.setTexture(ResourceManager::getTexture(ResourceManager::FIELD_WALL_VERTICAL));
		mFieldSprite.setTextureRect(sf::IntRect(0, getPosition().x == 0 ? 0 : gi::FIELD_HEIGHT, gi::FIELD_WIDTH, gi::FIELD_HEIGHT));
	}
	else if(getPosition().y == 0 || getPosition().y == gi::WINDOW_HEIGHT - gi::FIELD_HEIGHT) //horizontal walls
	{
		mFieldSprite.setTexture(ResourceManager::getTexture(ResourceManager::FIELD_WALL_HORIZONTAL));
		mFieldSprite.setTextureRect(sf::IntRect(0, getPosition().y == 0 ? 0 : gi::FIELD_HEIGHT, gi::FIELD_WIDTH, gi::FIELD_HEIGHT));
	}
	else //wall in the middle
	{
		mFieldSprite.setTexture(ResourceManager::getTexture(ResourceManager::FIELD_WALL_MIDDLE));
	}
}
bool WarpPerspectiveBilinear::keyDown(KeyEvent event)
{
	if( ! isEditModeEnabled() ) return false;
	if(mSelected >= mPoints.size()) return false;

	switch( event.getCode() ) {
		case KeyEvent::KEY_UP:
		case KeyEvent::KEY_DOWN:
		case KeyEvent::KEY_LEFT:
		case KeyEvent::KEY_RIGHT: {
			// make sure cursor keys are handled by 1 warp only
			if(!isCorner( mSelected ) || !mWarp->keyDown(event)) 
				return WarpBilinear::keyDown( event );

			return true;
		}
		break;
		case KeyEvent::KEY_F9:
		case KeyEvent::KEY_F10:
			// let only the Perspective warp handle rotating 
			return mWarp->keyDown(event);
		case KeyEvent::KEY_F11:
		case KeyEvent::KEY_F12:
			// let only the Bilinear warp handle flipping
			return WarpBilinear::keyDown( event );
		default: 
			{
				// let both warps handle the other keyDown events
				bool handled = mWarp->keyDown(event);
				return (WarpBilinear::keyDown( event ) || handled);
			}
		 break;
	}
}
void WarpPerspectiveBilinear::selectControlPoint(unsigned index)
{
	// depending on index, select perspective or bilinear control point
	if( isCorner( index ) ) {
		mWarp->selectControlPoint( convertIndex( index ) );
	}
	else {
		mWarp->deselectControlPoint();
	}

	// always select bilinear control point, which we use to keep track of editing
	Warp::selectControlPoint( index );	
}
void WarpPerspectiveBilinear::moveControlPoint(unsigned index, const Vec2f &shift)
{
	// depending on index, move perspective or bilinear control point
	if( isCorner( index ) ) {
		// perspective: simply move the control point
		mWarp->moveControlPoint( convertIndex( index ), shift );
	}
	else {
		// bilinear: transform control point from normalized screen space to warped space
		Vec2f pt = getControlPoint(index);
		setControlPoint(index, pt + shift);
	}
}
bool WarpPerspectiveBilinear::mouseDrag( MouseEvent event )
{
	if( !isEditModeEnabled() ) return false;
	if(mSelected >= mPoints.size()) return false;

	// depending on selected control point, let perspective or bilinear warp handle it
	if( isCorner( mSelected ) ) {
		return mWarp->mouseDrag( event );
	}
	else {
		return Warp::mouseDrag( event );
	}
}
Vec2f WarpPerspectiveBilinear::getControlPoint(unsigned index) const
{
	// depending on index, return perspective or bilinear control point
	if( isCorner( index ) ) {
		// perspective: simply return one of the corners
		return mWarp->getControlPoint( convertIndex( index ) );
	}
	else {
		// bilinear: transform control point from warped space to normalized screen space
		Vec2f p = Warp::getControlPoint(index) * Vec2f( mWarp->getSize() );
		Vec3f pt = mWarp->getTransform().transformPoint( Vec3f(p.x, p.y, 0.0f) );

		return Vec2f(pt.x, pt.y) / mWindowSize;
	}
}
void WarpPerspectiveBilinear::mouseDown( MouseEvent &event )
{
	if( !isEditModeEnabled() )
		return;
	if( mSelected >= mPoints.size() )
		return;

	// depending on selected control point, let perspective or bilinear warp handle it
	if( isCorner( mSelected ) ) {
		mWarp->mouseDown( event );
	}
	else {
		Warp::mouseDown( event );
	}
}
void WarpPerspectiveBilinear::setControlPoint(unsigned index, const Vec2f &pos)
{
	// depending on index, set perspective or bilinear control point
	if( isCorner( index ) ) {
		// perspective: simply set the control point
		mWarp->setControlPoint( convertIndex( index ), pos );
	}
	else {
		// bilinear:: transform control point from normalized screen space to warped space
		Vec2f p = pos * mWindowSize;
		Vec3f pt = mWarp->getInvertedTransform().transformPoint( Vec3f(p.x, p.y, 0.0f) );

		Vec2f size( mWarp->getSize() );
		Warp::setControlPoint( index, Vec2f(pt.x, pt.y) / size );
	}
}
    NeighborBitset update(float dTime)
    {
    
    NeighborBitset neighbors;
    neighbors.reserve(mHeight);
    std::vector<CA::State> bitLine;
    bitLine.reserve(mWidth);

    for(int i = 0; i < mHeight; i++){
        bitLine.clear();
        for(int j = 0; j < mWidth; j++){
            if(mCells[i+j*mWidth].get() == mCenter.get() || isCorner(i, j)){
               bitLine.push_back(CA::State::OFF);
            }
            else{
                bitLine.push_back(mCells[i+j*mWidth]->getState() == true ? CA::State::ON : CA::State::OFF);
            }
        }
        neighbors.push_back(bitLine);
    }

    return neighbors;

/*    	NeighborBitset neighbors;
        neighbors.reserve(mHeight);
        std::vector<CA::State> bitLine;
        bitLine.reserve(mWidth);

        for(int i = 0; i < mHeight; i++){
            bitLine.clear();
            for(int j = 0; j < mWidth; j++){
                if(mCells[i+j*mHeight].get() == mCenter.get() || isCorner(i, j)){
                   bitLine.push_back(CA::State::OFF);
                }
                else{
                    bitLine.push_back(mCells[i+j*mHeight]->getState() == true ? CA::State::ON : CA::State::OFF);
                }
            }
            neighbors.push_back(bitLine);
        }

        return neighbors;
*/
    }
vec2 WarpPerspectiveBilinear::getControlPoint( unsigned index ) const
{
	// depending on index, return perspective or bilinear control point
	if( isCorner( index ) ) {
		// perspective: simply return one of the corners
		return mWarp->getControlPoint( convertIndex( index ) );
	}
	else {
		// bilinear: transform control point from warped space to normalized screen space
		vec2 p = Warp::getControlPoint( index ) * vec2( mWarp->getSize() );
		vec4 pt = mWarp->getTransform() * vec4( p.x, p.y, 0, 1 );

		if( pt.w != 0 )
			pt.w = 1 / pt.w;
		pt *= pt.w;

		return vec2( pt.x, pt.y ) / mWindowSize;
	}
}
void WarpPerspectiveBilinear::setControlPoint( unsigned index, const vec2 &pos )
{
	// depending on index, set perspective or bilinear control point
	if( isCorner( index ) ) {
		// perspective: simply set the control point
		mWarp->setControlPoint( convertIndex( index ), pos );
	}
	else {
		// bilinear:: transform control point from normalized screen space to warped space
		vec2 p = pos * mWindowSize;
		vec4 pt = mWarp->getInvertedTransform() * vec4( p.x, p.y, 0, 1 );

		if( pt.w != 0 )
			pt.w = 1 / pt.w;
		pt *= pt.w;

		vec2 size( mWarp->getSize() );
		Warp::setControlPoint( index, vec2( pt.x, pt.y ) / size );
	}
}
Exemple #13
0
	void compute_splines()
	{
		// get point tangents first
		std::cout << "HermiteSpline2D: compute_splines(): Getting tangents of boundary points." << std::endl;
		for(int ipoin = 0; ipoin < m->gnbpoin(); ipoin++)
		{
			// in 2D, bpoints is not an array of stl std::vectors - we know there are only two faces surrounding each boundary point
			// if edge is bounded by (x1,y1) and (x2,y2), tangent to edge is (x2-x1)i + (y2-y1)j

			// first check if this point belongs to a face that needs to be reconstructed
			if(toRec(m->gbpoints(ipoin,1))==1  || toRec(m->gbpoints(ipoin,2))==1)
			{

				std::vector<int> en(2);

				// get intfac faces containing this point
				en[0] = m->gbpoints(ipoin,1);
				en[1] = m->gbpoints(ipoin,2);
				//std::cout << en[0] << " " << en[1] << std::endl;

				double xt, yt, dotx = 1, doty = 1, mag;

				// iterate over the two faces containing ipoin
				for(int i = 0; i < 2; i++)
				{
					xt = m->gcoords(m->gintfac(en[i],3),0) - m->gcoords(m->gintfac(en[i],2),0);
					yt = m->gcoords(m->gintfac(en[i],3),1) - m->gcoords(m->gintfac(en[i],2),1);
					mag = sqrt(xt*xt + yt*yt);
					ptangents(m->gbpoints(ipoin,0),0) += xt;
					ptangents(m->gbpoints(ipoin,0),1) += yt;
					dotx *= xt/mag;
					doty *= yt/mag;
				}
				ptangents(m->gbpoints(ipoin,0),0) /= 2.0;
				ptangents(m->gbpoints(ipoin,0),1) /= 2.0;

				// now normalize the averaged tangent std::vector
				mag = sqrt(ptangents(m->gbpoints(ipoin,0),0)*ptangents(m->gbpoints(ipoin,0),0) + ptangents(m->gbpoints(ipoin,0),1)*ptangents(m->gbpoints(ipoin,0),1));
				ptangents(m->gbpoints(ipoin,0),0) /= mag;
				ptangents(m->gbpoints(ipoin,0),1) /= mag;

				// check if this is a corner point
				double dotp = dotx+doty;			// dot product of tangents of the two faces
				if(dotp < cos(angle_threshold)) { 
					isCorner(m->gbpoints(ipoin,0)) = 1;				// set isCorner for global point number corresponding to boundary point ipoin
					std::cout << "Boundary point " << m->gbpoints(ipoin,0) << " is a corner point!" << std::endl;
				}
			}
		}

		// iterate over boundary faces of the mesh
		std::cout << "HermiteSpline2D: compute_splines(): Iterating over boundary faces to get tangents." << std::endl;
		std::vector<int> pnts(m->gnnofa());		// to store point numbers of points making up iface
		for(int iface = 0; iface < m->gnbface(); iface++)
		{
			if(toRec(iface) == 1)
			{
				// get tangent for this face
				for(int inofa = 0; inofa < m->gnnofa(); inofa++)
					pnts[inofa] = m->gintfac(iface,inofa+2);

				// magnitude of tangent (x2-x1)i + (y2-y1)j
				double mag = sqrt((m->gcoords(pnts[1],0)-m->gcoords(pnts[0],0))*(m->gcoords(pnts[1],0)-m->gcoords(pnts[0],0)) + (m->gcoords(pnts[1],1)-m->gcoords(pnts[0],1))*(m->gcoords(pnts[1],1)-m->gcoords(pnts[0],1)));
				
				for(int inofa = 0; inofa < m->gnnofa(); inofa++)
				{
					if(isCorner(pnts[inofa]) == 0)		// if not a corner
					{
						gallfa(iface,2*inofa) = ptangents(pnts[inofa],0);
						gallfa(iface,2*inofa+1) = ptangents(pnts[inofa],1);
					}
					else								// if pnts[inofa] is a corner, use this face's tangent at that point
					{
						gallfa(iface,2*inofa) = (m->gcoords(pnts[1],0) - m->gcoords(pnts[0],0))/mag;
						gallfa(iface,2*inofa+1) = (m->gcoords(pnts[1],1) - m->gcoords(pnts[0],1))/mag;
					}
				}

				/* Note that gallfa(*,0) contains x-component of tangent at point 1, gallfa(*,1) contains y-component of tangent at point 1,
				    gallfa(*,2) contains x-component of tangent at point 2, and gallfa(*,3) contains y-component of tangent at points 2. */
			}
		}

		// iterate over boundary faces of mesh again to calculate geometric spline coeffs from gallfa and intfac
		std::cout << "HermiteSpline2d: compute_splines(): Iterating over boundary faces again to compute geometric coefficients of the splines" << std::endl;
		for(int iface = 0; iface < m->gnbface(); iface++)
			if(toRec(iface) == 1)
			{
				for(int idim = 0; idim < m->gndim(); idim++)
				{
					cf[idim](iface,0) = m->gcoords(m->gintfac(iface,2),idim);
					cf[idim](iface,1) = m->gcoords(m->gintfac(iface,3),idim);
					cf[idim](iface,2) = gallfa(iface,idim);
					cf[idim](iface,3) = gallfa(iface,idim+2);
				}
			}
	}
Exemple #14
0
void edgeColoringSimple(Shape &shape, double angleThreshold, unsigned long long seed) {
    double crossThreshold = sin(angleThreshold);
    std::vector<int> corners;
    for (std::vector<Contour>::iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) {
        // Identify corners
        corners.clear();
        if (!contour->edges.empty()) {
            Vector2 prevDirection = (*(contour->edges.end()-1))->direction(1);
            int index = 0;
            for (std::vector<EdgeHolder>::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge, ++index) {
                if (isCorner(prevDirection.normalize(), (*edge)->direction(0).normalize(), crossThreshold))
                    corners.push_back(index);
                prevDirection = (*edge)->direction(1);
            }
        }

        // Smooth contour
        if (corners.empty())
            for (std::vector<EdgeHolder>::iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge)
                (*edge)->color = WHITE;
        // "Teardrop" case
        else if (corners.size() == 1) {
            EdgeColor colors[3] = { WHITE, WHITE };
            switchColor(colors[0], seed);
            switchColor(colors[2] = colors[0], seed);
            int corner = corners[0];
            if (contour->edges.size() >= 3) {
                int m = contour->edges.size();
                for (int i = 0; i < m; ++i)
                    contour->edges[(corner+i)%m]->color = (colors+1)[int(3+2.875*i/(m-1)-1.4375+.5)-3];
            } else if (contour->edges.size() >= 1) {
                // Less than three edge segments for three colors => edges must be split
                EdgeSegment *parts[7] = { };
                contour->edges[0]->splitInThirds(parts[0+3*corner], parts[1+3*corner], parts[2+3*corner]);
                if (contour->edges.size() >= 2) {
                    contour->edges[1]->splitInThirds(parts[3-3*corner], parts[4-3*corner], parts[5-3*corner]);
                    parts[0]->color = parts[1]->color = colors[0];
                    parts[2]->color = parts[3]->color = colors[1];
                    parts[4]->color = parts[5]->color = colors[2];
                } else {
                    parts[0]->color = colors[0];
                    parts[1]->color = colors[1];
                    parts[2]->color = colors[2];
                }
                contour->edges.clear();
                for (int i = 0; parts[i]; ++i)
                    contour->edges.push_back(EdgeHolder(parts[i]));
            }
        }
        // Multiple corners
        else {
            int cornerCount = corners.size();
            int spline = 0;
            int start = corners[0];
            int m = contour->edges.size();
            EdgeColor color = WHITE;
            switchColor(color, seed);
            EdgeColor initialColor = color;
            for (int i = 0; i < m; ++i) {
                int index = (start+i)%m;
                if (spline+1 < cornerCount && corners[spline+1] == index) {
                    ++spline;
                    switchColor(color, seed, EdgeColor((spline == cornerCount-1)*initialColor));
                }
                contour->edges[index]->color = color;
            }
        }
    }
}