Exemplo n.º 1
0
int main() {
    distmesh::helper::HighPrecisionTime time;

    Eigen::ArrayXXd boundingBox(2, 2);
    boundingBox << -2.0, -1.0, 2.0, 1.0;

    // radii of ellipse
    Eigen::ArrayXd radii(2);
    radii << 2.0, 1.0;

    // create mesh
    Eigen::ArrayXXd points;
    Eigen::ArrayXXi elements;

    std::tie(points, elements) = distmesh::distmesh(
        distmesh::distanceFunction::elliptical(radii),
        0.2, 1.0, boundingBox);

    // print mesh properties and elapsed time
    std::cout << "Created mesh with " << points.rows() << " points and " << elements.rows() <<
        " elements in " << time.elapsed() * 1e3 << " ms." << std::endl;

    // save mesh to file
    distmesh::helper::savetxt<double>(points, "points.txt");
    distmesh::helper::savetxt<int>(elements, "triangulation.txt");

    // plot mesh using python
    return system("python plot_mesh.py");
}
TEST_F(GeneratorsBenchmark, benchmarkHyperbolicGeneratorWithSortedNodes) {
	count n = 100000;
	double s = 1.0;
	double alpha = 1.0;
	double t = 1.0;
	vector<double> angles(n);
	vector<double> radii(n);
	double R = s*HyperbolicSpace::hyperbolicAreaToRadius(n);
	double r = HyperbolicSpace::hyperbolicRadiusToEuclidean(R);
	//sample points randomly

	HyperbolicSpace::fillPoints(angles, radii, s, alpha);
	vector<index> permutation(n);

	index p = 0;
	std::generate(permutation.begin(), permutation.end(), [&p](){return p++;});

	//can probably be parallelized easily, but doesn't bring much benefit
	Aux::Parallel::sort(permutation.begin(), permutation.end(), [&angles,&radii](index i, index j){return angles[i] < angles[j] || (angles[i] == angles[j] && radii[i] < radii[j]);});

	vector<double> anglecopy(n);
	vector<double> radiicopy(n);

	#pragma omp parallel for
	for (index j = 0; j < n; j++) {
		anglecopy[j] = angles[permutation[j]];
		radiicopy[j] = radii[permutation[j]];
	}

	Graph G = HyperbolicGenerator().generate(anglecopy, radiicopy, r, R*t);
	EXPECT_EQ(G.numberOfNodes(), n);
}
TEST_F(GeneratorsBenchmark, benchmarkHyperbolicGeneratorWithSequentialQuadtree) {
	count n = 100000;
	double s = 1.0;
	double alpha = 1;

	vector<double> angles(n);
	vector<double> radii(n);
	HyperbolicSpace::fillPoints(angles, radii, s, alpha);
	double R = s*HyperbolicSpace::hyperbolicAreaToRadius(n);
	double r = HyperbolicSpace::hyperbolicRadiusToEuclidean(R);
	Quadtree<index> quad(r);

	for (index i = 0; i < n; i++) {
		quad.addContent(i, angles[i], radii[i]);
	}

	angles.clear();
	radii.clear();

	quad.trim();
	quad.sortPointsInLeaves();
	quad.reindex();
	quad.extractCoordinates(angles, radii);

	HyperbolicGenerator gen;
	Graph G = gen.generate(angles, radii, quad, R);

	EXPECT_EQ(n, G.numberOfNodes());
}
static void paintRoundedSliderBackground(const IntRect& rect, const RenderStyle* style, GraphicsContext* context)
{
    int borderRadius = rect.height() / 2;
    IntSize radii(borderRadius, borderRadius);
    Color sliderBackgroundColor = Color(11, 11, 11);
    context->fillRoundedRect(rect, radii, radii, radii, radii, sliderBackgroundColor);
}
Exemplo n.º 5
0
static void paintRoundedSliderBackground(const IntRect& rect, const ComputedStyle& style, GraphicsContext* context, Color sliderBackgroundColor )
{
    float borderRadius = rect.height() / 2;
    FloatSize radii(borderRadius, borderRadius);

    context->fillRoundedRect(FloatRoundedRect(rect, radii, radii, radii, radii), sliderBackgroundColor);
}
Exemplo n.º 6
0
void mitk::SimulationDrawTool::drawSpheres(const std::vector<Vector3>& points, float radius, const Vec4f color)
{
  if (!m_Update || points.empty())
    return;

  unsigned int numPoints = points.size();
  std::vector<float> radii(numPoints, radius);

  this->drawSpheres(points, radii, color);
}
Exemplo n.º 7
0
void
AppendEllipseToPath(PathBuilder* aPathBuilder,
                    const Point& aCenter,
                    const Size& aDimensions)
{
  Size halfDim = aDimensions / 2.f;
  Rect rect(aCenter - Point(halfDim.width, halfDim.height), aDimensions);
  RectCornerRadii radii(halfDim.width, halfDim.height);

  AppendRoundedRectToPath(aPathBuilder, rect, radii);
}
static void paintSliderRangeHighlight(const IntRect& rect, const RenderStyle* style, GraphicsContext* context, int startPosition, int endPosition, Color startColor, Color endColor)
{
    // Calculate border radius; need to avoid being smaller than half the slider height
    // because of https://bugs.webkit.org/show_bug.cgi?id=30143.
    int borderRadius = rect.height() / 2;
    IntSize radii(borderRadius, borderRadius);

    // Calculate highlight rectangle and edge dimensions.
    int startOffset = startPosition;
    int endOffset = rect.width() - endPosition;
    int rangeWidth = endPosition - startPosition;

    if (rangeWidth <= 0)
        return;

    // Make sure the range width is bigger than border radius at the edges to retain rounded corners.
    if (startOffset < borderRadius && rangeWidth < borderRadius)
        rangeWidth = borderRadius;
    if (endOffset < borderRadius && rangeWidth < borderRadius)
        rangeWidth = borderRadius;

    // Set rectangle to highlight range.
    IntRect highlightRect = rect;
    highlightRect.move(startOffset, 0);
    highlightRect.setWidth(rangeWidth);

    // Don't bother drawing an empty area.
    if (highlightRect.isEmpty())
        return;

    // Calculate white-grey gradient.
    IntPoint sliderTopLeft = highlightRect.location();
    IntPoint sliderBottomLeft = sliderTopLeft;
    sliderBottomLeft.move(0, highlightRect.height());
    RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderBottomLeft);
    gradient->addColorStop(0.0, startColor);
    gradient->addColorStop(1.0, endColor);

    // Fill highlight rectangle with gradient, potentially rounded if on left or right edge.
    context->save();
    context->setFillGradient(gradient);

    if (startOffset < borderRadius && endOffset < borderRadius)
        context->fillRoundedRect(highlightRect, radii, radii, radii, radii, startColor);
    else if (startOffset < borderRadius)
        context->fillRoundedRect(highlightRect, radii, IntSize(0, 0), radii, IntSize(0, 0), startColor);
    else if (endOffset < borderRadius)
        context->fillRoundedRect(highlightRect, IntSize(0, 0), radii, IntSize(0, 0), radii, startColor);
    else
        context->fillRect(highlightRect);

    context->restore();
}
Exemplo n.º 9
0
PassOwnPtr<Shape> Shape::createShape(const LayoutSize& logicalSize, const LayoutSize& logicalRadii, WritingMode writingMode, Length margin, Length padding)
{
    FloatRect rect(0, 0, logicalSize.width(), logicalSize.height());
    FloatSize radii(logicalRadii.width(), logicalRadii.height());
    FloatRoundedRect bounds(rect, radii, radii, radii, radii);

    OwnPtr<Shape> shape = createBoxShape(bounds);
    shape->m_writingMode = writingMode;
    shape->m_margin = floatValueForLength(margin, 0);
    shape->m_padding = floatValueForLength(padding, 0);

    return shape.release();
}
Exemplo n.º 10
0
void GameUtils::createStaticBox(hkpWorld* world, float centerX, float centerY, float centerZ, float radiusX, float radiusY, float radiusZ) {
	hkVector4 radii(radiusX, radiusY, radiusZ);

	hkpShape* boxShape = new hkpBoxShape(radii, 0);

	hkpRigidBodyCinfo boxInfo;
	boxInfo.m_motionType = hkpMotion::MOTION_FIXED;
	boxInfo.m_shape = boxShape;
	boxInfo.m_position.set(centerX, centerY, centerZ);

	hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
	world->addEntity(boxRigidBody);
	boxRigidBody->removeReference();
	boxShape->removeReference();
}
TEST_F(GeneratorsBenchmark, benchmarkSequentialQuadtreeConstruction) {
	count n = 33554432;
	count capacity = 1000;
	double s =1;
	double alpha = 1;
	double R = s*HyperbolicSpace::hyperbolicAreaToRadius(n);
	vector<double> angles(n);
	vector<double> radii(n);
	HyperbolicSpace::fillPoints(angles, radii, s, alpha);

	Quadtree<index> quad(HyperbolicSpace::hyperbolicRadiusToEuclidean(R),false,alpha,capacity);

	for (index i = 0; i < n; i++) {
		quad.addContent(i, angles[i], radii[i]);
	}
	EXPECT_EQ(quad.size(), n);
}
double Foam::cfdemCloud::d(int index)
{
    return 2*radii()[index][0];
}
scalar Foam::cfdemCloud::radius(int index)
{
    scalar r = radii()[index][0];
    return r;
}
Exemplo n.º 14
0
void compute_projections(const Particles& particles,
                         unsigned int projection_number, double pixel_size,
                         double resolution,
                         boost::ptr_vector<Projection>& projections,
                         int image_size) {

  // get coordinates, radius and mass
  IMP::algebra::Vector3Ds points(particles.size());
  std::vector<double> radii(particles.size());
  std::vector<double> mass(particles.size());
  for (unsigned int i = 0; i < particles.size(); i++) {
    points[i] = core::XYZ(particles[i]).get_coordinates();
    radii[i] = core::XYZR(particles[i]).get_radius();
    mass[i] = atom::Mass(particles[i]).get_mass();
  }

  // estimate max image size
  double max_dist = compute_max_distance(points);
  double max_radius = *std::max_element(radii.begin(), radii.end());
  static IMP::em::KernelParameters kp(resolution);
  const IMP::em::RadiusDependentKernelParameters& params =
    kp.get_params(max_radius);
  double wrap_length = 2 * params.get_kdist() + 1.0;
  int axis_size =
      (int)((max_dist + 2 * wrap_length + 2 * pixel_size) / pixel_size + 2);
  if (axis_size <= image_size) axis_size = image_size;

  // storage for rotated points
  IMP::algebra::Vector3Ds rotated_points(points.size());
  // points on sphere
  IMP::algebra::SphericalVector3Ds spherical_coords;
  quasi_evenly_spherical_distribution(projection_number, spherical_coords, 1.0);

  for (unsigned int i = 0; i < spherical_coords.size(); i++) {
    // convert sphere coordinate to rotation
    IMP::algebra::SphericalVector3D v = spherical_coords[i];
    double cy = cos(v[1] / 2.0);
    double cz = cos(v[2] / 2.0);
    double sy = sin(v[1] / 2.0);
    double sz = sin(v[2] / 2.0);
    // this is a rotation about z axis by an angle v[2]
    // followed by rotation about y axis by an angle v[1]
    IMP::algebra::Rotation3D r(cy * cz, sy * sz, sy * cz, cy * sz);

    // rotate points
    for (unsigned int point_index = 0; point_index < points.size();
         point_index++) {
      rotated_points[point_index] = r * points[point_index];
    }
    // project
    std::auto_ptr<Projection> p(new Projection(rotated_points, radii, mass,
                                               pixel_size, resolution,
                                               axis_size));
    p->set_rotation(r);
    p->set_axis(IMP::algebra::Vector3D(v.get_cartesian_coordinates()));
    p->set_id(i);
    // rasmol
    // std::cout << "#projection " << i+1
    //<<"\nreset\nrotate Z " << RAD_2_DEG(v[2]);
    // std::cout << "\nrotate Y -" << IMP_RAD_2_DEG(v[1]) << std::endl;
    // chimera
    // std::cout << "#projection " << i+1
    //<<"\nreset;turn x 180; turn z -" <<  IMP_RAD_2_DEG(v[2]);
    // std::cout << ";turn y -" << IMP_RAD_2_DEG(v[1])
    // << ";wait;sleep 3;"<< std::endl;
    // string file_name = "projection_" +
    //   string(boost::lexical_cast<string>(i+1)) + ".pgm";
    // p.write_PGM(file_name);
    projections.push_back(p.release());
  }
}
Exemplo n.º 15
0
// constrain the swing using an ellipse
bool SwingAndTwist::ConstrainSwingWithEllipse(const MCore::Vector2& ellipseRadii)
{
	// safety check, to prevent 'explosions' :)
	if ((ellipseRadii.x > -0.05 && ellipseRadii.x < 0.05) || (ellipseRadii.y > -0.05 && ellipseRadii.y < 0.05)) 
		return ConstrainSwingWithRectangle(ellipseRadii); 

	// the ellipse radii
	MCore::Vector2 radii(ellipseRadii);

	// check if the swing is outside of the spherical ellipse
	float tx = mSwing.x / radii.x;
	float ty = mSwing.y / radii.y;

	if (tx * tx + ty * ty - 1 > 0)
	{
		// if so, then find the closest point on the ellipse to the swing
		Vector2 out;
		bool transpose = false;

		// depending on what were working with, rotate our space to avoide steep slopes in the below equation.
		// because when y is large and x is close to 0, the slope of the graph gets very steep near the root causing neumerical issues.
		if (Math::Abs(mSwing.x) > Math::Abs(mSwing.y))
		{
			float temp;
			transpose	= true;
			temp		= radii.x;
			radii.x		= radii.y;
			radii.y		= temp;

			temp		= mSwing.x;
			mSwing.x	= mSwing.y;
			mSwing.y	= temp;
		}

		// now solve for t in the following equation. t will corrospond to the candidate 
		// points on the ellipse which are closest to the swing:
		// mSwing.y * t^4 + (f - e) * t^3 + (f + e) * t - mSwing.y = 0
		float rxByry = radii.x / radii.y;
		float e = 2 * (radii.y - radii.x * rxByry);
		float f = 2 * mSwing.x * rxByry;

		float c[5];	// coefficients
		float s[4]; // solutions

		// the coefficients in the equation were trying to solve
		c[4] = mSwing.y;
		c[3] = (f - e);
		c[2] = 0;
		c[1] = (f + e);
		c[0] = -mSwing.y;

		// solve it
		// now s has the root that were found and rootsFound has the number of roots found
		int rootsFound = RootSolver::SolveQuartic(c, s);

		// go through each root found and find the one that corresponds to the closest point on the ellipse 
		// to our swing
		Vector2 outTemp;
		float root = s[0];
		float rootSqr = root * root;
		float inv1pRootSqr = 1 / (1 + rootSqr);
		out.x = radii.x * (1 - rootSqr) * inv1pRootSqr;
		out.y = radii.y * 2 * root * inv1pRootSqr;

		for (int i=1; i<rootsFound; i++)
		{
			root		 = s[i];
			rootSqr		 = root * root;
			inv1pRootSqr = 1.0f / (1.0f + rootSqr);
			outTemp.x	 = radii.x * (1.0f - rootSqr) * inv1pRootSqr;
			outTemp.y	 = radii.y * 2.0f * root * inv1pRootSqr;

			if ((outTemp - mSwing).SquareLength() < (out - mSwing).SquareLength())
				out = outTemp;
		}

		// rotate back
		if (transpose)
		{
			float temp;
			temp = radii.x;
			radii.x = radii.y;
			radii.y = temp;

			temp = out.x;
			out.x = out.y;
			out.y = temp;
		}

		mSwing = out;
		return true;
	}

	return false;
}
Exemplo n.º 16
0
void FloatRoundedRect::constrainRadii()
{
    m_radii.scaleAndFloor(calcBorderRadiiConstraintScaleFor(rect(), radii()));
}
Exemplo n.º 17
0
//----------------------------------------------------------
void ofPolyline::arc(const ofPoint & center, float radiusX, float radiusY, float angleBegin, float angleEnd, bool clockwise, int circleResolution){
    
    if(circleResolution<=1) circleResolution=2;
    setCircleResolution(circleResolution);
    points.reserve(points.size()+circleResolution);

    const float epsilon = 0.0001f;
    
    const size_t nCirclePoints = circlePoints.size();
    float segmentArcSize  = M_TWO_PI / (float)nCirclePoints;
    
    // convert angles to radians and wrap them into the range 0-M_TWO_PI and
    float angleBeginRad = wrapAngle(ofDegToRad(angleBegin));
    float angleEndRad =   wrapAngle(ofDegToRad(angleEnd));
    
    while(angleBeginRad >= angleEndRad) angleEndRad += M_TWO_PI;
    
    // determine the directional angle delta
    float d = clockwise ? angleEndRad - angleBeginRad : angleBeginRad - angleEndRad;
    // find the shortest angle delta, clockwise delta direction yeilds POSITIVE values
    float deltaAngle = atan2(sin(d),cos(d));
    
    // establish the remaining angle that we have to work through
    float remainingAngle = deltaAngle;
    
    // if the delta angle is in the CCW direction OR the start and stop angles are
    // effectively the same adjust the remaining angle to be a be a full rotation
    if(deltaAngle < 0 || abs(deltaAngle) < epsilon) remainingAngle += M_TWO_PI;
    
    ofPoint radii(radiusX,radiusY);
    ofPoint point;
    
    int currentLUTIndex = 0;
    bool isFirstPoint = true; // special case for the first point
    
    while(remainingAngle > 0) {
        if(isFirstPoint) {
            // TODO: should this be the exact point on the circle or
            // should it be an intersecting point on the line that connects two
            // surrounding LUT points?
            //
            // get the EXACT first point requested (for points that
            // don't fall precisely on a LUT entry)
            point = ofPoint(cos(angleBeginRad),sin(angleBeginRad));
            // set up the get any in between points from the LUT
            float ratio = angleBeginRad / M_TWO_PI * (float)nCirclePoints;
            currentLUTIndex = clockwise ? (int)ceil(ratio) : (int)floor(ratio);
            float lutAngleAtIndex = currentLUTIndex * segmentArcSize;
            // the angle between the beginning angle and the next angle in the LUT table
            float d = clockwise ? (lutAngleAtIndex - angleBeginRad) : (angleBeginRad - lutAngleAtIndex);
            float firstPointDelta = atan2(sin(d),cos(d)); // negative is in the clockwise direction
            
            // if the are "equal", get the next one CCW
            if(abs(firstPointDelta) < epsilon) {
                currentLUTIndex = clockwise ? (currentLUTIndex + 1) : (currentLUTIndex - 1);
                firstPointDelta = segmentArcSize; // we start at the next lut point
            }
            
            // start counting from the offset
            remainingAngle -= firstPointDelta;
            isFirstPoint = false;
        } else {
            point = ofPoint(circlePoints[currentLUTIndex].x,circlePoints[currentLUTIndex].y);
            if(clockwise) {
                currentLUTIndex++; // go to the next LUT point
                remainingAngle -= segmentArcSize; // account for next point
                // if the angle overshoots, then the while loop will fail next time
            } else {
                currentLUTIndex--; // go to the next LUT point
                remainingAngle -= segmentArcSize; // account for next point
                // if the angle overshoots, then the while loop will fail next time
            }
        }
        
        // keep the current lut index in range
        if(clockwise) {
            currentLUTIndex = currentLUTIndex % nCirclePoints;
        } else {
            if(currentLUTIndex < 0) currentLUTIndex = nCirclePoints + currentLUTIndex;
        }
        
        // add the point to the poly line
        point = point * radii + center;
        points.push_back(point);
        
        // if the next LUT point moves us past the end angle then
        // add a a point a the exact end angle and call it finished
        if(remainingAngle < epsilon) {
            point = ofPoint(cos(angleEndRad),sin(angleEndRad));
            point = point * radii + center;
            points.push_back(point);
            remainingAngle = 0; // call it finished, the next while loop test will fail
        }
    }
    flagHasChanged();
}
//- Construct from components
radialBinsNormalised::radialBinsNormalised
(
    const polyMesh& mesh,
    const dictionary& dict
)
:
    binModel(mesh, dict),
    propsDict_(dict.subDict(typeName + "Properties")),
    startPoint_(propsDict_.lookup("startPoint")),
    endPoint_(propsDict_.lookup("endPoint")),
    h_(mag(endPoint_ - startPoint_)),
    unitVector_((endPoint_ - startPoint_)/mag(endPoint_ - startPoint_)),
    normalVector_(vector::zero),
    radius_(readScalar(propsDict_.lookup("radius"))),
    nBins_(readLabel(propsDict_.lookup("nBins"))),
    binWidth_(radius_/scalar(nBins_)),

    magRadii_(),
    binWidths_(),
