//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; }
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; }
//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; } }
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 }