예제 #1
0
파일: blobs.cpp 프로젝트: josegutab/scipion
// Computes sum of the values of a unitary blob on grid points. The blob is
// supposed to be at the origin of the absolute coordinate system
double sum_blob_SimpleGrid(const struct blobtype &blob, const SimpleGrid &grid,
                           const Matrix2D<double> *D)
{
    SPEED_UP_temps012;
    Matrix1D<double> gr(3), ur(3), corner1(3), corner2(3);
    double         actual_radius;
    int          i, j, k;
    double        sum = 0.0;

    // Compute the limits of the blob in the grid coordinate system
    grid.universe2grid(vectorR3(-blob.radius, -blob.radius, -blob.radius), corner1);
    grid.universe2grid(vectorR3(blob.radius, blob.radius, blob.radius), corner2);
    if (D != NULL)
        box_enclosing(corner1, corner2, *D, corner1, corner2);

    // Compute the sum in the points inside the grid
    // The integer part of the vectors is taken for not picking points
    // just in the border of the blob, which we know they are 0.
    for (i = (int)XX(corner1); i <= (int)XX(corner2); i++)
        for (j = (int)YY(corner1); j <= (int)YY(corner2); j++)
            for (k = (int)ZZ(corner1); k <= (int)ZZ(corner2); k++)
            {
                VECTOR_R3(gr, i, j, k);
                grid.grid2universe(gr, ur);
                if (D != NULL)
                    M3x3_BY_V3x1(ur, *D, ur);
                actual_radius = ur.module();
                if (actual_radius < blob.radius)
                    sum += kaiser_value(actual_radius,
                                        blob.radius, blob.alpha, blob.order);
            }
    return sum;
}
MBoundingBox OpenSubdivDrawOverride::boundingBox(const MDagPath& objPath, const MDagPath& cameraPath) const
{
    MPoint corner1( -1.0, -1.0, -1.0 );
    MPoint corner2( 1.0, 1.0, 1.0);

    return MBoundingBox(corner1, corner2);
}
예제 #3
0
MBoundingBox bruiseMapNode::boundingBox() const
{ 
	MPoint corner1( -1.-1,-1 );
	MPoint corner2( 1,1,1 );

	return MBoundingBox( corner1, corner2 );
}
예제 #4
0
MBoundingBox octreeVizNode::boundingBox() const
{ 
	MPoint corner1( -1,-1,-1 );
	MPoint corner2( 1,1,1 );

	return MBoundingBox( corner1, corner2 );
}
예제 #5
0
void Container::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    QGraphicsItem::mousePressEvent(event);
    if(this->isSelected())
    {
        QRectF r = this->rect();
        QRectF corner1(r.width()/2 -8,0,16,5);
        QRectF corner2(0,r.bottom()/2-8,5,16);
        QRectF corner3(r.right()-5,r.bottom()/2-8,5,16);
        QRectF corner4(r.width()/2 -8,r.bottom()-5,16,5);
        if(corner1.contains(event->pos()))
        {
            _onResize = true;
            _resizeType = 0;
        }
        else if(corner2.contains(event->pos()))
        {
            _onResize = true;
            _resizeType = 1;
        }
        else if(corner3.contains(event->pos()))
        {
            _onResize = true;
            _resizeType = 2;
        }
        else if(corner4.contains(event->pos()))
        {
            _onResize = true;
            _resizeType = 3;
        }
    }
}
예제 #6
0
MBoundingBox BCIViz::boundingBox() const
{   
	
	MPoint corner1(-1.0, -1.0, -1.0);
	MPoint corner2( 1.0,  1.0,  1.0);

	return MBoundingBox( corner1, corner2 );
}
예제 #7
0
MBoundingBox wingVizNode::boundingBox() const
{ 
	MPoint corner1( 0,0,0 );
	MPoint corner2( 1,1,1 );
	
	m_base->getBBox(corner1, corner2);

	return MBoundingBox( corner1, corner2 );
}
예제 #8
0
MBoundingBox nailConstraintNode::boundingBox() const
{
    // std::cout << "nailConstraintNode::boundingBox()" << std::endl;
    //load the pdbs
    MObject node = thisMObject();

    MPoint corner1(-1, -1, -1);
    MPoint corner2(1, 1, 1);
    return MBoundingBox(corner1, corner2);
}
예제 #9
0
MBoundingBox ProxyViz::boundingBox() const
{   
	BoundingBox bbox = plantExample(0)->geomBox();
	if(numPlants() > 0) bbox = gridBoundingBox();
	else if(!isGroundEmpty() ) bbox = ground()->getBBox();
	
	MPoint corner1(bbox.m_data[0], bbox.m_data[1], bbox.m_data[2]);
	MPoint corner2(bbox.m_data[3], bbox.m_data[4], bbox.m_data[5]);

	return MBoundingBox( corner1, corner2 );
}
예제 #10
0
MBoundingBox FootPrintDrawOverride::boundingBox(
	const MDagPath& objPath,
	const MDagPath& cameraPath) const
{
	MPoint corner1( -0.17, 0.0, -0.7 );
	MPoint corner2( 0.17, 0.0, 0.3 );

	float multiplier = getMultiplier(objPath);
	corner1 = corner1 * multiplier;
	corner2 = corner2 * multiplier;

	return MBoundingBox( corner1, corner2 );
}
예제 #11
0
	//------------------------------------------------------------------------------//
	void GeoTerrainSection::_calcCurrentLod(Camera* cam)
	{
		Vector2 corner0(mSectionBound.getMinimum().x, mSectionBound.getMinimum().z);
		Vector2 corner1(mSectionBound.getMinimum().x, mSectionBound.getMaximum().z);
		Vector2 corner2(mSectionBound.getMaximum().x, mSectionBound.getMaximum().z);
		Vector2 corner3(mSectionBound.getMaximum().x, mSectionBound.getMinimum().z);

		Vector2 viewPoint(cam->getPosition().x, cam->getPosition().z);

		// compute view distance to our 4 corners
		float distance0 = viewPoint.distance(corner0);
		float distance1 = viewPoint.distance(corner1);
		float distance2 = viewPoint.distance(corner2);
		float distance3 = viewPoint.distance(corner3);

		// compute min distance as the test value
		float dist = minimum(distance0, distance1);
		dist = minimum(dist, distance2);
		dist = minimum(dist, distance3);

		// make sure the minimum distance is non-zero
		dist = maximum(dist, 0.0001f);

		// find the lowest lod which will suffice
		mCurrentLod = 0;
		bool finished = false;

		float fScale = mCreator->getLodErrorScale();
		float fLimit = mCreator->getRatioLimit();

		while (!finished)
		{
			// find the ratio of variance over distance
			float variance = mErrorMetrics[mCurrentLod];
			float vRatio = (variance * fScale) / dist;

			// if we exceed the ratio limit, move to the next lod
			if (vRatio > fLimit
				&& mCurrentLod + 1 < TOTAL_DETAIL_LEVELS)
			{
				++mCurrentLod;
			}
			else
			{
				finished=true;
			}
		}
	}
