ofVec3f SteeringBehaviors::Cohesion(const std::vector<Vehicle*>&_neighbors)
{
	ofVec3f _steeringForce(0.0, 0.0, 0.0);
	ofVec3f CenterOfMass(0.0, 0.0, 0.0);
	int NeighborCount = 0;

	for (int a = 0; a < _neighbors.size(); ++a)
	{
		//make sure this agent isn't included in the calculations and that
		//the agent being examined is close enough. ***also make sure it doesn't
		//include the evade target ***
		if ((_neighbors[a] != m_Vehicle) && (_neighbors[a]->IsTagged()) && (_neighbors[a] != m_Vehicle->Target()))
		{
			CenterOfMass += _neighbors[a]->Pos();
			++NeighborCount;
		}
	}

	if (NeighborCount > 0)
	{
		CenterOfMass /= NeighborCount;
		_steeringForce = Seek(CenterOfMass);
	}

	return(_steeringForce.getNormalized());
}
ofVec3f SteeringBehaviors::CohesionPlus(const std::vector<Vehicle*>&_neighbors)
{
	ofVec3f CenterOfMass(0.0,0.0,0.0);
	ofVec3f _steeringForce(0.0, 0.0, 0.0);

	int NeighborCount = 0;

	//iterate through the neighbors and sum up all the position vectors
	for (BaseEntity* pV = m_Vehicle->GameWorld()->CellSpace()->begin();
		!m_Vehicle->GameWorld()->CellSpace()->end();
		pV = m_Vehicle->GameWorld()->CellSpace()->next())
	{
		//make sure this agent isn't included in the caclulations and that the agent being examined is close enough
		if (pV != m_Vehicle)
		{
			CenterOfMass += pV->Pos();
			++NeighborCount;
		}
	}

	if (NeighborCount > 0)
	{
		CenterOfMass /= NeighborCount;
		_steeringForce = Seek(CenterOfMass);
	}

	return (_steeringForce.getNormalized());
}
void vtkKMeansClustering::EstimateClusterCenters(vtkPoints* data, vtkPoints* clusterCenters)
{
    vtkSmartPointer<vtkPoints> oldCenters =
        vtkSmartPointer<vtkPoints>::New();
    oldCenters->ShallowCopy(clusterCenters);

    clusterCenters->Reset();
    clusterCenters->Squeeze();

    for(unsigned int cluster = 0; cluster < this->K; cluster++)
    {
        vtkSmartPointer<vtkPoints> classPoints =
            vtkSmartPointer<vtkPoints>::New();
        for(unsigned int point = 0; point < data->GetNumberOfPoints(); point++)
        {
            if(this->Labels[point] == cluster)
            {
                classPoints->InsertNextPoint(data->GetPoint(point));
            }
        }
        double center[3];
        if(classPoints->GetNumberOfPoints() == 0)
        {
            //GetRandomPoint(data, center);
            oldCenters->GetPoint(cluster, center);
        }
        else
        {
            CenterOfMass(classPoints, center);
        }
        clusterCenters->InsertNextPoint(center);
    }

}
Exemple #4
0
void sdgEngine::Explode(float factor)
{
    double com[3];                      //residue center-of-mass
    CenterOfMass(_atoms, com);

    MIAtom_const_iter i, e = _atoms.end();

    for (i = _atoms.begin(); i != e; ++i)
    {
        (*i)->setPosition( (float)(com[0] + factor * ((*i)->x() - com[0])),
                           (float)(com[1] + factor * ((*i)->y() - com[1])),
                           (float)(com[2] + factor * ((*i)->z() - com[2])));
    }
}
Exemple #5
0
	vnl_double_3x3 SampleCovarianceMatrix(const std::vector<vgl_point_3d<double> > &Points)
	{
		vgl_point_3d<double> u = CenterOfMass(Points);
		vnl_double_3x3 S;
		S.fill(0);
		
		for(unsigned int i = 0; i < Points.size(); i++)
		{
			vgl_vector_3d<double> V = Points[i] - u;
			vnl_double_3x3 OP = VXLHelpers::OuterProduct(V, V);
			S += OP;
		}
		
		S /= Points.size();
		return S;
	}