//     volumes_(),
    avVolume_(0.0),
    avVolumeNormalised_(0.0),
    minBinWidth_(0.0),
    n_()

{
    //- set volumes --- here we impose a constant volume in all bins,
    // hence the binWidth is going change radially

   avVolume_ = radius_*radius_*constant::mathematical::pi*h_/nBins_;

//     Info << "average volume: " << avVolume_ << endl;

    DynamicList<scalar> radii(0);
    DynamicList<scalar> binWidths(0);

    binWidths.append(sqrt(avVolume_/(constant::mathematical::pi*h_)));

    radii.append(0.5*binWidths[0]);

    for(label i = 1; i < nBins_; i++)
    {
        scalar r2 = radii[i-1] + 0.5*binWidths[i-1];
        scalar r1 = sqrt((avVolume_/(constant::mathematical::pi*h_)) + (r2*r2));

        if(r2 <= radius_)
        {
            radii.append(0.5*(r1+r2));
            binWidths.append(r1-r2);
        }
        else
        {
            break;
        }
    }

    //binWidths.shrink();
    //radii.shrink();

    nBins_ = binWidths.size();

    magRadii_.setSize(nBins_, 0.0);
    binWidths_.setSize(nBins_, 0.0);
//     volumes_.setSize(nBins_, 0.0);

    forAll(magRadii_, n)
    {
        magRadii_[n] = radii[n];
        binWidths_[n] = binWidths[n];

//         if(n == 0)
//         {
//             volumes_[n] = mathematicalConstant::pi*binWidths_[n]*binWidths_[n]*h_;
//         }
//         else
//         {
//             volumes_[n] = 2.0*mathematicalConstant::pi*magRadii_[n]*binWidths_[n]*h_;
//         }
    }
Exemplo n.º 19
0
//- Construct from components
sphericalBins::sphericalBins
(
    const polyMesh& mesh,
    const dictionary& dict
)
:
    binModel(mesh, dict),
    propsDict_(dict.subDict(typeName + "Properties")),
    startPoint_(propsDict_.lookup("startPoint")),
    radius_(readScalar(propsDict_.lookup("radius"))),
    nBins_(readLabel(propsDict_.lookup("nBins"))),
    binWidth_(radius_/scalar(nBins_)),

    magRadii_(),
    binWidths_(),
    avVolume_(0.0),
    minBinWidth_(0.0),
    n_()
{
    //- set volumes --- here we impose a constant volume in all bins,
    // hence the binWidth is going change radially

    avVolume_ = 4.0*radius_*radius_*radius_*constant::mathematical::pi/(3.0*nBins_);

    Info << "average volume: " << avVolume_ << endl;

    DynamicList<scalar> radii(0);
    DynamicList<scalar> binWidths(0);

    scalar binWidth = Foam::pow((3.0*avVolume_/(4.0*constant::mathematical::pi)), (1.0/3.0));

    Info << "starting binWidth: " << binWidth << endl;

    binWidths.append(binWidth);

    radii.append(0.5*binWidths[0]);

    for(label i = 1; i < nBins_; i++)
    {
        scalar r2 = radii[i-1] + 0.5*binWidths[i-1];
        scalar r1 = pow(((3.0*avVolume_/(4.0*constant::mathematical::pi)) + (r2*r2*r2)), (1.0/3.0));

        if(r2 <= radius_)
        {
            radii.append(0.5*(r1+r2));
            binWidths.append(r1-r2);
        }
        else
        {
            break;
        }
    }

    //binWidths.shrink();
    //radii.shrink();

    nBins_ = binWidths.size();

    magRadii_.setSize(nBins_, 0.0);
    binWidths_.setSize(nBins_, 0.0);

    forAll(magRadii_, n)
    {
        magRadii_[n] = radii[n];
        binWidths_[n] = binWidths[n];
    }
Exemplo n.º 20
0
int main(int argc, char ** argv) {
	if (argc<2) {
		fprintf(stderr, "usage: mis [path] [memory budget in GB]\n");
		exit(-1);
	}
	std::string path = argv[1];
	long memory_bytes = ((argc>=3)?atol(argv[2]):8l) * (1024l*1024l*1024l);

	Graph graph(path);
	graph.set_memory_bytes(memory_bytes);
	Bitmap * active_in = graph.alloc_bitmap();
	Bitmap * active_out = graph.alloc_bitmap();
	BigVector<unsigned long [2]> visited(graph.path+"/visited", graph.vertices);
	BigVector<VertexId> radii(graph.path+"/radii", graph.vertices);
	graph.set_vertex_data_bytes( graph.vertices * ( sizeof(VertexId) + sizeof(long) * 2 ) );

	srand(time(NULL));

	double start_time = get_time();
	int iteration;
	VertexId active_vertices;
	VertexId max_radii;

	active_out->clear();
	graph.stream_vertices<VertexId>([&](VertexId i){
		visited[i][0] = 0ul;
		visited[i][1] = 0ul;
		radii[i] = -1;
		return 0;
	});
	for (int k=0;k<K;k++) {
		VertexId vid = rand() % graph.vertices;
		visited[vid][1] |= (1ul << k);
		radii[vid] = 0;
		active_out->set_bit(vid);
	}
	iteration = 0;
	active_vertices = K;
	while (active_vertices > 0) {
		iteration++;
		printf("%7d: %d\n", iteration, active_vertices);
		int now = iteration % 2;
		int next = 1 - now;
		std::swap(active_in, active_out);
		active_out->clear();
		active_vertices = graph.stream_edges<VertexId>([&](Edge & e) {
			if (visited[e.target][now] != visited[e.source][now]) {
				__sync_fetch_and_or( &visited[e.target][next], visited[e.source][now] );
				VertexId old_radii = radii[e.target];
				if (radii[e.target]!=iteration) {
					if (cas(&radii[e.target], old_radii, iteration)) {
						active_out->set_bit(e.target);
						return 1;
					}
				}
			}
			return 0;
		}, active_in);
		active_vertices = graph.stream_vertices<VertexId>([&](VertexId i){
			visited[i][now] = visited[i][next];
			return 1;
		}, active_out); // necessary?
	}
	max_radii = 0;
	for (VertexId i=0;i<graph.vertices;i++) {
		if (max_radii < radii[i]) {
			max_radii = radii[i];
		}
	}
	std::vector<VertexId> candidates;
	VertexId threshold = 0;
	while (candidates.size()<K) {
		for (VertexId i=0;i<graph.vertices;i++) {
			if (radii[i]==max_radii-threshold) candidates.push_back(i);
		}
		threshold++;
	}
	printf("radii:%d\n", max_radii);

	active_out->clear();
	graph.stream_vertices<VertexId>([&](VertexId i){
		visited[i][0] = 0ul;
		visited[i][1] = 0ul;
		radii[i] = -1;
		return 0;
	});
	for (int k=0;k<K;k++) {
		VertexId vid = candidates[k];
		visited[vid][1] |= (1ul << k);
		radii[vid] = 0;
		active_out->set_bit(vid);
	}
	iteration = 0;
	active_vertices = K;
	while (active_vertices > 0) {
		iteration++;
		printf("%7d: %d\n", iteration, active_vertices);
		int now = iteration % 2;
		int next = 1 - now;
		std::swap(active_in, active_out);
		active_out->clear();
		active_vertices = graph.stream_edges<VertexId>([&](Edge & e) {
			if (visited[e.target][now] != visited[e.source][now]) {
				__sync_fetch_and_or( &visited[e.target][next], visited[e.source][now] );
				VertexId old_radii = radii[e.target];
				if (radii[e.target]!=iteration) {
					if (cas(&radii[e.target], old_radii, iteration)) {
						active_out->set_bit(e.target);
						return 1;
					}
				}
			}
			return 0;
		}, active_in);
		active_vertices = graph.stream_vertices<VertexId>([&](VertexId i){
			visited[i][now] = visited[i][next];
			return 1;
		}, active_out); // necessary?
	}
	max_radii = 0;
	for (VertexId i=0;i<graph.vertices;i++) {
		if (max_radii < radii[i]) {
			max_radii = radii[i];
		}
	}
	printf("radii: %d\n", max_radii);

	double end_time = get_time();
	printf("radii: %d\n", max_radii);
	printf("time: %.2f seconds\n", end_time - start_time);

	return 0;
}