示例#1
0
void PuzzlePrinter::drawBlocks (const ksudoku::Puzzle * puzzle,
				const SKGraph * graph)
{
    QVector<int> edges (graph->size(), 0);	// One bitmap per cell.
    int order = graph->order();

    for (int n = 0; n < graph->cliqueCount(); n++) {
        // Find out which groups are blocks of cells, not rows or columns.
        QVector<int> clique = graph->clique (n);
        int x = graph->cellPosX (clique.at (0));
        int y = graph->cellPosY (clique.at (0));
        bool isRow = true;
        bool isCol = true;
        for (int k = 1; k < order; k++) {
            if (graph->cellPosX (clique.at (k)) != x) isRow = false;
            if (graph->cellPosY (clique.at (k)) != y) isCol = false;
        }
        if (isRow || isCol) continue;	// Skip rows and columns.

        // Mark the outside edges of each block.
	markEdges (clique, puzzle, graph, edges);
    }

    // Draw each cell in the puzzle.
    for (int n = 0; n < graph->size(); n++) {
        if (puzzle->value (n) < 0) {
            continue;				// Do not draw unused cells.
	}
	drawCell (graph->cellPosX (n), graph->cellPosY (n), edges.at (n));
    }
}
示例#2
0
void PuzzlePrinter::drawCages (const ksudoku::Puzzle * puzzle,
			       const SKGraph * graph, bool killerStyle)
{
    QVector<int> edges (graph->size(), 0);	// One bitmap per cell.
    for (int n = 0; n < graph->cageCount(); n++) {
        // Mark the outside edges of each cage.
	markEdges (graph->cage (n), puzzle, graph, edges);
    }
    if (killerStyle) {
	drawKillerSudokuCages (graph, edges);
    }
    else {
	// Draw each cell in the puzzle.
	for (int n = 0; n < graph->size(); n++) {
	    if (puzzle->value (n) < 0) {
		continue;			// Do not draw unused cells.
	    }
	    drawCell (graph->cellPosX (n), graph->cellPosY (n), edges.at (n));
	}
    }
    for (int n = 0; n < graph->cageCount(); n++) {
	drawCageLabel (graph, n, killerStyle);
    }
}
示例#3
0
bool poly::giftwrap(){
	
	if (surface.size() != 0) 
		surface.clear();
	
		// sort by x coordinate
	sortPoints(0);
		// first points is minimum x
	point p1 = points[0]; point* p1_ptr = &points[0];
	
		// 2nd point is found by 2d giftwrap in xy plane
	double maxDot = -1.;
	point p2; point* p2_ptr;
	for (int i=1;i<points.size();i++){
		point delta = points[i] - p1;
		delta.setX(2,0.);
		delta.makeUnit();
		double dDot = delta * point(0,1,0);
		
		std::cout << delta << " * " << points[i] << " : " << dDot << std::endl;
		if (maxDot < dDot){
			maxDot = dDot;
			p2 = points[i];
			p2_ptr = &points[i];
		}
		else if (dDot == maxDot)
			if ( (points[i] - p1).mag() < p2.mag()){
				maxDot = dDot;
				p2 = points[i];
				p2_ptr = &points[i];
			}
	}
	
	std::cout << p1 << "   " << p2 << std::endl;
	
		// project into plane defined by edge
		// between the first two points
	point dp = p2 - p1;
	dp.makeUnit();
		// origin in projected space
	point p0 = p1 - dp * (dp*p1);
	
	std::vector<point> pp;
	for (int i=1;i<points.size();i++)
		if (points[i] != p2)
			pp.push_back(points[i] - dp * (dp*points[i]) - p0);
	
		// find all possible pairs of points
	std::vector<point> ppairs1;
	std::vector<point> ppairs2;
	for (int i=0;i<pp.size();i++)
		for (int j=i+1;j<pp.size();j++){
			ppairs1.push_back(pp[i]);
			ppairs2.push_back(pp[j]);
		}
	
	pp.clear();

		// find the two points in this space 
		// with the largest opening angle
	point pp1, pp2;
	double minDot = 2.;
	for (int i=0;i<ppairs1.size();i++){
		double dDot = (ppairs1[i]*ppairs2[i])/(ppairs1[i].mag()*ppairs2[i].mag());
		if (dDot < minDot){
			minDot = dDot;
			pp1 = ppairs1[i];
			pp2 = ppairs2[i];
		}
		else if (dDot == minDot)
			if ( (ppairs1[i]-ppairs2[i]).mag() < (pp1-pp2).mag()){
				minDot = dDot;
				pp1 = ppairs1[i];
				pp2 = ppairs2[i];
			}
	}
	
	ppairs1.clear();
	ppairs2.clear();
	
		// find the poitns in original space
		// that match the points at large angles
		// these are the first two triangles
	for (int i=0;i<points.size();i++){
		point mPP = points[i] - dp*(dp*points[i]) - p0;
		if (mPP==pp1 || mPP==pp2)
			surface.push_back(tri(*p1_ptr,*p2_ptr,points[i]));
	}
	
	if (!markEdges())
		return false;
	
		//	for (int j=0;j<surface.size();j++)
		//		std::cout << "surface["<<j<< "] : " << surface[j] << std::endl;
		//	std::cout << std::endl;
	
	while (isSurfaceOpen()){
		edge mE;
		point mP;
		
		for (int i=0;i<surface.size();i++){
			
			if (!surface[i].getUnconnected(mE, mP))
				continue;
			
			dp = mE(1) - mE(0);
			dp.makeUnit();
			p0 = mE(1) - dp*(dp*mE(1));
			point mPP = mP - dp*(dp*mP) - p0;
			mPP = -mPP/(mPP.mag());
			
			std::vector<point> ppoints;
			for (int j=0;j<points.size();j++){
				if (surface[i].hasPoint(points[j]))
					continue;
				ppoints.push_back(points[j] - dp *(dp*points[j]) - p0);
			}
			
			double maxDot = -2.;
			point nPP;
				// find most colinear
			for (int j=0;j<ppoints.size();j++){
				double dDot = (ppoints[j]*mPP)/ppoints[j].mag();
				if (dDot > maxDot){
					maxDot = dDot;
					nPP = ppoints[j];
				}
					// if there are planar points, take the closest one
				else if (dDot == maxDot)
					if ( ppoints[j].mag() < nPP.mag()){
						maxDot = dDot;
						nPP = ppoints[j];
					}
			}
			ppoints.clear();

			for (int j=0;j<points.size();j++)
				if (nPP == points[j] - dp*(dp*points[j]) - p0)
					surface.push_back(tri(mE(0),mE(1),points[j]));

				//			for (int j=0;j<surface.size();j++)
				//				std::cout << "surface["<<j<< "] : " << surface[j] << std::endl;
				//			std::cout << std::endl;
			
			if (!markEdges()) {
				return false;
				
					//unmarkEdges();
					//surface.pop_back();
				
					//for (int j=0;j<surface.size();j++)
					//std::cout << "surface["<<j<< "] : " << surface[j] << std::endl;
					//std::cout << std::endl;
					//continue;
			}
			break;
				
		}
	}
	
	calcCenter();
	fixN();
	
	return true;
}