//Welzl algorithm
void minimumCircle(float* radius, Point* position, Point* points,int size){

	if(size == 0){
		*radius = 0;
		*position = pointMake(0, 0);
		return;
	}
	
	size--;
	Point* evaluationPoint = &points[size];
	
	minimumCircle(radius, position, points, size);
	
	if(isPointInsideCircle(*evaluationPoint, *radius, *position)){
		return;
	}
	
	Point* P = copyPoints(size, points);
	Point* R = copyPoints(1, evaluationPoint);

	minimumDisk(P, R, size, 1, radius, position);
	
	free(P);
	free(R);
	
	return;
	
}
//Welzl final recursion - calculates the actual circle
void minimumDisk(Point* P, Point* R, int sizeP, int sizeR, float* radius, Point* position){
	
	if(sizeP==0 || sizeR==3){
		if(sizeR==1){
			*radius = 0;
			*position = R[0];
			return;
		}
		if(sizeR==2){
			*position = pointMake((R[0].x+R[1].x)/2., (R[0].y+R[1].y)/2.);
			*radius = pointsDistance(R[0], R[1])/2.;
			return;
		}
		if(sizeR==3){
			
			Point P1 = pointMake((R[0].x+R[1].x)/2., (R[0].y+R[1].y)/2.);
			Point AB = pointMake((R[1].x-R[0].x)/2., (R[1].y-R[0].y)/2.);
			Point BC = pointMake((R[2].x-R[1].x)/2., (R[2].y-R[1].y)/2.);
			Point AC = pointMake((R[2].x-R[0].x)/2., (R[2].y-R[0].y)/2.);
			Point PR = pointMake(-AB.y,AB.x);
			
			float w = -1./2.*(BC.x*AC.x+BC.y*AC.y)/(BC.x*AB.y-BC.y*AB.x);
			
			*position = pointMake(P1.x+w*PR.x, P1.y+w*PR.y);
			
			*radius = pointsDistance(*position, R[0]);
			
			return;
		}
	}
	
	Point* P2 = copyPoints(sizeP, P);
	Point* R2 = copyPoints(sizeR, R);
	
	
	sizeP--;
	Point point = P[sizeP];

	minimumDisk(P2, R2, sizeP, sizeR, radius, position);
	
	if(isPointInsideCircle(point, *radius, *position)){
		free(R2);
		free(P2);
		return;
	}
	
	
	R2[sizeR] = point;
	
	sizeR++;
	
	minimumDisk(P2, R2, sizeP, sizeR, radius, position);
	
	free(R2);
	free(P2);
	return;
	
	
}
示例#3
0
void IRThread::run()
{
    int visiblePointCount = 0;
    while(!isConnected)
        initialize();

    int poll_res = 0;
    while(1) {
        poll_res = wiiuse_poll(wiimotes, MAX_WIIMOTES);
        //qWarning() << "poll result" << poll_res;
        if (poll_res) {
            //qWarning() << "wii event: " << wiimotes[0]->event;
            if(wiimotes[0]->event == WIIUSE_EVENT) {
                if (WIIUSE_USING_IR(wiimotes[0])) {
                    int i = 0;
                    //count number of visible points
                    visiblePointCount = 0;
                    for(int i = 0; i < 4; i++) {
                        if(wiimotes[0]->ir.dot[i].visible) {
                            irpoints[i].setX(wiimotes[0]->ir.dot[i].rx);
                            irpoints[i].setY(wiimotes[0]->ir.dot[i].ry);
                            visiblePointCount++;
                        }
                        else {
                            //qWarning() << "else";
                            irpoints[i].setX(-1);
                            irpoints[i].setY(-1);
                        }
                    }
                    //qWarning() << "visible points:" << visiblePointCount;
                    // process ir dot #0
                    if (wiimotes[0]->ir.dot[0].visible) {
                        if(previous[0] == false) {
                            previous[0] = true;
                            emit IRInputReceived(irpoints,0,MOUSE_PRESSED,visiblePointCount);
                            copyPoints(irpoints,previousPoints);
                        }
                        else if(previous[0] == true) {
                            emit IRInputReceived(irpoints,0,MOUSE_MOVE,visiblePointCount);
                            copyPoints(irpoints,previousPoints);
                        }
                    }
                    else if(previous[0] == true) {
                        previous[0] = false;
                        //emit IRInputReceived(wiimotes[0]->ir.dot[0].rx, wiimotes[0]->ir.dot[0].ry,0,MOUSE_RELEASED,visiblePointCount);
                        //previousPoint = QPoint(wiimotes[0]->ir.dot[0].rx,wiimotes[0]->ir.dot[0].ry);
                        emit IRInputReceived(previousPoints, 0, MOUSE_RELEASED, visiblePointCount);
                    }
                    else if(previous[0] == false) {
                        // do nothing
                    }
                }
            }
        }
    }

    exec();
}
void separateTriangles(PhysicsObject* object){
	int size = object->format.polygonInfo.count;
	Point* points = copyPoints(size, object->format.polygonInfo.points);
	trueSeparateTriangles(points,object,0, size);
	free(points);
	return;
}
void calculateMinimumCircle(PhysicsObject* object){
	
	float radius;
	Point position;
	Point* copy = copyPoints(object->format.polygonInfo.count, object->format.polygonInfo.points);
	minimumCircle(&radius,&position,copy,object->format.polygonInfo.count);
	free(copy);
	object->minimumCirclePosition = position;
	object->minimumCircleRadius = radius;
	return;
}
//returns how many triangles were inserted in the last recursion step
int trueSeparateTriangles(Point* points, PhysicsObject* object, int currentTriangle, int size){
	float* signals = (float*)malloc(size*sizeof(float));
	int i=0;
	//verifies if any of the points is a concave point. we assumed that the points are given at counter-clockwise order
	for (i=0; i<size; i++) {
		int j = i-1<0?size-1:i-1;
		int k = i+1>=size?0:i+1;
		
		Point p1 = points[j];
		Point p2 = points[i];
		Point p3 = points[k];
		
		signals[i] =(p2.x-p1.x)*(p3.y-p2.y)-(p3.x-p2.x)*(p2.y-p1.y);
	}
	
	char isConvex = 1;
	int removable = 0;
	for(i=0;i<size;i++){
		if(signals[i]<0){//is a concave point, so the polygon is concave
			isConvex = 0;
			int j= i-1<0?size-1:i-1;
			if(signals[j]>0){//the point just before the concave one is an option for a triangle
				int k = j==0?size-1:j-1;
				char hasPointInside = 0;
				int l=0;
				for(l=0;l<size;l++){//check if the triangle has a point inside it
					if(l == i || l == j || l==k){
						continue;
					}
					if(isPointInsideTriangle(points[i], points[j], points[k], points[l])){
						hasPointInside = 1;
						break;
					}
				}
				if(hasPointInside){
					continue;
				}
				//if everything is ok, add the triangle to the structure
				object->format.polygonInfo.triangles[currentTriangle][0] = points[i];
				object->format.polygonInfo.triangles[currentTriangle][1] = points[j];
				object->format.polygonInfo.triangles[currentTriangle][2] = points[k];
				currentTriangle++;
				removable = j;
				break;
			}
			j = i+1>=size?0:i+1;
			if(signals[j]>0){//the point just after the concave one is an option for a triangle
				int k = j==size-1?0:j+1;
				char hasPointInside = 0;
				int l=0;
				for(l=0;l<size;l++){//check if the triangle has a point inside it
					if(l == i || l == j || l==k){
						continue;
					}
					if(isPointInsideTriangle(points[i], points[j], points[k], points[l])){
						hasPointInside = 1;
						break;
					}
				}
				if(hasPointInside){
					continue;
				}
				//if everything is ok, add the triangle to the structure
				object->format.polygonInfo.triangles[currentTriangle][0] = points[i];
				object->format.polygonInfo.triangles[currentTriangle][1] = points[j];
				object->format.polygonInfo.triangles[currentTriangle][2] = points[k];
				currentTriangle++;
				removable = j;
				break;
			}
		}
	}
	
	free(signals);
	
	//in the case object is convex, just fix a point and trace a line to all other points.
	if(isConvex){
		int maxTriangles = size -2;
		for(i=0;i<maxTriangles; i++){
			object->format.polygonInfo.triangles[currentTriangle][0] = points[0];
			object->format.polygonInfo.triangles[currentTriangle][1] = points[i+1];
			object->format.polygonInfo.triangles[currentTriangle][2] = points[i+2];
			currentTriangle++;
		}
		
		return size-2;
	}
	//if is a concave structure
	
	Point* points2 = copyPoints(size, points);
	for(i=removable;i<size-1;i++){
		points2[i] = points2[i+1];
	}
	
	trueSeparateTriangles(points2, object, currentTriangle, size-1);
	
	free(points2);
	
	return 1;
}
示例#7
0
//implementation of the ransac algorithm
void ransac(){
	int i, j, k = 0, index_p1, index_p2, n_inliers = 0, n_inliers2;
	float slope, intercept;
	point inliers[1000], inliers2[1000];
	segment segTemp1, segTemp2;
	
	while(n_data >= 8){
		segments[n_segments].n_inliers = 0;
		
		//try to find a segment to different models
		for(i = 0; i < 500; i++){
			//get 2 random points of the data set
			index_p1 = getRandomPoint();
			index_p2 = getRandomPoint();
			while(index_p1 == index_p2 || data[index_p2].x == data[index_p1].x)
				index_p2 = getRandomPoint();
			
			//fit the model
			slope = (data[index_p2].y - data[index_p1].y) / (data[index_p2].x - data[index_p1].x);
			intercept = data[index_p1].y - (slope * data[index_p1].x); 
			
			//find the inliers
			findInliers(slope, intercept, inliers, &n_inliers);
			
			//find the biggest segment
			segTemp1 = getBiggestSegment(slope, intercept, inliers, &n_inliers);
			
			//there is no point in continue trying if the segment explains all data
			if(segTemp1.n_inliers == n_data){
				segments[n_segments] = segTemp1;
				break;
			}
				
			//apply regression to the segment until it gets less inliers
			segTemp2.n_inliers = 0;
			while(1){
				copyPoints(inliers2, inliers, n_inliers);
				n_inliers2 = n_inliers;
				
				segTemp2 = linearRegression(inliers2, &n_inliers2);
				
				if(segTemp2.n_inliers > segTemp1.n_inliers){
					segTemp1 = segTemp2;
					copyPoints(inliers, inliers2, n_inliers2);
					n_inliers = n_inliers2;
				}
				
				else
					break;
			}
			
			//compare with the biggest segments until now
			if(segTemp1.n_inliers > segments[n_segments].n_inliers)
				segments[n_segments] = segTemp1;
		}
		
		if(segments[n_segments].n_inliers >= 8){
			//remove inliers of the segment
			removeInliers(segments[n_segments]);
			n_segments++;
		}
		else
			break;
	}
}
示例#8
0
void
OverlayOp::computeOverlay(int opCode)
	//throw(TopologyException *)
{

	// copy points from input Geometries.
	// This ensures that any Point geometries
	// in the input are considered for inclusion in the result set

	copyPoints(0);
	copyPoints(1);


	// node the input Geometries
	delete (*arg)[0]->computeSelfNodes(li,false);
	delete (*arg)[1]->computeSelfNodes(li,false);

#if DEBUG
	cerr<<"OverlayOp::computeOverlay: computed SelfNodes"<<endl;
#endif

	// compute intersections between edges of the two input geometries
	delete (*arg)[0]->computeEdgeIntersections((*arg)[1],li,true);

#if DEBUG
	cerr<<"OverlayOp::computeOverlay: computed EdgeIntersections"<<endl;
	cerr<<"OverlayOp::computeOverlay: li: "<<li->toString()<<endl;
#endif


	vector<Edge*> baseSplitEdges;
	(*arg)[0]->computeSplitEdges(&baseSplitEdges);
	(*arg)[1]->computeSplitEdges(&baseSplitEdges);

	// add the noded edges to this result graph
	insertUniqueEdges(&baseSplitEdges);
	computeLabelsFromDepths();
	replaceCollapsedEdges();
	//Debug.println(edgeList);

    	// debugging only
    	//NodingValidator nv = new NodingValidator(edgeList.getEdges());
    	//nv.checkValid();

	graph->addEdges(edgeList->getEdges());

	// this can throw TopologyException *
	computeLabelling();

	//Debug.printWatch();
	labelIncompleteNodes();
	//Debug.printWatch();
	//nodeMap.print(System.out);


	/*
	 * The ordering of building the result Geometries is important.
	 * Areas must be built before lines, which must be built
	 * before points.
	 * This is so that lines which are covered by areas are not
	 * included explicitly, and similarly for points.
	 */
	findResultAreaEdges(opCode);
	cancelDuplicateResultEdges();

	PolygonBuilder polyBuilder(geomFact,cga);
	
	// might throw a TopologyException *
	polyBuilder.add(graph);

	vector<Geometry*> *gv=polyBuilder.getPolygons();
	size_t gvSize=gv->size();
	resultPolyList=new vector<Polygon*>(gvSize);
	for(size_t i=0; i<gvSize; ++i) {
		(*resultPolyList)[i]=(Polygon*)(*gv)[i];
	}
	delete gv;

	LineBuilder lineBuilder(this,geomFact,ptLocator);
	resultLineList=lineBuilder.build(opCode);

	PointBuilder pointBuilder(this,geomFact,ptLocator);
	resultPointList=pointBuilder.build(opCode);

	// gather the results from all calculations into a single
	// Geometry for the result set
	resultGeom=computeGeometry(resultPointList,resultLineList,resultPolyList);
#if USE_ELEVATION_MATRIX
	elevationMatrix->elevate(resultGeom);
#endif // USE_ELEVATION_MATRIX
	


}