Exemple #6
0
	vgl_plane_3d<double> BestPlane(const std::vector<vgl_point_3d<double> > &Points)
	{
		//this function finds the eigen vector corresponding to the smallest eigen value and places the plane's P0 at the center of mass of the points.
		
		vgl_point_3d<double> Centroid = CenterOfMass(Points);
		vnl_double_3x3 S = SampleCovarianceMatrix(Points);
		std::vector<vnl_double_3> evecs = VXLHelpers::EigenVectors(S);
		
		std::vector<vgl_vector_3d<double> > EvecsVGL;
		for(unsigned int i = 0; i < 3; i++)
			EvecsVGL.push_back(VXLHelpers::vnl_vector_to_vgl_vector(evecs[i]));
		
		//WriteEigenVectorVTP(Centroid, EvecsVGL, .3);
		
		vgl_plane_3d<double> P(EvecsVGL[0], Centroid); //apparently these are sorted from smallest to largest?
		
		return P;
	}
Exemple #7
0
Fichier : lbrcb.c Projet : rolk/ug
int NS_DIM_PREFIX BalanceGridRCB (MULTIGRID *theMG, int level)
{
  HEAP *theHeap = theMG->theHeap;
  GRID *theGrid = GRID_ON_LEVEL(theMG,level);       /* balance grid of level */
  LB_INFO *lbinfo;
  ELEMENT *e;
  int i, son;
  INT MarkKey;

  /* distributed grids cannot be redistributed by this function */
  if (me!=master && FIRSTELEMENT(theGrid) != NULL)
  {
    printf("Error: Redistributing distributed grids using recursive coordinate bisection is not implemented!\n");
    return (1);
  }

  if (me==master)
  {
    if (NT(theGrid) == 0)
    {
      UserWriteF("WARNING in BalanceGridRCB: no elements in grid\n");
      return (1);
    }

    Mark(theHeap,FROM_TOP,&MarkKey);
    lbinfo = (LB_INFO *)
             GetMemUsingKey(theHeap, NT(theGrid)*sizeof(LB_INFO), FROM_TOP, MarkKey);

    if (lbinfo==NULL)
    {
      Release(theHeap,FROM_TOP,MarkKey);
      UserWrite("ERROR in BalanceGridRCB: could not allocate memory from the MGHeap\n");
      return (1);
    }


    /* construct LB_INFO list */
    for (i=0, e=FIRSTELEMENT(theGrid); e!=NULL; i++, e=SUCCE(e))
    {
      lbinfo[i].elem = e;
      CenterOfMass(e, lbinfo[i].center);
    }


    /* apply coordinate bisection strategy */
    theRCB(lbinfo, NT(theGrid), 0, 0, DimX, DimY, 0);

    IFDEBUG(dddif,1)
    for (e=FIRSTELEMENT(theGrid); e!=NULL; e=SUCCE(e))
    {
      UserWriteF("elem %08x has dest=%d\n",
                 DDD_InfoGlobalId(PARHDRE(e)), PARTITION(e));
    }
    ENDDEBUG

    for (i=0, e=FIRSTELEMENT(theGrid); e!=NULL; i++, e=SUCCE(e))
    {
      InheritPartition (e);
    }

    Release(theHeap,FROM_TOP,MarkKey);
  }

  return 0;
}
//
// LATER: remove printfs...
//
// main tracking function. Processes a given sequence of type YARPImageSequence.
int 
YARPFlowTracker::Apply (YARPOutputPortOf<YARPGenericImage>& port)
{
	printf ("ox %d oy %d\n", ox, oy);

	// PROCESSING SEQUENCE.
	int start = seq->GetStartPushing();
	int stop = seq->GetStopPushing();
	printf ("Processing from frame %d to %d\n", start, stop); 

	printf ("Sequence has %d frames\n", seq->GetNumElements());
	assert (stop-start+1 <= m_maxsize);	

	// PREPARE SEQUENCE FOR PROCESSING.
	processor.Reset ();

	oseq.Reset ();

	contact = 0;
	contact_frame = 0;
	howmanycontacts = 0;

	lack_of_vectors = 0;

	int i, frame;
	for (frame = start; frame <= stop; frame++)
	{
		oseq.IncrementCounter ();
		contact = processor.Apply (seq->GetImageRef (frame), 
								   oseq.GetImageRef (frame-start));

		oseq.GetImageRef (frame-start) = seq->GetImageRef (frame);

		if (contact)
		{
			processor.GetPokeDirection (dirx, diry);
			processor.GetSegmentedImage (segmentation_mask);
			segmentation_mask_copy = segmentation_mask;
		
			processor.GetFlipper(flipper_segmentation_mask);
			flipper_segmentation_mask_copy = flipper_segmentation_mask;
						
			ba.Apply(segmentation_mask_copy);
			orientation = ba.GetAngle();
			orientation_quality = ba.GetPointiness();

			// enlarge it twice.
			GrowMask (segmentation_mask, extended_segmentation);
			segmentation_mask = extended_segmentation;
			GrowMask (segmentation_mask, extended_segmentation);

			CenterOfMass (extended_segmentation, com_x, com_y);

			contact_frame = frame;
			howmanycontacts++;

			GenerateAndSend (port);
		}
	}

	if (howmanycontacts == 0)
	{
		printf ("No poking detected... \n");

		// nothing much to do.
		return -1;
	}

	// OPTICFLOW.	
	int startopticflow = contact_frame - 5; //10;
	if (startopticflow < start) startopticflow = start;

	int endopticflow = contact_frame + FRAMES_TRACKED;
	if (endopticflow > stop) endopticflow = stop;

	// TRACK.
	int endtracking = contact_frame+FRAMES_TRACKED;
	if (endtracking > stop) endtracking = stop;

	// optic flow mask, initialize optic flow and additional tracker.
	mask.Zero();

	YARPColorConverter::RGB2Grayscale (seq->GetImageRef(startopticflow), mono);
	of.Initialize (mono);

	bool trackvalid = false;
	int sx = com_x, sy = com_y;
	int sx2 = com_x, sy2 = com_y;
	tracker.Initialize (seq->GetImageRef(startopticflow), com_x, com_y);
	
	YarpPixelBGR green;
	green.r = green.b = 0;
	green.g = 0;

	i = 0;
	for (frame = startopticflow+1; frame <= endopticflow; frame++)
	{
		AddCircleOutline (oseq.GetImageRef(frame-start+1), green, sx, sy, 10);

		if (tracker.IsTracking())
		{
			tracker.Apply (seq->GetImageRef(frame), true, sx2, sy2, trackvalid);
			printf ("frame: %d, valid: %d, sx, sy: %d %d\n", frame, trackvalid, sx2, sy2);
		}
 
		YARPColorConverter::RGB2Grayscale (seq->GetImageRef(frame), mono);

		if (frame < contact_frame)
			of.Apply (mono, mask, sx2-sx, sy2-sy, outimage, vx[frame-start], vy[frame-start]);
		else
			of.Apply (mono, extended_segmentation, sx2-sx, sy2-sy, outimage, vx[frame-start], vy[frame-start]);

		sx = sx2;
		sy = sy2;
 
		of.DrawFlow (oseq.GetImageRef (frame-start));

		if (frame == contact_frame)
			WriteMask (extended_segmentation, oseq.GetImageRef (frame-start));

		if (frame >= contact_frame+1 && frame <= endtracking)
		{
			if (ComputeRotation (extended_segmentation, 
								 vx[frame-start], 
								 vy[frame-start], 
								 ox, 
								 oy, 
								 trsf[i], 
								 10) == -2)
				lack_of_vectors++;
			i++;

			WriteMask (extended_segmentation, oseq.GetImageRef (frame-start));
		}
	}

	CenterOfMass (extended_segmentation, final_x, final_y);
	printf ("starting point: %d %d\n", com_x, com_y);
	printf ("center of mass: %d %d\n", final_x, final_y);

	dispframe = contact_frame - start - 10;	// it was -5.
	m_stepping = 2;

	if (lack_of_vectors > 6)
	{
		printf ("optic flow is poor, skipping frames\n");

		oseq.Reset ();

		// adjust start frame parity.
		int newstart = start;
		if (((contact_frame % 2) == 0 && (newstart % 2) == 1) ||
			((contact_frame % 2) == 1 && (newstart % 2) == 0)
			)
			newstart ++;

		lack_of_vectors = 0;

		printf ("re-processing from frame %d to %d\n", start, stop); 
		
		// RECOMPUTING INDEX ETC.
		// 
		segmentation_mask = segmentation_mask_copy; 
		flipper_segmentation_mask = flipper_segmentation_mask_copy; 

		// enlarge it twice.
		GrowMask (segmentation_mask, extended_segmentation);
		segmentation_mask = extended_segmentation;
		GrowMask (segmentation_mask, extended_segmentation);

		// contact frame is ok.
		// poke dir is ok.
		// center of mass is ok.
				
		// RECOMPUTE OPTIC FLOW.
		int startopticflow = contact_frame - 10; //20;
		if (startopticflow < newstart) startopticflow = newstart;
		if (((contact_frame % 2) == 0 && (startopticflow % 2) == 1) ||
			((contact_frame % 2) == 1 && (startopticflow % 2) == 0)
			)
			startopticflow ++;

		int endopticflow = contact_frame + FRAMES_TRACKED*2;
		if (endopticflow > stop) endopticflow = stop;


		// TRACK.
		int endtracking = contact_frame+FRAMES_TRACKED*2;
		if (endtracking > stop) endtracking = stop;


		YARPColorConverter::RGB2Grayscale (seq->GetImageRef(startopticflow), mono);
		of.Initialize (mono);

		bool trackvalid = false;
		int sx = com_x, sy = com_y;
		int sx2 = com_x, sy2 = com_y;
		tracker.Initialize (seq->GetImageRef(startopticflow), com_x, com_y);
		
		YarpPixelBGR green;
		green.r = green.b = 0;
		green.g = 0;

		for (frame = start; frame <= stop; frame++)
		{
			oseq.IncrementCounter ();
			oseq.GetImageRef (frame-start) = seq->GetImageRef (frame);		
		}

		i = 0;
		for (frame = startopticflow+2; frame <= endopticflow; frame+=2)
		{
			AddCircleOutline (oseq.GetImageRef(frame-start+2), green, sx, sy, 10);

			if (tracker.IsTracking())
			{
				tracker.Apply (seq->GetImageRef(frame), true, sx2, sy2, trackvalid);
				printf ("frame: %d, valid: %d, sx, sy: %d %d\n", frame, trackvalid, sx2, sy2);
			}

			YARPColorConverter::RGB2Grayscale (seq->GetImageRef(frame), mono);
			if (frame < contact_frame)
				of.Apply (mono, mask, sx2-sx, sy2-sy, outimage, vx[frame-start], vy[frame-start]);
			else
				of.Apply (mono, extended_segmentation, sx2-sx, sy2-sy, outimage, vx[frame-start], vy[frame-start]);

			sx = sx2;
			sy = sy2;

			of.DrawFlow (oseq.GetImageRef (frame-start));

			if (frame == contact_frame)
				WriteMask (extended_segmentation, oseq.GetImageRef (frame-start));

			if (frame >= contact_frame+2 && frame <= endtracking)
			{
				if (ComputeRotation (extended_segmentation, 
									 vx[frame-start], 
									 vy[frame-start], 
									 ox, 
									 oy, 
									 trsf[i], 
									 10) == -2)
					lack_of_vectors++;
				i++;

				WriteMask (extended_segmentation, oseq.GetImageRef (frame-start));
			}
		}

		CenterOfMass (extended_segmentation, final_x, final_y);
		printf ("starting point: %d %d\n", com_x, com_y);
		printf ("center of mass: %d %d\n", final_x, final_y);

		printf ("improved? %d\n", lack_of_vectors);

		//
		//
		//
		m_stepping = 4;
		dispframe = contact_frame - start - 10;
		if (dispframe < 0) dispframe = 0;

		if (lack_of_vectors > 6)
		{
			// bad sequence.
			printf ("Still bad flow after post-processing\n");
			return -2;
		}
	}

	return 0;
}
Exemple #9
0
//酸素の位置を読みこむ。
sLattIce* load_LattIce( FILE* file, real hposition )
{
    char buf[1000];
    sLattIce* ice;
    bool coord=False, network=False;
    real rhb=0;

    ice = calloc( 1, sizeof( sLattIce ) );
    ice->periodic = False;
    //ice->dryrun   = False;
    /*プロトンの場所は不明*/
    ice->currentBond = -1;
    ice->currentPotential = 0;
    while( NULL != fgets( buf, sizeof( buf ), file ) ){
        if ( strncmp( buf, "@BOX3",5 ) == 0 ){
            fgets( buf, sizeof( buf ), file );
            ice->periodic = True;
#ifdef SINGLEPRECISION
            sscanf( buf, "%f %f %f", &ice->bx, &ice->by, &ice->bz );
#else
            sscanf( buf, "%lf %lf %lf", &ice->bx, &ice->by, &ice->bz );
#endif
        }
        else if ( strncmp( buf, "@BXLA",5 ) == 0 ){
            fgets( buf, sizeof( buf ), file );
            ice->periodic = True;
#ifdef SINGLEPRECISION
            sscanf( buf, "%f", &ice->bx );
#else
            sscanf( buf, "%lf", &ice->bx );
#endif
            ice->by = ice->bz = ice->bx;
        }
        else if ( strncmp( buf, "@NGPH", 5 ) == 0 ){
            int o1,o2;
            int no;
            int nhb=0;

            network = True;
            fgets( buf, sizeof( buf ), file );
            no = atoi( buf );
            if ( ice->nOxygen == 0 ){
                ice->nOxygen = no;
                ice->comx = ice->comy = ice->comz = 0;
                ice->oxygens = calloc( ice->nOxygen,     sizeof( sOxygen ) );
                ice->bonds   = calloc( ice->nOxygen * 2, sizeof( sHydrogenBond ) );
            }
            else if ( ice->nOxygen != no ){
                fprintf( stderr, "Error: number of sites differ: %d != %d\n",
                         ice->nOxygen, no );
                exit(1);
            }
            /*ネットワークを読みこむ。一応有向グラフと考える。*/
            while ( NULL != fgets( buf, sizeof( buf ), file ) ){
                sOxygen*       oxy1;
                sOxygen*       oxy2;
                sHydrogenBond* hb;
                sscanf( buf, "%d %d", &o1, &o2 );
                if ( o1 < 0 ) break;
                oxy1 = &ice->oxygens[ o1 ];
                oxy2 = &ice->oxygens[ o2 ];
                hb   = &ice->bonds[ nhb ];
                oxy1->hydrogenBond[ oxy1->nAdj ] = nhb;
                oxy1->oxygen[ oxy1->nAdj ]       = o2;
                oxy2->hydrogenBond[ oxy2->nAdj ] = nhb;
                oxy2->oxygen[ oxy2->nAdj ]       = o1;
                if ( o1 < o2 ){
                    hb->oxygen[0] = o1;
                    hb->oxygen[1] = o2;
                    hb->direction = +1;
                }
                else {
                    hb->oxygen[0] = o2;
                    hb->oxygen[1] = o1;
                    hb->direction = -1;
                }
                oxy1->outgo ++;
                oxy1->nAdj ++;
                oxy2->nAdj ++;
                nhb ++;
            }
            ice->nBond = nhb;
        }            
        else if ( strncmp( buf, "@PPOS", 5 ) == 0 ){
            int o1,o2;
            int no;
            int nhb;
            sOxygen*       oxy1;
            sOxygen*       oxy2;
            sHydrogenBond* hb;

            /*@PPOSより前に@NGPHを読みこんでいる必要がある。*/
            if ( ! network ){
                fprintf( stderr, "Network topology must be read before proton position.\n" );
                exit(1);
            }
            fgets( buf, sizeof( buf ), file );
            no = atoi( buf );
            /*ネットワークを読みこむ。一応有向グラフと考える。*/
            nhb = ice->nBond;
            /*最初のプロトンしか読まない。*/
            fgets( buf, sizeof( buf ), file );
            sscanf( buf, "%d %d", &o1, &o2 );
            oxy1 = &ice->oxygens[ o1 ];
            oxy2 = &ice->oxygens[ o2 ];
            hb   = &ice->bonds[ nhb ];
            oxy1->hydrogenBond[ oxy1->nAdj ] = nhb;
            oxy1->oxygen[ oxy1->nAdj ]       = o2;
            oxy2->hydrogenBond[ oxy2->nAdj ] = nhb;
            oxy2->oxygen[ oxy2->nAdj ]       = o1;
            hb->oxygen[0] = o1;
            hb->oxygen[1] = o2;
            hb->direction = 0;
            oxy1->nAdj ++;
            oxy2->nAdj ++;
            ice->currentBond = nhb;
            nhb ++;
            ice->nBond = nhb;
        }            
        else if ( strncmp( buf, "@RCOO", 5 ) == 0 ){
            /*結合しているとみなすO-O間距離の閾値*/
            fgets( buf, sizeof( buf ), file );
            rhb = atof( buf );
        }
        else if ( strncmp( buf, "@NX4A", 5 ) == 0 ||
                  strncmp( buf, "@AR3A", 5 ) == 0 ||
                  strncmp( buf, "@NX3A", 5 ) == 0 ){
            int o1;
            int no;

            coord = True;
            fgets( buf, sizeof( buf ), file );
            no = atoi( buf );
            if ( ice->nOxygen == 0 ){
                ice->nOxygen = no;
                ice->comx = ice->comy = ice->comz = 0;
                ice->oxygens = calloc( ice->nOxygen,     sizeof( sOxygen ) );
                ice->bonds   = calloc( ice->nOxygen * 2, sizeof( sHydrogenBond ) );
            }
            else if ( ice->nOxygen != no ){
                fprintf( stderr, "Error: number of sites differ: %d != %d\n",
                         ice->nOxygen, no );
                exit(1);
            }
            /*座標を読みこむ。*/
            for( o1=0; o1< ice->nOxygen; o1++ ){
                fgets( buf, sizeof( buf ), file );
#ifdef SINGLEPRECISION
                sscanf( buf, "%f %f %f",
                        &ice->oxygens[o1].x, 
                        &ice->oxygens[o1].y, 
                        &ice->oxygens[o1].z );
#elif real == double
                sscanf( buf, "%lf %lf %lf",
                        &ice->oxygens[o1].x, 
                        &ice->oxygens[o1].y, 
                        &ice->oxygens[o1].z );
#else
#error
#endif
                /*ファイルから読む場合はとりあえずダミーサイトではないと考える。→平成16年2月18日(水)変更。結合数によってダミーかどうかを決める。*/
                ice->oxygens[o1].charge = -2;
            }
#ifdef DEBUG
            fprintf( stderr, "CoM: %f %f %f\n", ice->comx, ice->comy, ice->comz );
#endif
        }
        //if ( coord && network ) break;
    }

    if ( ! network && 0.0 < rhb ) {
        DetermineBonds( ice, rhb );
    }

    CenterOfMass( ice );
    /*O-O間のプロトンのとりうる位置3つの座標を計算する。*/
    SetHBins( ice, hposition );
    return ice;
    //fprintf( stderr, "Error: No inputs.\n" );
    //exit(1);
}
Exemple #10
0
/*create N x N x N cubic ice */
sLattIce* CubicIce( int n, real hposition )
{
    int x,y,z;
    int nhb;
    int o1;
    
    sLattIce* ice;
    
    ice = malloc( sizeof(sLattIce) );

    ice->oxygens = calloc( n*n*n,   sizeof( sOxygen ) );
    ice->bonds   = calloc( n*n*n*2, sizeof( sHydrogenBond ) );
    ice->nOxygen = n*n*n;
    ice->periodic = False;
    //ice->dryrun  = False;
    
    for ( x=0; x<2*n; x+=2 ){
        for ( y=0; y<2*n; y+=2 ){
            for ( z=0; z<2*n; z+=2 ){
                if ( ( ( x+y+z ) % 4 ) == 0 ){
                    int xi,yi,zi;
                    //位置から酸素IDを得る
                    int self = Coordinate2OxygenID( n, x, y, z );
                    
                    if ( ice->oxygens[self].x != 0 || ice->oxygens[self].y != 0
                         || ice->oxygens[self].z != 0 ){
                        printf("%d %d %d %d is used\n", self,x,y,z);
                    }
                    //位置を保存する
                    ice->oxygens[self].x = x;
                    ice->oxygens[self].y = y;
                    ice->oxygens[self].z = z;

                    //立方体表面にあるなら
                    if ( x == 0 || x == 2*n-2 ||
                         y == 0 || y == 2*n-2 ||
                         z == 0 || z == 2*n-2 )
                      //ダミーサイトである。
		      ice->oxygens[self].charge = 0;
                    else{
                      //水素の電荷の-2倍。
		      ice->oxygens[self].charge = -2;
                      ice->oxygens[self].oxygen[0] =
                        Coordinate2OxygenID( n, x+1, y+1, z+1 );
                      ice->oxygens[self].oxygen[1] =
                        Coordinate2OxygenID( n, x+1, y-1, z-1 );
                      ice->oxygens[self].oxygen[2] =
                        Coordinate2OxygenID( n, x-1, y+1, z-1 );
                      ice->oxygens[self].oxygen[3] =
                        Coordinate2OxygenID( n, x-1, y-1, z+1 );
                      ice->oxygens[self].nAdj = 4;
                    }
                    
                    xi = x + 1;
                    yi = y + 1;
                    zi = z + 1;
                    
                    self = Coordinate2OxygenID( n, xi, yi, zi );
                    ice->oxygens[self].x = xi;
                    ice->oxygens[self].y = yi;
                    ice->oxygens[self].z = zi;

                    if ( xi == 2*n-1 ||
                         yi == 2*n-1 ||
                         zi == 2*n-1 )
                        ice->oxygens[self].charge = 0;
                    else{
                        ice->oxygens[self].charge = -2;
                        ice->oxygens[self].oxygen[0] =
                            Coordinate2OxygenID( n, xi-1, yi-1, zi-1 );
                        ice->oxygens[self].oxygen[1] =
                            Coordinate2OxygenID( n, xi-1, yi+1, zi+1 );
                        ice->oxygens[self].oxygen[2] =
                            Coordinate2OxygenID( n, xi+1, yi-1, zi+1 );
                        ice->oxygens[self].oxygen[3] =
                            Coordinate2OxygenID( n, xi+1, yi+1, zi-1 );
                        ice->oxygens[self].nAdj = 4;
                    }
                }
            }
        }
    }
    
    CenterOfMass( ice );
    /*つぎに水素結合を定義する。*/
    nhb = 0;
    /*すべての酸素原子について*/
    for ( o1=0; o1<n*n*n; o1++ ){
        /*もしダミーサイト(表面サイト)でなければ*/
        if ( ice->oxygens[o1].charge != 0 ){
            int j;
            /*4つの隣接酸素について*/
            for( j=0; j<ice->oxygens[o1].nAdj; j++ ){
                int o2;
                
                o2 = ice->oxygens[o1].oxygen[j];
                /*o1<o2なら、ボンドを登録する(重複登録をさけるため)*/
                if ( o1 < o2 ) {
                    /*bondの2つの端点を登録する*/
                    ice->bonds[nhb].oxygen[0] = o1;
                    ice->bonds[nhb].oxygen[1] = o2;
                    /*この結合をo2への結合として登録する。*/
                    ice->oxygens[o1].hydrogenBond[j] = nhb;
                    /*隣接酸素がダミーサイトでないなら*/
                    if ( ice->oxygens[o2].charge != 0 ){
                        int k;
                    
                        /*隣接酸素の隣接酸素について*/
                        for ( k=0; k<ice->oxygens[o2].nAdj; k++ )
                            /*それがo1なら*/
                            if ( ice->oxygens[o2].oxygen[k] == o1 )
                                /*この結合をo2からo1への結合として登録する*/
                                ice->oxygens[o2].hydrogenBond[k] = nhb;
                    }
                    
                    /*登録結合数を増やす*/
                    nhb ++;
                }
                /*隣接酸素がダミーサイトなら*/
                else if ( ice->oxygens[o2].charge == 0 ) {
                    /*o2 < o1でもボンドを登録する。*/
                    ice->bonds[nhb].oxygen[1] = o1;
                    ice->bonds[nhb].oxygen[0] = o2;
                    ice->oxygens[o1].hydrogenBond[j] = nhb;
                    nhb ++;
                }
            }
        }
    }

    //結合総数には、ダミーボンドへの結合が含まれるので、酸素(電荷あり)の総数の2倍よりも大きいはず。
    ice->nBond = nhb;
    SetHBins( ice, hposition );
    
    return ice;
    
}