예제 #12
0
void CBoundingBoxAligned::Transform(const CMatrix3D& transform, CBoundingBoxOriented& result) const
{
	// The idea is this: compute the corners of this bounding box, transform them according to the specified matrix,
	// then derive the box center, orientation vectors, and half-sizes.
	// TODO: this implementation can be further optimized; see Philip's comments on http://trac.wildfiregames.com/ticket/914
	const CVector3D& pMin = m_Data[0];
	const CVector3D& pMax = m_Data[1];

	// Find the corners of these bounds. We only need some of the corners to derive the information we need, so let's 
	// not actually compute all of them. The corners are numbered starting from the minimum position (m_Data[0]), going
	// counter-clockwise in the bottom plane, and then in the same order for the top plane (starting from the corner
	// that's directly above the minimum position). Hence, corner0 is pMin and corner6 is pMax, so we don't need to
	// custom-create those.
	
	CVector3D corner0; // corner0 is pMin, no need to copy it
	CVector3D corner1(pMax.X, pMin.Y, pMin.Z);
	CVector3D corner3(pMin.X, pMin.Y, pMax.Z);
	CVector3D corner4(pMin.X, pMax.Y, pMin.Z);
	CVector3D corner6; // corner6 is pMax, no need to copy it

	// transform corners to world space
	corner0 = transform.Transform(pMin); // = corner0
	corner1 = transform.Transform(corner1);
	corner3 = transform.Transform(corner3);
	corner4 = transform.Transform(corner4);
	corner6 = transform.Transform(pMax); // = corner6

	// Compute orientation vectors, half-size vector, and box center. We can get the orientation vectors by just taking
	// the directional vectors from a specific corner point (corner0) to the other corners, once in each direction. The
	// half-sizes are similarly computed by taking the distances of those sides and dividing them by 2. Finally, the 
	// center is simply the middle between the transformed pMin and pMax corners.

	const CVector3D sideU(corner1 - corner0);
	const CVector3D sideV(corner4 - corner0);
	const CVector3D sideW(corner3 - corner0);

	result.m_Basis[0] = sideU.Normalized();
	result.m_Basis[1] = sideV.Normalized();
	result.m_Basis[2] = sideW.Normalized();

	result.m_HalfSizes = CVector3D(
		sideU.Length()/2.f,
		sideV.Length()/2.f,
		sideW.Length()/2.f
	);

	result.m_Center = (corner0 + corner6) * 0.5f;
}
예제 #13
0
파일: Cube.cpp 프로젝트: mrkno/Ray-Tracer
Cube::Cube(Vector position, float size, Colour colour)
{
	Vector corner1(position.x + size, position.y + size, position.z + size);
	Vector corner2(position.x - size, position.y - size, position.z - size);

	auto maxX = max(corner1.x, corner2.x);
	auto maxY = max(corner1.y, corner2.y);
	auto maxZ = max(corner1.z, corner2.z);
	maxVector = Vector(maxX, maxY, maxZ);
	auto minX = min(corner1.x, corner2.x);
	auto minY = min(corner1.y, corner2.y);
	auto minZ = min(corner1.z, corner2.z);
	minVector = Vector(minX, minY, minZ);
	center = (maxVector + minVector) / 2;
	color = colour;
}
예제 #14
0
Primitive::Ptr Renderer::CreateLine( const sf::Vector2f& begin, const sf::Vector2f& end, const sf::Color& color, float thickness ) {
	// Get vector perpendicular to direction of the line vector.
	// Vector is rotated CCW 90 degrees and normalized.
	sf::Vector2f normal( end - begin );
	std::swap( normal.x, normal.y );
	float length = std::sqrt( normal.x * normal.x + normal.y * normal.y );
	normal.x /= -length;
	normal.y /= length;

	sf::Vector2f corner0( begin + normal * ( thickness * .5f ) );
	sf::Vector2f corner1( begin - normal * ( thickness * .5f ) );
	sf::Vector2f corner2( end - normal * ( thickness * .5f ) );
	sf::Vector2f corner3( end + normal * ( thickness * .5f ) );

	return CreateQuad( corner3, corner2, corner1, corner0, color );
}
예제 #15
0
MBoundingBox mpBox::boundingBox() const
{
    MObject thisNode = thisMObject();
    float x, y, z;
    MPlug xsize = MPlug( thisNode, aXsize );
    xsize.getValue(x);
    MPlug ysize = MPlug( thisNode, aYsize );
    ysize.getValue(y);
    MPlug zsize = MPlug( thisNode, aZsize );
    zsize.getValue(z);

    MPoint corner1(x, y, z);
    MPoint corner2(-x, -y, -z);
    MBoundingBox bbox = MBoundingBox( corner1, corner2 );

    return bbox;
}
예제 #16
0
MBoundingBox swissArmyLocator::boundingBox() const
{   
	// Get the size
	//
	MObject thisNode = thisMObject();
	MPlug plug(thisNode, aSize);
	MDistance sizeVal;
	plug.getValue(sizeVal);

	double multiplier = sizeVal.asCentimeters();
 
	MPoint corner1(-1.1, 0.0, -1.1);
	MPoint corner2(1.1, 0.0, 1.1);

	corner1 = corner1 * multiplier;
	corner2 = corner2 * multiplier;

	return MBoundingBox(corner1, corner2);
}
예제 #17
0
MBoundingBox footPrint::boundingBox() const
{
	// Get the size
	//
	MObject thisNode = thisMObject();
	MPlug plug( thisNode, size );
	MDistance sizeVal;
	plug.getValue( sizeVal );

	double multiplier = sizeVal.asCentimeters();

	MPoint corner1( -0.17, 0.0, -0.7 );
	MPoint corner2( 0.17, 0.0, 0.3 );

	corner1 = corner1 * multiplier;
	corner2 = corner2 * multiplier;

	return MBoundingBox( corner1, corner2 );
}
예제 #18
0
MBoundingBox mtmEnvLight::boundingBox() const
{   
	// Get the size
	//
	//MObject thisNode = thisMObject();
	//MPlug plug( thisNode, size );
	//MDistance sizeVal;
	//plug.getValue( sizeVal );

	//double multiplier = sizeVal.asCentimeters();
 
	MPoint corner1( -0.7, 0.0, -0.3 );
	MPoint corner2( 0.7, 0.0, 0.3 );

	//corner1 = corner1 * multiplier;
	//corner2 = corner2 * multiplier;

	return MBoundingBox( corner1, corner2 );
}
예제 #19
0
파일: SoRing.cpp 프로젝트: CURG/graspit_bci
void SoRing::computeBBox(SoAction*, SbBox3f& box, SbVec3f& BBcenter)
{
  float Xc, Yc;
  center.getValue().getValue(Xc,Yc);

  // centered at origin
  BBcenter.setValue(Xc, Yc, 0.);

  // bounding box
  float R = outerRadius.getValue();
  float theta = sweepAngle.getValue()*M_PI/180.F;

  float Xmin, Ymin, Ymax;
  if ( theta < M_PI_2 )
  {
    Ymin = 0;
    Ymax = R*sin(theta);
    Xmin = 0;
  }
  else if ( theta < M_PI )
  {
    Ymin = 0;
    Ymax = R;
    Xmin = R*cos(theta);
  }
  else if ( theta < 3*M_PI_2 )
  {
    Ymin = R*sin(theta);
    Ymax = R;
    Xmin = -R;
  }
  else
  {
    Xmin = -R;
    Ymin = -R;
    Ymax = R;
  }

  SbVec3f corner1(Xmin+Xc,Ymin+Yc,0);
  SbVec3f corner2(R+Xc,Ymax+Yc,0);
  box.setBounds(corner1,corner2);
}
예제 #20
0
void CBC_DefaultPlacement::place() {
  int32_t pos = 0;
  int32_t row = 4;
  int32_t col = 0;
  do {
    if ((row == m_numrows) && (col == 0)) {
      corner1(pos++);
    }
    if ((row == m_numrows - 2) && (col == 0) && ((m_numcols % 4) != 0)) {
      corner2(pos++);
    }
    if ((row == m_numrows - 2) && (col == 0) && (m_numcols % 8 == 4)) {
      corner3(pos++);
    }
    if ((row == m_numrows + 4) && (col == 2) && ((m_numcols % 8) == 0)) {
      corner4(pos++);
    }
    do {
      if ((row < m_numrows) && (col >= 0) && !hasBit(col, row)) {
        utah(row, col, pos++);
      }
      row -= 2;
      col += 2;
    } while (row >= 0 && (col < m_numcols));
    row++;
    col += 3;
    do {
      if ((row >= 0) && (col < m_numcols) && !hasBit(col, row)) {
        utah(row, col, pos++);
      }
      row += 2;
      col -= 2;
    } while ((row < m_numrows) && (col >= 0));
    row += 3;
    col++;
  } while ((row < m_numrows) || (col < m_numcols));
  if (!hasBit(m_numcols - 1, m_numrows - 1)) {
    setBit(m_numcols - 1, m_numrows - 1, true);
    setBit(m_numcols - 2, m_numrows - 2, true);
  }
}
예제 #21
0
	//-------------------------------------------------------------------------------//
	void ChunkTerrainSection::_calcLod(Camera* cam)
	{
		// compute a 2d point for each corner of the section
		Vector2 corner0(mSectionBound.getMinimum().x, mSectionBound.getMinimum().z);
		Vector2 corner1(mSectionBound.getMinimum().x, mSectionBound.getMaximum().z);
		Vector2 corner2(mSectionBound.getMaximum().x, mSectionBound.getMaximum().z);
		Vector2 corner3(mSectionBound.getMaximum().x, mSectionBound.getMinimum().z);

		Vector2 viewPoint= Vector2(cam->getPosition().x, cam->getPosition().z);

		// compute view distance to our 4 corners
		float distance0 = viewPoint.distance(corner0);
		float distance1 = viewPoint.distance(corner1);
		float distance2 = viewPoint.distance(corner2);
		float distance3 = viewPoint.distance(corner3);
		
		_recursiveTessellate(distance0, distance1, distance2, distance3, 
			0, 0, 0, 
			mCreator->getLodErrorScale(), mCreator->getRatioLimit());

	}
