Exemple #1
0
Point min_center()
{
    o = p[0];
    r = 0;
    for(int i=1; i<n; i++)//准备加入的点
    {
        if(dis(p[i], o)-r > eps)//如果第i点在 i-1前最小圆外面
        {
            o = p[i];//另定圆心
            r = 0;//另定半径

            for(int j=0; j<i; j++)//循环再确定半径
            {
                if(dis(p[j], o)-r > eps)
                {
                    o.x = (p[i].x + p[j].x) / 2.0;
                    o.y = (p[i].y + p[j].y) / 2.0;
                    r = dis( o, p[j]);
                    for(int k = 0; k<j; k++)
                    {
                        if(dis(o, p[k])-r > eps)//如果j前面有点不符和 i与j确定的圆,则更新
                        {
                            o = circumcenter(p[i], p[j], p[k]);
                            r = dis(o, p[k]);
                        }
                    }//循环不超过3层,因为一个圆最多3个点可以确定
                }
            }
        }
    }
    return o;
}
Exemple #2
0
double
circumradius(const Facet& f)
{
    Point c = circumcenter(f);
    Point p = f.first->vertex((f.second+1)%4)->point();
    return sqrt(CGAL::to_double((p-c)*(p-c)));
}
circle spanning_circle(vector<point>& T)
{
    int n = T.size();

    random_shuffle(ALL(T));

    circle C(point(), -INFINITY);

    for (int i = 0; i < n; i++) if (!in_circle(C, T[i]))
        {
            C = circle(T[i], 0);

            for (int j = 0; j < i; j++) if (!in_circle(C, T[j]))
                {
                    C = circle((T[i] + T[j]) / 2, abs(T[i] - T[j]) / 2);

                    for (int k = 0; k < j; k++) if (!in_circle(C, T[k]))
                        {
                            point o = circumcenter(T[i], T[j], T[k]);
                            C = circle(o, abs(o - T[k]));
                        }
                }
        }

    return C;
}
Exemple #4
0
int main()
{
	point a,b,c;
	point center;
	double r;
	while (scanf("%lf %lf %lf %lf %lf %lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y) != EOF)
	{
		center = circumcenter(a,b,c);
		r = distance(center,a);
		printf("%.2lf\n",2*PI*r);
	}
	return 0;
}
circle enclosing_circle(vector<pt>& pts){
    srand(unsigned(time(0)));
    random_shuffle(pts.begin(), pts.end());

    circle c(pt(), -1);
    for (int i = 0; i < pts.size(); ++i){
        if (point_circle(pts[i], c)) continue;
        c = circle(pts[i], 0);
        for (int j = 0; j < i; ++j){
            if (point_circle(pts[j], c)) continue;
            c = circle((pts[i] + pts[j])/2, abs(pts[i] - pts[j])/2);
            for (int k = 0; k < j; ++k){
                if (point_circle(pts[k], c)) continue;
                pt center = circumcenter(pts[i], pts[j], pts[k]);
                c = circle(center, abs(center - pts[i])/2);
            }
        }
    }
    return c;
}
Exemple #6
0
void Foam::CV2D::calcDual
(
    point2DField& dualPoints,
    faceList& dualFaces,
    wordList& patchNames,
    labelList& patchSizes,
    EdgeMap<label>& mapEdgesRegion,
    EdgeMap<label>& indirectPatchEdge
) const
{
    // Dual points stored in triangle order.
    dualPoints.setSize(number_of_faces());
    label dualVerti = 0;

    for
    (
        Triangulation::Finite_faces_iterator fit = finite_faces_begin();
        fit != finite_faces_end();
        ++fit
    )
    {
        if
        (
            fit->vertex(0)->internalOrBoundaryPoint()
         || fit->vertex(1)->internalOrBoundaryPoint()
         || fit->vertex(2)->internalOrBoundaryPoint()
        )
        {
            fit->faceIndex() = dualVerti;

            dualPoints[dualVerti++] = toPoint2D(circumcenter(fit));
        }
        else
        {
            fit->faceIndex() = -1;
        }
    }

    dualPoints.setSize(dualVerti);

    extractPatches(patchNames, patchSizes, mapEdgesRegion, indirectPatchEdge);

    forAll(patchNames, patchi)
    {
        Info<< "Patch " << patchNames[patchi]
            << " has size " << patchSizes[patchi] << endl;
    }

    // Create dual faces
    // ~~~~~~~~~~~~~~~~~

    dualFaces.setSize(number_of_vertices());
    label dualFacei = 0;
    labelList faceVerts(maxNvert);

    for
    (
        Triangulation::Finite_vertices_iterator vit = finite_vertices_begin();
        vit != finite_vertices_end();
        ++vit
    )
    {
        if (vit->internalOrBoundaryPoint())
        {
            Face_circulator fcStart = incident_faces(vit);
            Face_circulator fc = fcStart;
            label verti = 0;

            do
            {
                if (!is_infinite(fc))
                {
                    if (fc->faceIndex() < 0)
                    {
                        FatalErrorInFunction
                         << "Dual face uses vertex defined by a triangle"
                            " defined by an external point"
                            << exit(FatalError);
                    }

                    // Look up the index of the triangle
                    faceVerts[verti++] = fc->faceIndex();
                }
            } while (++fc != fcStart);

            if (faceVerts.size() > 2)
            {
                dualFaces[dualFacei++] =
                    face(labelList::subList(faceVerts, verti));
            }
            else
            {
                Info<< "From triangle point:" << vit->index()
                    << " coord:" << toPoint2D(vit->point())
                    << " generated illegal dualFace:" << faceVerts
                    << endl;
            }
        }
    }

    dualFaces.setSize(dualFacei);
}
Exemple #7
0
void Foam::CV2D::writeFaces(const fileName& fName, bool internalOnly) const
{
    Info<< "Writing dual faces to " << fName << nl << endl;
    OFstream str(fName);

    label dualVerti = 0;

    for
    (
        Triangulation::Finite_faces_iterator fit = finite_faces_begin();
        fit != finite_faces_end();
        ++fit
    )
    {
        if
        (
            !internalOnly
         || (
                fit->vertex(0)->internalOrBoundaryPoint()
             || fit->vertex(1)->internalOrBoundaryPoint()
             || fit->vertex(2)->internalOrBoundaryPoint()
            )
        )
        {
            fit->faceIndex() = dualVerti++;
            meshTools::writeOBJ(str, toPoint3D(circumcenter(fit)));
        }
        else
        {
            fit->faceIndex() = -1;
        }
    }

    for
    (
        Triangulation::Finite_vertices_iterator vit = finite_vertices_begin();
        vit != finite_vertices_end();
        ++vit
    )
    {
        if (!internalOnly || vit->internalOrBoundaryPoint())
        {
            Face_circulator fcStart = incident_faces(vit);
            Face_circulator fc = fcStart;

            str<< 'f';

            do
            {
                if (!is_infinite(fc))
                {
                    if (fc->faceIndex() < 0)
                    {
                        FatalErrorInFunction
                         << "Dual face uses vertex defined by a triangle"
                            " defined by an external point"
                            << exit(FatalError);
                    }

                    str<< ' ' << fc->faceIndex() + 1;
                }
            } while (++fc != fcStart);

            str<< nl;
        }
    }
}
Exemple #8
0
void Graph::create(const vector< vector<Cell_handle> >& chains,
		   const vector<COMPUTATION_STATUS>& chains_property,
                   const vector< Facet >& start_of_chains)
{
    // `chains' is a collection of chains each of which is given by a list
    // of ordered vertices on it. the edges are therefore implicitly defined
    // between two consecutive vertices in the list. It has impurity because
    // some edges are not correct. So, we collect only the correct edges
    // and remove any duplication. We call it pure_chains.
    vector< vector<int> > pure_chains;
    pure_chains.resize((int)chains.size());
    int current_pure_chain = -1;

    // we first create a set of vertices. we omit duplication at the start
    // and end of chains by consulting the vector start_end_of_chains.
    for(int i = 0; i < (int)chains.size(); i ++)
    {
       if(chains_property[i] != SUCCESS) continue;
       if((int)chains[i].size() == 0) continue;

       current_pure_chain++;

       Facet i2f = start_of_chains[i];
       if( i2f.first->saddle_g_vid[i2f.second] == -1)
       {
          vert_list.push_back( GVertex(circumcenter(start_of_chains[i])) );
          vert_list[(int)vert_list.size()-1].id = (int)vert_list.size()-1;
          vert_list[(int)vert_list.size()-1].c = i2f.first;
          pure_chains[current_pure_chain].push_back((int)vert_list.size()-1);

          Cell_handle c[2]; int id[2];
          c[0] = i2f.first; id[0] = i2f.second;
          c[1] = c[0]->neighbor(id[0]); id[1] = c[1]->index(c[0]);

          c[0]->saddle_g_vid[id[0]] = (int)vert_list.size()-1;
          c[1]->saddle_g_vid[id[1]] = (int)vert_list.size()-1;

          vert_list[(int)vert_list.size()-1].set_out(c[0]->outside && c[1]->outside );

          // if either of the three VFs incident on the VE (dual to Face(c[0], id[0]))
          // is on_um_i1, this graph vertex is also on um_i1.
          int u = (id[0]+1)%4, v = (id[0]+2)%4, w = (id[0]+3)%4;
          if(c[0]->VF_on_um_i1(u,v) || 
             c[0]->VF_on_um_i1(v,w) || 
             c[0]->VF_on_um_i1(w,u) )
                vert_list[(int)vert_list.size()-1].set_on_um_i1(true);
          // collect the clusters the incident VFs fall into.
          if(c[0]->patch_id[u][v] != -1)
             vert_list[(int)vert_list.size()-1].cluster_membership.push_back(c[0]->patch_id[u][v]);
          if(c[0]->patch_id[v][w] != -1 &&
             c[0]->patch_id[v][w] !=  c[0]->patch_id[u][v])
             vert_list[(int)vert_list.size()-1].cluster_membership.push_back(c[0]->patch_id[v][w]);
          if(c[0]->patch_id[w][u] != -1 &&
             c[0]->patch_id[w][u] !=  c[0]->patch_id[u][v] &&
             c[0]->patch_id[w][u] !=  c[0]->patch_id[v][w] )
             vert_list[(int)vert_list.size()-1].cluster_membership.push_back(c[0]->patch_id[w][u]);
          if((int)vert_list[(int)vert_list.size()-1].cluster_membership.size() >= 2) cerr << " >= 2 ";
       }
       else
       {
          pure_chains[current_pure_chain].push_back(i2f.first->saddle_g_vid[i2f.second]);
       }

       for(int j = 0; j < (int)chains[i].size(); j ++)
       {
          // if the cell is already included by another chain
          if(chains[i][j]->g_vid != -1)
             pure_chains[current_pure_chain].push_back(chains[i][j]->g_vid);
          else // add its voronoi as a vertex in the graph
          {
             vert_list.push_back(GVertex(chains[i][j]->voronoi()));
             vert_list[(int)vert_list.size()-1].id = (int)vert_list.size()-1;
             vert_list[(int)vert_list.size()-1].c = chains[i][j];

             pure_chains[current_pure_chain].push_back((int)vert_list.size()-1);
             chains[i][j]->g_vid = (int)vert_list.size()-1;

             vert_list[(int)vert_list.size()-1].set_out(chains[i][j]->outside);

             // keep the info if this cell also lies on um(i1).
             if(chains[i][j]->VV_on_um_i1()) 
             {
                vert_list[(int)vert_list.size()-1].set_on_um_i1(true);
                for(int u = 0; u < 4; u ++)
                {
                   for(int v = u+1; v < 4; v ++)
                   {
                      if(chains[i][j]->patch_id[u][v] == -1) continue;
                      bool found = false;
                      for(int k = 0; k < (int)vert_list[(int)vert_list.size()-1].cluster_membership.size(); k ++)
                         if(vert_list[(int)vert_list.size()-1].cluster_membership[k] == 
                            chains[i][j]->patch_id[u][v])
                            found = true;
                      if(found) continue;
                      vert_list[(int)vert_list.size()-1].cluster_membership.push_back(
                                                  chains[i][j]->patch_id[u][v]);
                   }
                }
             }
          }
       }
    }
    set_nv((int)vert_list.size());

    for(int i = 0; i < (int)pure_chains.size(); i ++)
    {
       if((int)pure_chains[i].size() == 0) continue;
       for(int j = 0; j < (int)pure_chains[i].size() - 1; j ++)
       {
          edge_list.push_back(GEdge(pure_chains[i][j], pure_chains[i][j+1]));
          edge_list[(int)edge_list.size()-1].id = (int)edge_list.size()-1;

          // we have considered only the chains with status == SUCCESS.
          edge_list[(int)edge_list.size()-1].set_status(SUCCESS);

          // update adjacency information.
          // vertex
          vert_list[pure_chains[i][j]].add_inc_vert(pure_chains[i][j+1]);
          vert_list[pure_chains[i][j+1]].add_inc_vert(pure_chains[i][j]);
          // edge
          vert_list[pure_chains[i][j]].add_inc_edge((int)edge_list.size()-1);
          vert_list[pure_chains[i][j+1]].add_inc_edge((int)edge_list.size()-1);
       }
    }
    set_ne((int)edge_list.size());
}
Exemple #9
0
Point orthocenter(const Point &a, const Point &b, const Point &c) {
    return a + b + c - circumcenter(a, b, c) * 2.0;
}
Exemple #10
0
void Foam::CV2D::newPoints()
{
    const scalar relaxation = relaxationModel_->relaxation();

    Info<< "Relaxation = " << relaxation << endl;

    Field<point2D> dualVertices(number_of_faces());

    label dualVerti = 0;

    // Find the dual point of each tetrahedron and assign it an index.
    for
    (
        Triangulation::Finite_faces_iterator fit = finite_faces_begin();
        fit != finite_faces_end();
        ++fit
    )
    {
        fit->faceIndex() = -1;

        if
        (
            fit->vertex(0)->internalOrBoundaryPoint()
         || fit->vertex(1)->internalOrBoundaryPoint()
         || fit->vertex(2)->internalOrBoundaryPoint()
        )
        {
            fit->faceIndex() = dualVerti;

            dualVertices[dualVerti] = toPoint2D(circumcenter(fit));

            dualVerti++;
        }
    }

    dualVertices.setSize(dualVerti);

    Field<vector2D> displacementAccumulator
    (
        startOfSurfacePointPairs_,
        vector2D::zero
    );

    // Calculate target size and alignment for vertices
    scalarField sizes
    (
        number_of_vertices(),
        meshControls().minCellSize()
    );

    Field<vector2D> alignments
    (
        number_of_vertices(),
        vector2D(1, 0)
    );

    for
    (
        Triangulation::Finite_vertices_iterator vit = finite_vertices_begin();
        vit != finite_vertices_end();
        ++vit
    )
    {
        if (vit->internalOrBoundaryPoint())
        {
            point2D vert = toPoint2D(vit->point());

            // alignment and size determination
            pointIndexHit pHit;
            label hitSurface = -1;

            qSurf_.findSurfaceNearest
            (
                toPoint3D(vert),
                meshControls().span2(),
                pHit,
                hitSurface
            );

            if (pHit.hit())
            {
                vectorField norm(1);
                allGeometry_[hitSurface].getNormal
                (
                    List<pointIndexHit>(1, pHit),
                    norm
                );

                alignments[vit->index()] = toPoint2D(norm[0]);

                sizes[vit->index()] =
                    cellSizeControl_.cellSize
                    (
                        toPoint3D(vit->point())
                    );
            }
        }
    }

    // Info<< "Calculated alignments" << endl;

    scalar cosAlignmentAcceptanceAngle = 0.68;

    // Upper and lower edge length ratios for weight
    scalar u = 1.0;
    scalar l = 0.7;

    PackedBoolList pointToBeRetained(startOfSurfacePointPairs_, true);

    std::list<Point> pointsToInsert;

    for
    (
        Triangulation::Finite_edges_iterator eit = finite_edges_begin();
        eit != finite_edges_end();
        eit++
    )
    {
        Vertex_handle vA = eit->first->vertex(cw(eit->second));
        Vertex_handle vB = eit->first->vertex(ccw(eit->second));

        if (!vA->internalOrBoundaryPoint() || !vB->internalOrBoundaryPoint())
        {
            continue;
        }

        const point2D& dualV1 = dualVertices[eit->first->faceIndex()];
        const point2D& dualV2 =
            dualVertices[eit->first->neighbor(eit->second)->faceIndex()];

        scalar dualEdgeLength = mag(dualV1 - dualV2);

        point2D dVA = toPoint2D(vA->point());
        point2D dVB = toPoint2D(vB->point());

        Field<vector2D> alignmentDirsA(2);

        alignmentDirsA[0] = alignments[vA->index()];
        alignmentDirsA[1] = vector2D
        (
           -alignmentDirsA[0].y(),
            alignmentDirsA[0].x()
        );

        Field<vector2D> alignmentDirsB(2);

        alignmentDirsB[0] = alignments[vB->index()];
        alignmentDirsB[1] = vector2D
        (
           -alignmentDirsB[0].y(),
            alignmentDirsB[0].x()
        );

        Field<vector2D> alignmentDirs(alignmentDirsA);

        forAll(alignmentDirsA, aA)
        {
            const vector2D& a(alignmentDirsA[aA]);

            scalar maxDotProduct = 0.0;

            forAll(alignmentDirsB, aB)
            {
                const vector2D& b(alignmentDirsB[aB]);

                scalar dotProduct = a & b;

                if (mag(dotProduct) > maxDotProduct)
                {
                    maxDotProduct = mag(dotProduct);

                    alignmentDirs[aA] = a + sign(dotProduct)*b;

                    alignmentDirs[aA] /= mag(alignmentDirs[aA]);
                }
            }
        }

        vector2D rAB = dVA - dVB;

        scalar rABMag = mag(rAB);

        forAll(alignmentDirs, aD)
        {
            vector2D& alignmentDir = alignmentDirs[aD];

            if ((rAB & alignmentDir) < 0)
            {
                // swap the direction of the alignment so that has the
                // same sense as rAB
                alignmentDir *= -1;
            }

            scalar alignmentDotProd = ((rAB/rABMag) & alignmentDir);

            if (alignmentDotProd > cosAlignmentAcceptanceAngle)
            {
                scalar targetFaceSize =
                    0.5*(sizes[vA->index()] + sizes[vB->index()]);

                // Test for changing aspect ratio on second alignment (first
                // alignment is neartest surface normal)
                // if (aD == 1)
                // {
                //     targetFaceSize *= 2.0;
                // }

                alignmentDir *= 0.5*targetFaceSize;

                vector2D delta = alignmentDir - 0.5*rAB;

                if (dualEdgeLength < 0.7*targetFaceSize)
                {
                    delta *= 0;
                }
                else if (dualEdgeLength < targetFaceSize)
                {
                    delta *=
                        (
                            dualEdgeLength
                           /(targetFaceSize*(u - l))
                          - 1/((u/l) - 1)
                        );
                }

                if
                (
                    vA->internalPoint()
                 && vB->internalPoint()
                 && rABMag > 1.75*targetFaceSize
                 && dualEdgeLength > 0.05*targetFaceSize
                 && alignmentDotProd > 0.93
                )
                {
                    // Point insertion
                    pointsToInsert.push_back(toPoint(0.5*(dVA + dVB)));
                }
                else if
                (
                    (vA->internalPoint() || vB->internalPoint())
                 && rABMag < 0.65*targetFaceSize
                )
                {
                    // Point removal

                    // Only insert a point at the midpoint of the short edge
                    // if neither attached point has already been identified
                    // to be removed.
                    if
                    (
                        pointToBeRetained[vA->index()] == true
                     && pointToBeRetained[vB->index()] == true
                    )
                    {
                        pointsToInsert.push_back(toPoint(0.5*(dVA + dVB)));
                    }

                    if (vA->internalPoint())
                    {
                        pointToBeRetained[vA->index()] = false;
                    }

                    if (vB->internalPoint())
                    {
                        pointToBeRetained[vB->index()] = false;
                    }
                }
                else
                {
                    if (vA->internalPoint())
                    {
                        displacementAccumulator[vA->index()] += delta;
                    }

                    if (vB->internalPoint())
                    {
                        displacementAccumulator[vB->index()] += -delta;
                    }
                }
            }
        }
    }
void BMMap::make_edges_delauney(  )
{
	for (int i=0; i < nloc; i++) {
		for (int j=0; j < nloc; j++) {
			adj[i][j].pass = 0;
		}
	}

	// DBG: fill in edges at random
#if 0
	for (i=0; i <10; i++) {
		int l1,l2;
		l1 = random( nloc );
		l2 = random( nloc );
		adj[l1][l2].pass = 1;
		adj[l2][l1].pass = 1;
	}
#endif

	std::vector<Triangle> tris, tris2;
	tris.push_back( Triangle() );
	tris.push_back( Triangle() );
	tris[0].ax = 0; tris[0].ay = 0;
	tris[0].bx = 800; tris[0].by = 0;
	tris[0].cx = 800; tris[0].cy = 600;

	tris[1].ax = 0;   tris[1].ay = 0;
	tris[1].bx = 0;   tris[1].by = 600;
	tris[1].cx = 800; tris[1].cy = 600;

	// edgelist
	std::vector<Edge> edge;

	for (int ndx=0; ndx < nloc; ndx++) {
		
		// init lists
		tris2.erase( tris2.begin(), tris2.end() );
		edge.erase( edge.begin(), edge.end() );
		

		// find all triangle whose circumcenter contains loc ndx
		for (i=0; i < tris.size(); i++) {
			float cx, cy, rad;

			circumcenter( tris[i], cx, cy, rad );
			float d = sqrt( (loc[ndx].xpos - cx) * (loc[ndx].xpos - cx) +
						    (loc[ndx].ypos - cy) * (loc[ndx].ypos - cy) );
			if (d <= rad) {
				// in triangle circumcenter, add to edgelist
				add_edge( edge, tris[i].ax, tris[i].ay, tris[i].bx, tris[i].by );
				add_edge( edge, tris[i].bx, tris[i].by, tris[i].cx, tris[i].cy );
				add_edge( edge, tris[i].cx, tris[i].cy, tris[i].ax, tris[i].ay );
				
			} else {
				// just keep the tri
				tris2.push_back( tris[i] );
				//printf("Keeping tri %i\n", i );
			}
		}

		// add a triangle for every edge appearing once in the list
		for (i=0; i < edge.size(); i++) {
			if ( edge[i].count == 1 ) {
				Triangle t;
				t.ax = loc[ndx].xpos;
				t.ay = loc[ndx].ypos;
				t.bx = edge[i].x1; t.by = edge[i].y1;
				t.cx = edge[i].x2; t.cy = edge[i].y2;
				tris2.push_back( t );

				//printf("constructing tri\n" );
			}
		}

		// update the list
		tris = tris2;				
	}


	// convert the tris to adjacency
	for (i=0; i < tris.size(); i++) {
		int andx, bndx, cndx;

		andx = -1; bndx = -1; cndx = -1;
		for (int j=0; j < nloc; j++) {
			if ( ((int)tris[i].ax == loc[j].xpos) &&
				 ((int)tris[i].ay == loc[j].ypos) ) andx = j;
			
			if ( ((int)tris[i].bx == loc[j].xpos) &&
				 ((int)tris[i].by == loc[j].ypos) ) bndx = j;
			
			if ( ((int)tris[i].cx == loc[j].xpos) &&
				 ((int)tris[i].cy == loc[j].ypos) ) cndx = j;
		}

		if ( (andx > 0) && (bndx >=0 )) {
			adj[andx][bndx].pass = 1;
			adj[bndx][andx].pass = 1;

			if (!adj[andx][bndx].de) {
				DualEdge *de = find_dual_edge( tris, andx, bndx );
				adj[andx][bndx].de = de;
				adj[bndx][andx].de = de;
			}

		}

		if ( (bndx > 0) && (cndx >=0 )) {
			adj[bndx][cndx].pass = 1;
			adj[cndx][bndx].pass = 1;

			if (!adj[bndx][cndx].de) {
				DualEdge *de = find_dual_edge( tris, bndx, cndx );
				adj[bndx][cndx].de = de;
				adj[cndx][bndx].de = de;
			}
		}

		if ( (cndx > 0) && (andx >=0 )) {
			adj[cndx][andx].pass = 1;
			adj[andx][cndx].pass = 1;

			if (!adj[cndx][andx].de) {
				DualEdge *de = find_dual_edge( tris, cndx, andx );
				adj[cndx][andx].de = de;
				adj[andx][cndx].de = de;
			}
		}
	}
	
}
Exemple #12
0
 Circle(const Point &a, const Point &c, const Point &d): o(circumcenter(a, b, c)) {
     r = ((a - o).norm() + (b - o).norm() + (c - o).norm()) / 3.0;
 }