예제 #22
0
파일: Decal.cpp 프로젝트: Gallaecio/0ad
void CModelDecal::CalcVertexExtents(ssize_t& i0, ssize_t& j0, ssize_t& i1, ssize_t& j1)
{
	CVector3D corner0(m_Decal.m_OffsetX + m_Decal.m_SizeX/2, 0, m_Decal.m_OffsetZ + m_Decal.m_SizeZ/2);
	CVector3D corner1(m_Decal.m_OffsetX + m_Decal.m_SizeX/2, 0, m_Decal.m_OffsetZ - m_Decal.m_SizeZ/2);
	CVector3D corner2(m_Decal.m_OffsetX - m_Decal.m_SizeX/2, 0, m_Decal.m_OffsetZ - m_Decal.m_SizeZ/2);
	CVector3D corner3(m_Decal.m_OffsetX - m_Decal.m_SizeX/2, 0, m_Decal.m_OffsetZ + m_Decal.m_SizeZ/2);

	corner0 = GetTransform().Transform(corner0);
	corner1 = GetTransform().Transform(corner1);
	corner2 = GetTransform().Transform(corner2);
	corner3 = GetTransform().Transform(corner3);

	i0 = floor(std::min(std::min(corner0.X, corner1.X), std::min(corner2.X, corner3.X)) / TERRAIN_TILE_SIZE);
	j0 = floor(std::min(std::min(corner0.Z, corner1.Z), std::min(corner2.Z, corner3.Z)) / TERRAIN_TILE_SIZE);
	i1 = ceil(std::max(std::max(corner0.X, corner1.X), std::max(corner2.X, corner3.X)) / TERRAIN_TILE_SIZE);
	j1 = ceil(std::max(std::max(corner0.Z, corner1.Z), std::max(corner2.Z, corner3.Z)) / TERRAIN_TILE_SIZE);

	i0 = clamp(i0, (ssize_t)0, m_Terrain->GetVerticesPerSide()-1);
	j0 = clamp(j0, (ssize_t)0, m_Terrain->GetVerticesPerSide()-1);
	i1 = clamp(i1, (ssize_t)0, m_Terrain->GetVerticesPerSide()-1);
	j1 = clamp(j1, (ssize_t)0, m_Terrain->GetVerticesPerSide()-1);
}
예제 #23
0
/* Sum spline on a grid ---------------------------------------------------- */
double sum_spatial_Bspline03_SimpleGrid(const SimpleGrid &grid)
{
    Matrix1D<double> gr(3), ur(3), corner1(3), corner2(3);
    int          i, j, k;
    double        sum = 0.0;

// Compute the limits of the spline in the grid coordinate system
    grid.universe2grid(vectorR3(-2.0, -2.0, -2.0), corner1);
    grid.universe2grid(vectorR3(2.0, 2.0, 2.0), corner2);

// Compute the sum in the points inside the grid
// The integer part of the vectors is taken for not picking points
// just in the border of the spline, which we know they are 0.
    for (i = (int)XX(corner1); i <= (int)XX(corner2); i++)
        for (j = (int)YY(corner1); j <= (int)YY(corner2); j++)
            for (k = (int)ZZ(corner1); k <= (int)ZZ(corner2); k++)
            {
                VECTOR_R3(gr, i, j, k);
                grid.grid2universe(gr, ur);
                sum += spatial_Bspline03(ur);
            }
    return sum;
}
void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
        SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError, bool ignoreLineWidth ) const
{
    // The full width of the lines to create:
    int linewidth = ignoreLineWidth ? 0 : m_Width;

    linewidth += 2 * aClearanceValue;

    // Creating a reliable clearance shape for circles and arcs is not so easy, due to
    // the error created by segment approximation.
    // for a circle this is not so hard: create a polygon from a circle slightly bigger:
    // thickness = linewidth + s_error_max, and radius = initial radius + s_error_max/2
    // giving a shape with a suitable internal radius and external radius
    // For an arc this is more tricky: TODO

    switch( m_Shape )
    {
    case S_CIRCLE:
        TransformRingToPolygon(
                aCornerBuffer, GetCenter(), GetRadius(), aError, linewidth );
        break;

    case S_ARC:
        TransformArcToPolygon(
                aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, aError, linewidth );
        break;

    case S_SEGMENT:
        TransformOvalClearanceToPolygon(
                aCornerBuffer, m_Start, m_End, linewidth, aError );
        break;

    case S_POLYGON:
        if( IsPolyShapeValid() )
        {
            // The polygon is expected to be a simple polygon
            // not self intersecting, no hole.
            MODULE* module = GetParentModule();     // NULL for items not in footprints
            double orientation = module ? module->GetOrientation() : 0.0;
            wxPoint offset;

            if( module )
                offset = module->GetPosition();

            // Build the polygon with the actual position and orientation:
            std::vector< wxPoint> poly;
            poly = BuildPolyPointsList();

            for( unsigned ii = 0; ii < poly.size(); ii++ )
            {
                RotatePoint( &poly[ii], orientation );
                poly[ii] += offset;
            }

            // If the polygon is not filled, treat it as a closed set of lines
            if( !IsPolygonFilled() )
            {
                for( size_t ii = 1; ii < poly.size(); ii++ )
                {
                    TransformOvalClearanceToPolygon( aCornerBuffer, poly[ii - 1], poly[ii],
                            linewidth, aError );
                }

                TransformOvalClearanceToPolygon( aCornerBuffer, poly.back(), poly.front(),
                        linewidth, aError );
                break;
            }

            // Generate polygons for the outline + clearance
            // This code is compatible with a polygon with holes linked to external outline
            // by overlapping segments.

            // Insert the initial polygon:
            aCornerBuffer.NewOutline();

            for( unsigned ii = 0; ii < poly.size(); ii++ )
                aCornerBuffer.Append( poly[ii].x, poly[ii].y );

            if( linewidth )     // Add thick outlines
            {
                wxPoint corner1( poly[poly.size()-1] );

                for( unsigned ii = 0; ii < poly.size(); ii++ )
                {
                    wxPoint corner2( poly[ii] );

                    if( corner2 != corner1 )
                    {
                        TransformRoundedEndsSegmentToPolygon(
                                aCornerBuffer, corner1, corner2, aError, linewidth );
                    }

                    corner1 = corner2;
                }
            }
        }
        break;

    case S_CURVE:       // Bezier curve
        {
            std::vector<wxPoint> ctrlPoints = { m_Start, m_BezierC1, m_BezierC2, m_End };
            BEZIER_POLY converter( ctrlPoints );
            std::vector< wxPoint> poly;
            converter.GetPoly( poly, m_Width );

            for( unsigned ii = 1; ii < poly.size(); ii++ )
            {
                TransformRoundedEndsSegmentToPolygon(
                        aCornerBuffer, poly[ii - 1], poly[ii], aError, linewidth );
            }
        }
        break;

    default:
        break;
    }
}
예제 #25
0
파일: blobs.cpp 프로젝트: josegutab/scipion
void * blobs2voxels_SimpleGrid( void * data )
{
    ThreadBlobsToVoxels * thread_data = (ThreadBlobsToVoxels *) data;

    const MultidimArray<double> *vol_blobs = thread_data->vol_blobs;
    const SimpleGrid *grid = thread_data->grid;
    const struct blobtype *blob = thread_data->blob;
    MultidimArray<double> *vol_voxels = thread_data->vol_voxels;
    const Matrix2D<double> *D = thread_data->D;
    int istep = thread_data->istep;
    MultidimArray<double> *vol_corr = thread_data->vol_corr;
    const MultidimArray<double> *vol_mask = thread_data->vol_mask;
    ;
    bool FORW = thread_data->FORW;
    int eq_mode = thread_data->eq_mode;

    int min_separation = thread_data->min_separation;

    int z_planes = (int)(ZZ(grid->highest) - ZZ(grid->lowest) + 1);

    Matrix2D<double> Dinv;                   // Inverse of D
    Matrix1D<double> act_coord(3);           // Coord: Actual position inside
    // the voxel volume without deforming
    Matrix1D<double> real_position(3);       // Coord: actual position after
    // applying the V transformation
    Matrix1D<double> beginZ(3);              // Coord: Voxel coordinates of the
    // blob at the 3D point
    // (z0,YY(lowest),XX(lowest))
    Matrix1D<double> beginY(3);              // Coord: Voxel coordinates of the
    // blob at the 3D point
    // (z0,y0,XX(lowest))
    Matrix1D<double> corner2(3), corner1(3); // Coord: Corners of the
    // blob in the voxel volume
    Matrix1D<double> gcurrent(3);            // Position in g of current point
    MultidimArray<double> blob_table;             // Something like a blobprint
    // but with the values of the
    // blob in space
    double         d;                        // Distance between the center
    // of the blob and a voxel position
    int           id;                        // index inside the blob value
    // table for tha blob value at
    // a distance d
    double         intx, inty, intz;         // Nearest integer voxel
    int           i, j, k;                   // Index within the blob volume
    int           process;                   // True if this blob has to be
    // processed
    double         vol_correction=0;         // Correction to apply to the
    // volume when "projecting" back
    SPEED_UP_temps012;

    // Some aliases
#define x0 STARTINGX(*vol_voxels)
#define xF FINISHINGX(*vol_voxels)
#define y0 STARTINGY(*vol_voxels)
#define yF FINISHINGY(*vol_voxels)
#define z0 STARTINGZ(*vol_voxels)
#define zF FINISHINGZ(*vol_voxels)

#ifdef DEBUG

    bool condition = !FORW;
    if (condition)
    {
        (*vol_voxels)().printShape();
        std::cout << std::endl;
        std::cout << "x0= " << x0 << " xF= " << xF << std::endl;
        std::cout << "y0= " << y0 << " yF= " << yF << std::endl;
        std::cout << "z0= " << z0 << " zF= " << zF << std::endl;
        std::cout << grid;
    }
#endif

    // Invert deformation matrix ............................................
    if (D != NULL)
        Dinv = D->inv();

    // Compute a blob value table ...........................................
    blob_table.resize((int)(blob->radius*istep + 1));
    for (size_t i = 0; i < blob_table.xdim; i++)
    {
        A1D_ELEM(blob_table, i) = kaiser_value((double)i/istep, blob->radius, blob->alpha, blob->order);

#ifdef DEBUG_MORE

        if (condition)
            std::cout << "Blob (" << i << ") r=" << (double)i / istep <<
            " val= " << A1D_ELEM(blob_table, i) << std::endl;
#endif

    }

    int assigned_slice;

    do
    {
        assigned_slice = -1;
        do
        {
            pthread_mutex_lock(&blobs_conv_mutex);
            if( slices_processed == z_planes )
            {
                pthread_mutex_unlock(&blobs_conv_mutex);
                return (void*)NULL;
            }

            for(int w = 0 ; w < z_planes ; w++ )
            {
                if( slices_status[w]==0 )
                {
                    slices_status[w] = -1;
                    assigned_slice = w;
                    slices_processed++;

                    for( int in = (w-min_separation+1) ; in <= (w+min_separation-1 ) ; in ++ )
                    {
                        if( in != w )
                        {
                            if( ( in >= 0 ) && ( in < z_planes ))
                            {
                                if( slices_status[in] != -1 )
                                    slices_status[in]++;
                            }
                        }
                    }
                    break;
                }
            }

            pthread_mutex_unlock(&blobs_conv_mutex);
        }
        while( assigned_slice == -1);

        // Convert the whole grid ...............................................
        // Corner of the plane defined by Z. These coordinates are in the
        // universal coord. system
        Matrix1D<double> aux( grid->lowest );
        k = (int)(assigned_slice + ZZ( grid->lowest ));
        ZZ(aux) = k;
        grid->grid2universe(aux, beginZ);

        Matrix1D<double> grid_index(3);

        // Corner of the row defined by Y
        beginY = beginZ;
        for (i = (int) YY(grid->lowest); i <= (int) YY(grid->highest); i++)
        {
            // First point in the row
            act_coord = beginY;
            for (j = (int) XX(grid->lowest); j <= (int) XX(grid->highest); j++)
            {
                VECTOR_R3(grid_index, j, i, k);
#ifdef DEBUG

                if (condition)
                {
                    printf("Dealing blob at (%d,%d,%d) = %f\n", j, i, k, A3D_ELEM(*vol_blobs, k, i, j));
                    std::cout << "Center of the blob      "
                    << act_coord.transpose() << std::endl;
                }
#endif

                // Place act_coord in its right place
                if (D != NULL)
                {
                    M3x3_BY_V3x1(real_position, *D, act_coord);
#ifdef DEBUG

                    if (condition)
                        std::cout << "Center of the blob moved to "
                        //ROB, the "moved" coordinates are in
                        // real_position not in act_coord
                        << act_coord.transpose() << std::endl;
                    << real_position.transpose() << std::endl;
#endif
                    // ROB This is OK if blob.radius is in Cartesian space as I
                    // think is the case
                }
                else
                    real_position = act_coord;

                // These two corners are also real valued
                process = true;
                //ROB
                //This is OK if blob.radius is in Cartesian space as I think is the case
                V3_PLUS_CT(corner1, real_position, -blob->radius);
                V3_PLUS_CT(corner2, real_position, blob->radius);
#ifdef DEFORM_BLOB_WHEN_IN_CRYSTAL
                //ROB
                //we do not need this, it is already in Cartesian space
                //if (D!=NULL)
                //   box_enclosing(corner1,corner2, *D, corner1, corner2);
#endif

                if (XX(corner1) >= xF)
                    process = false;
                if (YY(corner1) >= yF)
                    process = false;
                if (ZZ(corner1) >= zF)
                    process = false;
                if (XX(corner2) <= x0)
                    process = false;
                if (YY(corner2) <= y0)
                    process = false;
                if (ZZ(corner2) <= z0)
                    process = false;
#ifdef DEBUG

                if (!process && condition)
                    std::cout << "   It is outside output volume\n";
#endif

                if (!grid->is_interesting(real_position))
                {
#ifdef DEBUG
                    if (process && condition)
                        std::cout << "   It is not interesting\n";
#endif

                    process = false;
                }

#ifdef DEBUG
                if (condition)
                {
                    std::cout << "Corner 1 for this point " << corner1.transpose() << std::endl;
                    std::cout << "Corner 2 for this point " << corner2.transpose() << std::endl;
                }
#endif

                if (process)
                {
                    // Clip the corners to the volume borders
                    XX(corner1) = ROUND(CLIP(XX(corner1), x0, xF));
                    YY(corner1) = ROUND(CLIP(YY(corner1), y0, yF));
                    ZZ(corner1) = ROUND(CLIP(ZZ(corner1), z0, zF));
                    XX(corner2) = ROUND(CLIP(XX(corner2), x0, xF));
                    YY(corner2) = ROUND(CLIP(YY(corner2), y0, yF));
                    ZZ(corner2) = ROUND(CLIP(ZZ(corner2), z0, zF));
#ifdef DEBUG

                    if (condition)
                    {
                        std::cout << "Clipped and rounded Corner 1 " << corner1.transpose() << std::endl;
                        std::cout << "Clipped and rounded Corner 2 " << corner2.transpose() << std::endl;
                    }
#endif

                    if (!FORW)
                        switch (eq_mode)
                        {
                        case VARTK:
                            vol_correction = 0;
                            break;
                        case VMAXARTK:
                            vol_correction = -1e38;
                            break;
                        }

                    // Effectively convert
                    long N_eq;
                    N_eq = 0;
                    for (intz = ZZ(corner1); intz <= ZZ(corner2); intz++)
                        for (inty = YY(corner1); inty <= YY(corner2); inty++)
                            for (intx = XX(corner1); intx <= XX(corner2); intx++)
                            {
                                int iz = (int)intz, iy = (int)inty, ix = (int)intx;
                                if (vol_mask != NULL)
                                    if (!A3D_ELEM(*vol_mask, iz, iy, ix))
                                        continue;

                                // Compute distance to the center of the blob
                                VECTOR_R3(gcurrent, intx, inty, intz);
#ifdef DEFORM_BLOB_WHEN_IN_CRYSTAL
                                // ROB
                                //if (D!=NULL)
                                //   M3x3_BY_V3x1(gcurrent,Dinv,gcurrent);
#endif

                                V3_MINUS_V3(gcurrent, real_position, gcurrent);
                                d = sqrt(XX(gcurrent) * XX(gcurrent) +
                                         YY(gcurrent) * YY(gcurrent) +
                                         ZZ(gcurrent) * ZZ(gcurrent));
                                if (d > blob->radius)
                                    continue;
                                id = (int)(d * istep);
#ifdef DEBUG_MORE

                                if (condition)
                                {
                                    std::cout << "At (" << intx << ","
                                    << inty << "," << intz << ") distance=" << d;
                                    std::cout.flush();
                                }
#endif

                                // Add at that position the corresponding blob value

                                if (FORW)
                                {
                                    A3D_ELEM(*vol_voxels, iz, iy, ix) +=
                                        A3D_ELEM(*vol_blobs, k, i, j) *
                                        A1D_ELEM(blob_table, id);
#ifdef DEBUG_MORE

                                    if (condition)
                                    {
                                        std::cout << " adding " << A3D_ELEM(*vol_blobs, k, i, j)
                                        << " * " << A1D_ELEM(blob_table, id) << " = "
                                        << A3D_ELEM(*vol_blobs, k, i, j)*
                                        A1D_ELEM(blob_table, id) << std::endl;
                                        std::cout.flush();
                                    }
#endif
                                    if (vol_corr != NULL)
                                        A3D_ELEM(*vol_corr, iz, iy, ix) +=
                                            A1D_ELEM(blob_table, id) * A1D_ELEM(blob_table, id);
                                }
                                else
                                {
                                    double contrib = A3D_ELEM(*vol_corr, iz, iy, ix) *
                                                     A1D_ELEM(blob_table, id);
                                    switch (eq_mode)
                                    {
                                    case VARTK:
                                        vol_correction += contrib;
                                        N_eq++;
                                        break;
                                    case VMAXARTK:
                                        if (contrib > vol_correction)
                                            vol_correction = contrib;
                                        break;

                                    }
#ifdef DEBUG_MORE
                                    if (condition)
                                    {
                                        std::cout << " adding " << A3D_ELEM(*vol_corr, iz, iy, ix)
                                        << " * " << A1D_ELEM(blob_table, id) << " = "
                                        << contrib << std::endl;
                                        std::cout.flush();
                                    }
#endif

                                }
                            }
                    if (N_eq == 0)
                        N_eq = 1;
                    if (!FORW)
                    {
                        A3D_ELEM(*vol_blobs, k, i, j) += vol_correction / N_eq;
#ifdef DEBUG_MORE

                        std::cout << " correction= " << vol_correction << std::endl
                        << " Number of eqs= " << N_eq << std::endl
                        << " Blob after correction= "
                        << A3D_ELEM(*vol_blobs, k, i, j) << std::endl;
#endif

                    }
                }

                // Prepare for next iteration
                XX(act_coord) = XX(act_coord) + grid->relative_size * (grid->basis)( 0, 0);
                YY(act_coord) = YY(act_coord) + grid->relative_size * (grid->basis)( 1, 0);
                ZZ(act_coord) = ZZ(act_coord) + grid->relative_size * (grid->basis)( 2, 0);
            }
예제 #26
0
/* Splines -> Voxels for a SimpleGrid -------------------------------------- */
void spatial_Bspline032voxels_SimpleGrid(const MultidimArray<double> &vol_splines,
        const SimpleGrid &grid,
        MultidimArray<double> *vol_voxels,
        const MultidimArray<double> *vol_mask = NULL)
{
    Matrix1D<double> act_coord(3);           // Coord: Actual position inside
    // the voxel volume without deforming
    Matrix1D<double> beginZ(3);              // Coord: Voxel coordinates of the
    // blob at the 3D point
    // (z0,YY(lowest),XX(lowest))
    Matrix1D<double> beginY(3);              // Coord: Voxel coordinates of the
    // blob at the 3D point
    // (z0,y0,XX(lowest))
    Matrix1D<double> corner2(3), corner1(3); // Coord: Corners of the
    // blob in the voxel volume
    Matrix1D<double> gcurrent(3);            // Position in g of current point
    double        intx, inty, intz;          // Nearest integer voxel
    int           i, j, k;                   // Index within the blob volume
    bool          process;                   // True if this blob has to be
    // processed
    double spline_radius = 2 * sqrt(3.0);

    // Some aliases
#define x0 STARTINGX(*vol_voxels)
#define xF FINISHINGX(*vol_voxels)
#define y0 STARTINGY(*vol_voxels)
#define yF FINISHINGY(*vol_voxels)
#define z0 STARTINGZ(*vol_voxels)
#define zF FINISHINGZ(*vol_voxels)

#ifdef DEBUG
    bool condition = true;
    (*vol_voxels)().printShape();
    std::cout << std::endl;
    std::cout << "x0= " << x0 << " xF= " << xF << std::endl;
    std::cout << "y0= " << y0 << " yF= " << yF << std::endl;
    std::cout << "z0= " << z0 << " zF= " << zF << std::endl;
    std::cout << grid;
#endif

    // Convert the whole grid ...............................................
    // Corner of the plane defined by Z. These coordinates are in the
    // universal coord. system
    grid.grid2universe(grid.lowest, beginZ);

    Matrix1D<double> grid_index(3);
    for (k = (int) ZZ(grid.lowest); k <= (int) ZZ(grid.highest); k++)
    {
        // Corner of the row defined by Y
        beginY = beginZ;
        for (i = (int) YY(grid.lowest); i <= (int) YY(grid.highest); i++)
        {
            // First point in the row
            act_coord = beginY;
            for (j = (int) XX(grid.lowest); j <= (int) XX(grid.highest); j++)
            {
                VECTOR_R3(grid_index, j, i, k);
#ifdef DEBUG
                if (condition)
                {
                    printf("Dealing spline at (%d,%d,%d) = %f\n", j, i, k, A3D_ELEM(vol_splines, k, i, j));
                    std::cout << "Center of the blob      "
                    << act_coord.transpose() << std::endl;
                }
#endif

                // These two corners are also real valued
                process = true;
                if (XX(act_coord) >= xF) process = false;
                if (YY(act_coord) >= yF) process = false;
                if (ZZ(act_coord) >= zF) process = false;
                if (XX(act_coord) <= x0) process = false;
                if (YY(act_coord) <= y0) process = false;
                if (ZZ(act_coord) <= z0) process = false;
#ifdef DEBUG
                if (!process && condition) std::cout << "   It is outside output volume\n";
#endif
                if (!grid.is_interesting(act_coord))
                {
#ifdef DEBUG
                    if (process && condition) std::cout << "   It is not interesting\n";
#endif
                    process = false;
                }

                if (process)
                {
                    V3_PLUS_CT(corner1, act_coord, -spline_radius);
                    V3_PLUS_CT(corner2, act_coord, spline_radius);
#ifdef DEBUG
                    if (condition)
                    {
                        std::cout << "Corner 1 for this point " << corner1.transpose() << std::endl;
                        std::cout << "Corner 2 for this point " << corner2.transpose() << std::endl;
                    }
#endif

                    // Clip the corners to the volume borders
                    XX(corner1) = ROUND(CLIP(XX(corner1), x0, xF));
                    YY(corner1) = ROUND(CLIP(YY(corner1), y0, yF));
                    ZZ(corner1) = ROUND(CLIP(ZZ(corner1), z0, zF));
                    XX(corner2) = ROUND(CLIP(XX(corner2), x0, xF));
                    YY(corner2) = ROUND(CLIP(YY(corner2), y0, yF));
                    ZZ(corner2) = ROUND(CLIP(ZZ(corner2), z0, zF));
#ifdef DEBUG
                    if (condition)
                    {
                        std::cout << "Clipped and rounded Corner 1 " << corner1.transpose() << std::endl;
                        std::cout << "Clipped and rounded Corner 2 " << corner2.transpose() << std::endl;
                    }
#endif

                    // Effectively convert
                    for (intz = ZZ(corner1); intz <= ZZ(corner2); intz++)
                        for (inty = YY(corner1); inty <= YY(corner2); inty++)
                            for (intx = XX(corner1); intx <= XX(corner2); intx++)
                            {
                                int iz = (int)intz, iy = (int)inty, ix = (int)intx;
                                if (vol_mask != NULL)
                                    if (!A3D_ELEM(*vol_mask, iz, iy, ix)) continue;

                                // Compute the spline value at this point
                                VECTOR_R3(gcurrent, intx, inty, intz);
                                V3_MINUS_V3(gcurrent, act_coord, gcurrent);
                                double spline_value = spatial_Bspline03(gcurrent);
#ifdef DEBUG_MORE
                                if (condition)
                                {
                                    std::cout << "At (" << intx << ","
                                    << inty << "," << intz << ") value="
                                    << spline_value;
                                    std::cout.flush();
                                }
#endif

                                // Add at that position the corresponding spline value
                                A3D_ELEM(*vol_voxels, iz, iy, ix) +=
                                    A3D_ELEM(vol_splines, k, i, j) * spline_value;
#ifdef DEBUG_MORE
                                if (condition)
                                {
                                    std::cout << " adding " << A3D_ELEM(vol_splines, k, i, j)
                                    << " * " << value_spline << " = "
                                    << A3D_ELEM(vol_splines, k, i, j)*
                                    value_spline << std::endl;
                                    std::cout.flush();
                                }
#endif
                            }
                }

                // Prepare for next iteration
                XX(act_coord) = XX(act_coord) + grid.relative_size * grid.basis(0, 0);
                YY(act_coord) = YY(act_coord) + grid.relative_size * grid.basis(1, 0);
                ZZ(act_coord) = ZZ(act_coord) + grid.relative_size * grid.basis(2, 0);
            }
            XX(beginY) = XX(beginY) + grid.relative_size * grid.basis(0, 1);
            YY(beginY) = YY(beginY) + grid.relative_size * grid.basis(1, 1);
            ZZ(beginY) = ZZ(beginY) + grid.relative_size * grid.basis(2, 1);
        }
        XX(beginZ) = XX(beginZ) + grid.relative_size * grid.basis(0, 2);
        YY(beginZ) = YY(beginZ) + grid.relative_size * grid.basis(1, 2);
        ZZ(beginZ) = ZZ(beginZ) + grid.relative_size * grid.basis(2, 2);
    }
}
예제 #27
0
// GET INTERPOLATOR
//-------------------------------------------------------------------------
GridInterface::Interpolator RectilinearGrid::getInterpolator(Index elem, const Vector &point, DataBase::Mapping mapping, GridInterface::InterpolationMode mode) const {

   vassert(inside(elem, point));

#ifdef INTERPOL_DEBUG
   if (!inside(elem, point)) {
      return Interpolator();
   }
#endif

   if (mapping == DataBase::Element) {
       std::vector<Scalar> weights(1, 1.);
       std::vector<Index> indices(1, elem);

       return Interpolator(weights, indices);
   }

   std::array<Index,3> n = cellCoordinates(elem, m_numDivisions);
   std::array<Index,8> cl = cellVertices(elem, m_numDivisions);

   Vector corner0(m_coords[0][n[0]], m_coords[1][n[1]], m_coords[2][n[2]]);
   Vector corner1(m_coords[0][n[0]+1], m_coords[1][n[1]+1], m_coords[2][n[2]+1]);
   const Vector diff = point-corner0;
   const Vector size = corner1-corner0;

   const Index nvert = 8;
   std::vector<Index> indices((mode==Linear || mode==Mean) ? nvert : 1);
   std::vector<Scalar> weights((mode==Linear || mode==Mean) ? nvert : 1);

   if (mode == Mean) {
       const Scalar w = Scalar(1)/nvert;
       for (Index i=0; i<nvert; ++i) {
           indices[i] = cl[i];
           weights[i] = w;
       }
   } else if (mode == Linear) {
       vassert(nvert == 8);
       for (Index i=0; i<nvert; ++i) {
           indices[i] = cl[i];
       }
       Vector ss = diff;
       for (int c=0; c<3; ++c) {
           ss[c] /= size[c];
       }
       weights[0] = (1-ss[0])*(1-ss[1])*(1-ss[2]);
       weights[1] = ss[0]*(1-ss[1])*(1-ss[2]);
       weights[2] = ss[0]*ss[1]*(1-ss[2]);
       weights[3] = (1-ss[0])*ss[1]*(1-ss[2]);
       weights[4] = (1-ss[0])*(1-ss[1])*ss[2];
       weights[5] = ss[0]*(1-ss[1])*ss[2];
       weights[6] = ss[0]*ss[1]*ss[2];
       weights[7] = (1-ss[0])*ss[1]*ss[2];
   } else {
      weights[0] = 1;

      if (mode == First) {
         indices[0] = cl[0];
      } else if(mode == Nearest) {
          Vector ss = diff;
          int nearest=0;
          for (int c=0; c<3; ++c) {
              nearest <<= 1;
              ss[c] /= size[c];
              if (ss[c] < 0.5)
                  nearest |= 1;
          }
          indices[0] = cl[nearest];
      }
   }

   return Interpolator(weights, indices);

}
예제 #28
0
  bool PixelMap::isCollision(const PixelMap &pixelmap2, const IntPoint &pos1, const IntPoint &pos2, const geo::IntRect &rect1, const geo::IntRect &rect2, const Alignment &alignment1, const Alignment &alignment2) const
  {
    int fp1x, fp1y, fp2x, fp2y; /* First pixel to check */
    int cw, ch; /* Sizes of the rect to check on both maps */
    IntPoint corner1(pos1), corner2(pos2);
    IntRect mrect1, mrect2;
    IntRect framerect1, framerect2;
    IntRect *cutrect;


    /* Break */
      if(map == NULL)
        return false;


    /* Translate negative axises */
      mrect1 = rect_translate_negative_axises(rect1, size);
      mrect2 = rect_translate_negative_axises(rect2, pixelmap2.size);


    /* Align */
      if(alignment1.getX() != 0) corner1.decX((int)(mrect1.getWidth() * alignment1.getX()));
      if(alignment1.getY() != 0) corner1.decY((int)(mrect1.getHeight() * alignment1.getY()));
      if(alignment2.getX() != 0) corner2.decX((int)(mrect2.getWidth() * alignment2.getX()));
      if(alignment2.getY() != 0) corner2.decY((int)(mrect2.getHeight() * alignment2.getY()));


    /* Framerects */
      framerect1.load(corner1.getX(), corner1.getY(), mrect1.getWidth(), mrect1.getHeight());
      framerect2.load(corner2.getX(), corner2.getY(), mrect2.getWidth(), mrect2.getHeight());



    /* Break */
      if(!IntRect(0, 0, size.getWidth(), size.getHeight()).isCovering(mrect1))
        throw Exception() << "pixelmap1 doesn't fully cover rect";
      if(!IntRect(0, 0, pixelmap2.size.getWidth(), pixelmap2.size.getHeight()).isCovering(mrect2))
        throw Exception() << "pixelmap2 doesn't fully cover rect";


    /* Cutrect */
      if((cutrect = framerect1.getCutrect(framerect2)) == NULL)
        return false;


    /* Get first pixels and size to check */
      cw = cutrect->getWidth();
      ch = cutrect->getHeight();
      fp1x = cutrect->getX() - (framerect1.getX() - mrect1.getX());
      fp1y = cutrect->getY() - (framerect1.getY() - mrect1.getY());
      fp2x = cutrect->getX() - (framerect2.getX() - mrect2.getX());
      fp2y = cutrect->getY() - (framerect2.getY() - mrect2.getY());

      /* Delete cutrect */
        delete cutrect;


    /* Compare Pixels */
      for(int py = 0; py < ch; py++)
      {
        for(int px = 0; px < cw; px++)
        {
          if(is_pixel_on_map(map, px + fp1x, py + fp1y) && is_pixel_on_map(pixelmap2.map, px + fp2x, py + fp2y))
            return true;
        }
      }


    /* No collision detected */
      return false;
  }
예제 #29
0
  bool PixelMap::isCollision(const RectMap &rectmap, const IntPoint &pos1, const IntPoint &pos2, const IntRect &rect1, const IntRect &rect2, const Alignment &alignment1, const Alignment &alignment2) const
  {
    IntPoint corner1(pos1), corner2(pos2);
    IntRect framerect1, framerect2;
    IntRect mrect1, mrect2;
    IntRect *cutrect;


    /* Break */
      if(map == NULL)
        return false;


    /* Translate negative axises */
      mrect1 = rect_translate_negative_axises(rect1, size);
      mrect2 = rect_translate_negative_axises(rect2, rectmap.getSize());


    /* Align */
      if(alignment1.getX() != 0) corner1.decX((int)(mrect1.getWidth() * alignment1.getX()));
      if(alignment1.getY() != 0) corner1.decY((int)(mrect1.getHeight() * alignment1.getY()));
      if(alignment2.getX() != 0) corner2.decX((int)(mrect2.getWidth() * alignment2.getX()));
      if(alignment2.getY() != 0) corner2.decY((int)(mrect2.getHeight() * alignment2.getY()));


    /* Framerects */
      framerect1.load(corner1.getX(), corner1.getY(), mrect1.getWidth(), mrect1.getHeight());
      framerect2.load(corner2.getX(), corner2.getY(), mrect2.getWidth(), mrect2.getHeight());


    /* Break */
      if(!size_to_rect(size).isCovering(mrect1))
        throw Exception() << "pixelmap1 doesn't fully cover rect";


    /* Cutrect */
      if((cutrect = framerect1.getCutrect(framerect2)) == NULL)
        return false;


    /* Iterate rects, check pixels */
      for(int r = 0; r < rectmap.getRectCount(); r++)
      {
        int fpx, fpy; /* First pixel to check */
        int lpx, lpy; /* Last pixel to check */

        IntRect srect = rectmap.getRect(r) + point_to_vector(corner2) - IntVector(mrect2.getX(), mrect2.getY());
        IntRect *scutrect;


        /* Clip with cutrect*/
          if((scutrect = srect.getCutrect(*cutrect)) == NULL)
            continue;


        /* Pixels to check */
          fpx = scutrect->getX() - (corner1.getX() - mrect1.getX());
          fpy = scutrect->getY() - (corner1.getY() - mrect1.getY());
          lpx = fpx + scutrect->getWidth() - 1;
          lpy = fpy + scutrect->getHeight() - 1;


        /* Check pixels */
          for(int py = fpy; py <= lpy; py++)
          {
            for(int px = fpx; px <= lpx; px++)
            {
              if(is_pixel(px, py))
              {
                /* Free mem */
                  delete cutrect;
                  delete scutrect;

                /* Collision detected */
                  return true;
              }
            }
          }

        delete scutrect;
      }

    delete cutrect;


    return false;

  }
예제 #30
0
  bool PixelMap::isCollision(const RasterMap &rastermap, const IntPoint &pos1, const IntPoint &pos2, const IntRect &rect1, const IntRect &rect2, const Alignment &alignment1, const Alignment &alignment2) const
  {
    int fpx, fpy; /* First pixel to check */
    int lpx, lpy; /* Last pixel to check */
    int frx, fry; /* First pixel relative to rastermap */
    IntPoint corner1(pos1), corner2(pos2);
    IntRect framerect1, framerect2;
    IntRect mrect1, mrect2;
    IntRect *cutrect;


    /* Break */
      if(map == NULL)
        return false;


    /* Translate negative axises */
      mrect1 = rect_translate_negative_axises(rect1, size);
      mrect2 = rect_translate_negative_axises(rect2, rastermap.getMapSize() * rastermap.getCellSize());


    /* Align */
      if(alignment1.getX() != 0) corner1.decX((int)(mrect1.getWidth() * alignment1.getX()));
      if(alignment1.getY() != 0) corner1.decY((int)(mrect1.getHeight() * alignment1.getY()));
      if(alignment2.getX() != 0) corner2.decX((int)(mrect2.getWidth() * alignment2.getX()));
      if(alignment2.getY() != 0) corner2.decY((int)(mrect2.getHeight() * alignment2.getY()));


    /* Framerects */
      framerect1.load(corner1.getX(), corner1.getY(), mrect1.getWidth(), mrect1.getHeight());
      framerect2.load(corner2.getX(), corner2.getY(), mrect2.getWidth(), mrect2.getHeight());


    /* Break */
      if(!size_to_rect(size).isCovering(mrect1))
        throw Exception() << "pixelmap doesn't fully cover rect";
      if(!size_to_rect(rastermap.getMapSize() * rastermap.getCellSize()).isCovering(mrect2))
        throw Exception() << "rastermap doesn't fully cover rect";


   /* Cutrect */
      if((cutrect = framerect1.getCutrect(framerect2)) == NULL)
        return false;


    /* First / last pixel to check on pixelmap */
      fpx = cutrect->getX() - (corner1.getX() - mrect1.getX());
      fpy = cutrect->getY() - (corner1.getY() - mrect1.getY());

      lpx = fpx + cutrect->getWidth() - 1;
      lpy = fpy + cutrect->getHeight() - 1;


    /* Get first pixel relative to rastermap */
      frx = cutrect->getX() - (corner2.getX() - mrect2.getX());
      fry = cutrect->getY() - (corner2.getY() - mrect2.getY());


    /* Delete cutrect */
      delete cutrect;


    /* Iterate pixels */
      for(int py = fpy, ry = fry; py <= lpy; py++, ry++)
      {
        for(int px = fpx, rx = frx; px <= lpx; px++, rx++)
        {
          if(is_pixel(px, py))
          {
            int cx, cy;

            /* Get cell */
              cx = rx / rastermap.getCellSize().getWidth();
              cy = ry / rastermap.getCellSize().getHeight();

            /* Check */
              if(rastermap.isCell(IntPoint(cx, cy)))
              {
                return true;
              }
              else
              {
                int add = rastermap.getCellSize().getWidth() - (rx % rastermap.getCellSize().getWidth());
                  rx += add;
                  px += add;
              }
          }

        }
      }



    return false;
  }