bool LayoutCreator::write_file()
{
    // Copy the file to the new location
    QFile file(m_parent->filename());
    if(!file.copy(m_file_name)) {
        //TODO: Error handling
        LOGD << "\tError copying file to new location!";
        return false;
    }

    if( !file.setPermissions((QFile::Permission)0x666) ) {
        LOGD << "WARNING: Unable to set permissions for new layout.";
    }

    // Read the file

    // Update values
    MemoryLayout newLayout(m_file_name, m_parent->data());
    QString checksum = hexify(m_df->calculate_checksum());
    newLayout.set_game_version(m_version_name);
    newLayout.set_checksum(checksum);
    newLayout.set_address("addresses/translation_vector", m_translation_vector);
    newLayout.set_address("addresses/language_vector", m_language_vector);
    newLayout.set_address("addresses/creature_vector", m_creature_vector);
    newLayout.set_address("addresses/dwarf_race_index", m_dwarf_race_index);
    newLayout.set_address("addresses/squad_vector", m_squad_vector);
    newLayout.set_address("addresses/current_year", m_current_year);
    newLayout.set_complete();
    LOGD << "\tWriting file.";
    newLayout.save_data();
    return true;
}
Пример #2
0
void KbBindWidget::setBind(KbBind* newBind, KbProfile* newProfile){
    ui->keyWidget->clearSelection();
    ui->rbWidget->setBind(newBind, newProfile);
    newSelection(QStringList());
    if(bind == newBind)
        return;
    if(bind){
        disconnect(bind, SIGNAL(layoutChanged()), this, SLOT(newLayout()));
        disconnect(bind, SIGNAL(updated()), this, SLOT(updateBind()));
    }
    connect(newBind, SIGNAL(layoutChanged()), this, SLOT(newLayout()));
    connect(newBind, SIGNAL(updated()), this, SLOT(updateBind()));
    bind = newBind;
    profile = newProfile;
    newLayout();
    ui->rbWidget->setBind(bind, profile);
    updateBind();
}
Пример #3
0
QgsMasterLayoutInterface *QgsLayoutManager::duplicateLayout( const QgsMasterLayoutInterface *layout, const QString &newName )
{
  if ( !layout )
    return nullptr;

  std::unique_ptr< QgsMasterLayoutInterface > newLayout( layout->clone() );
  if ( !newLayout )
  {
    return nullptr;
  }

  newLayout->setName( newName );
  QgsMasterLayoutInterface *l = newLayout.get();
  if ( !addLayout( newLayout.release() ) )
  {
    return nullptr;
  }
  else
  {
    return l;
  }
}
void Hypergraph::updateLayout(const vector<int> &changedSet, int boundary [], int dim, float c)
{
	_layoutDim = dim;
	int nIteration = 500;
	float temperature = 10;

	srand(time(NULL));

	int area = 1;
	for (int i=0; i<dim; ++i)
	{
		area *= boundary[2*i+1]-boundary[2*i];
	}
	float k = c*sqrt(area*1.0f/_nVertices);

	int nEdges = _edges.size();
	int nTotal = _nVertices+nEdges;
	vector<fvec> dispBuf (nTotal);
	for (int i=0; i<nTotal; ++i)
	{
		dispBuf[i] = fvec(dim);
	}
	int i,j;

	vector<bool> bMovable (nTotal);
	for (i=0; i<changedSet.size(); ++i)
	{
		bMovable[changedSet[i]] = true;
	}

	QProgressDialog prog ("Performing graph layout ...", "", 0, nIteration-1);
	prog.setCancelButton(NULL);
	for (int it=0; it<nIteration; ++it)
	{
		DWORD t1 = GetTickCount();
		bool bChanged = false;
		for (i=0; i<nTotal; ++i)
		{
			dispBuf[i].fill(0);
		}

		DWORD t2 = GetTickCount();
		/*calculate repulsive force*/
		for (i=0; i<changedSet.size(); ++i)
		{
			int idx = changedSet[i];
			for (j=0; j<nTotal; ++j)
			{
				if (j==idx)
				{
					continue;
				}
				fvec d = _layout[j]-_layout[idx];
				fvec disp;
				float normD = norm(d,2);
				if (normD<1.0e-5)
				{
					disp = fvec(dim);
					for (int iDim=0; iDim<dim; ++iDim)
					{
						disp(iDim) = rand()%100/100.0f;
					}
					disp *= temperature;
				} else
				{
					disp = d*k*k/pow(normD,2);
				}
				dispBuf[idx] -= disp;
			}
		}

		DWORD tRepForce = GetTickCount()-t2;

		/*calculate attractive force*/
		for (i=0; i<_edges.size(); ++i)
		{
			int edgeIdx = i+_nVertices;
			for (j=0; j<_edges[i].size(); ++j)
			{
				if (!bMovable[_edges[i][j]])
				{
					continue;
				}
				float c2 = 3.0;
				fvec d1 = _layout[edgeIdx] - _layout[_edges[i][j]];
				fvec disp1 = c2*d1*norm(d1,2)/k;
				dispBuf[edgeIdx] -= disp1;
				dispBuf[_edges[i][j]] += disp1;

				for (int m=0; m<_edges[i].size(); ++m)
				{
					if (m==j)
					{
						continue;
					}
					fvec d = _layout[_edges[i][m]] - _layout[_edges[i][j]];
					fvec disp = d*norm(d,2)/k;
					dispBuf[_edges[i][j]] += disp;
				}
			}
		}
		DWORD tRepAttrForces = GetTickCount()-t2;

		/*restrict the points from being pushed towards the boundary*/
		for (i=0; i<nTotal; ++i)
		{
			if (!bMovable[i])
			{
				continue;
			}
			for (j=0; j<dim; ++j)
			{
				float c1=1.0e6;
				float x = _layout[i](j);
				if (x==boundary[j*2] || x==boundary[j*2+1])
				{
					int stop = 1;
				}
				float d = c1*(1/(x-boundary[j*2]+1.0e-3)-1/(boundary[j*2+1]-x+1.0e-3));
				dispBuf[i](j) += d;
			}
		}

		/*limit the maximum displacement, boundary check*/
		for (i=0; i<nTotal; ++i)
		{
			if (!bMovable[i])
			{
				continue;
			}
			float n = norm(dispBuf[i],2);
			fvec newLayout = _layout[i]+dispBuf[i]*min(n, temperature)/n;
			for (j=0; j<dim; ++j)
			{
				int minBoundary = boundary[2*j];
				int maxBoundary = boundary[2*j+1];
				newLayout(j) = newLayout(j) < minBoundary?minBoundary:(newLayout(j)>maxBoundary?maxBoundary:newLayout(j));
			}
			if (norm(newLayout-_layout[i], 2)>1.0e-3)
			{
				_layout[i] = newLayout;
				bChanged = true;
			}
		}

		if (!bChanged)
		{
			break;
		}

		DWORD perItTime = GetTickCount() - t1;
		t1 = GetTickCount();

		prog.setValue(it);
	}
}
void Hypergraph::layoutGraph( int boundary [], int dim/*=2*/, float c/*=1.0*/ )
{
	_layoutDim = dim;
	int nIteration = 500;
	float temperature = 10;

	srand(time(NULL));

	int area = 1;
	for (int i=0; i<dim; ++i)
	{
		area *= boundary[2*i+1]-boundary[2*i];
	}
	float k = c*sqrt(area*1.0f/_nVertices);

	/*initialize vertex layout*/
	int nEdges = _edges.size();
	int nTotal = _nVertices+nEdges;
	_layout.resize(nTotal);
	vector<fvec> dispBuf (nTotal);
	for (int i=0; i<nTotal; ++i)
	{
		_layout[i] = fvec(dim);
		for (int j=0; j<dim; ++j)
		{
			_layout[i](j) = boundary[2*j]+rand()%(boundary[2*j+1]-boundary[2*j]);
		}

		dispBuf[i] = fvec(dim);
	}

	int i,j;

	QProgressDialog prog ("Performing graph layout ...", "", 0, nIteration-1);
	prog.setCancelButton(NULL);
	for (int it=0; it<nIteration; ++it)
	{
		DWORD t1 = GetTickCount();
		bool bChanged = false;
		for (i=0; i<nTotal; ++i)
		{
			dispBuf[i].fill(0);
		}

		DWORD t2 = GetTickCount();
		/*calculate repulsive force*/
		for (i=0; i<nTotal; ++i)
		{
			for (j=0; j<i; ++j)
			{
				if (j==i)
				{
					continue;
				}
				fvec disp = getRepulsiveForce(_layout[i], _layout[j], k);
				dispBuf[j] += disp;
				dispBuf[i] -= disp;
			}
		}

		DWORD tRepForce = GetTickCount()-t2;

		/*calculate attractive force*/
		for (i=0; i<_edges.size(); ++i)
		{
			int edgeIdx = i+_nVertices;
			for (j=0; j<_edges[i].size(); ++j)
			{
				float c2 = 300.0;
				fvec disp1 = c2*getAttractiveForce(_layout[_edges[i][j]], _layout[edgeIdx], k);
				dispBuf[edgeIdx] -= disp1;
				dispBuf[_edges[i][j]] += disp1;
			}
		}
		DWORD tRepAttrForces = GetTickCount()-t2;

		/*restrict the points from being pushed towards the boundary*/
		for (i=0; i<nTotal; ++i)
		{
			for (j=0; j<dim; ++j)
			{
				float c1=1.0e6;
				float x = _layout[i](j);
				if (x==boundary[j*2] || x==boundary[j*2+1])
				{
					int stop = 1;
				}
				float d = c1*(1/(x-boundary[j*2]+1.0e-3)-1/(boundary[j*2+1]-x+1.0e-3));
				dispBuf[i](j) += d;
			}
		}

		/*limit the maximum displacement, boundary check*/
		for (i=0; i<nTotal; ++i)
		{
			float n = norm(dispBuf[i],2);
			fvec newLayout = _layout[i]+dispBuf[i]*min(n, temperature)/n;
			for (j=0; j<dim; ++j)
			{
				int minBoundary = boundary[2*j];
				int maxBoundary = boundary[2*j+1];
				newLayout(j) = newLayout(j) < minBoundary?minBoundary:(newLayout(j)>maxBoundary?maxBoundary:newLayout(j));
			}
			if (norm(newLayout-_layout[i], 2)>1.0e-3)
			{
				_layout[i] = newLayout;
				bChanged = true;
			}
		}

		if (!bChanged)
		{
			break;
		}

		DWORD perItTime = GetTickCount() - t1;
		t1 = GetTickCount();

		prog.setValue(it);
	}
}
void Hypergraph::layoutFast(int boundary [], int dim, float c, int Vmax, int Smax, int nIteration)
{
	_layoutDim = dim;
	float temperature = 10;

	srand(time(NULL));

	int area = 1;
	for (int i=0; i<dim; ++i)
	{
		area *= boundary[2*i+1]-boundary[2*i];
	}
	float k = c*sqrt(area*1.0f/_nVertices);

	/*initialize vertex layout*/
	int nEdges = _edges.size();
	int nTotal = _nVertices+nEdges;
	_layout.resize(nTotal);
	vector<fvec> dispBuf (nTotal);
	for (int i=0; i<nTotal; ++i)
	{
		_layout[i] = fvec(dim);
		for (int j=0; j<dim; ++j)
		{
			_layout[i](j) = boundary[2*j]+rand()%(boundary[2*j+1]-boundary[2*j]);
		}

		dispBuf[i] = fvec(dim);
	}

	int i,j;

	vector<list<int> > sampleBufs (nTotal);
	vector<int> Vsizes (nTotal);

	vector<float> maxDists (nTotal);
	maxDists.assign(nTotal, 40);

	/*initialize distance matrix*/
	vector<float> distMat (nTotal*(nTotal-1)/2);
	distMat.assign(nTotal*(nTotal-1)/2, 50);
	for (int i=0; i<nEdges; ++i)
	{
		int edgeIdx = i+_nVertices;
		for (int j=0; j<_edges[i].size(); ++j)
		{
			int n1 = _edges[i][j];
			for (int k=0; k<j; ++k)
			{
				int n2 = _edges[i][k];
				distMat[n1*(n1-1)/2+n2] = 20;
			}

			distMat[edgeIdx*(edgeIdx-1)/2+n1] = 10;
		}
	}

	QProgressDialog prog ("Performing graph layout ...", "", 0, nIteration-1);
	prog.setCancelButton(NULL);

	for (int it=0; it<nIteration; ++it)
	{
		DWORD t1 = GetTickCount();
		bool bChanged = false;
		for (i=0; i<nTotal; ++i)
		{
			dispBuf[i].fill(0);
		}

		DWORD t2 = GetTickCount();
		DWORD tFindSample = 0;
		for (i=0; i<nTotal; ++i)
		{
			DWORD t3 = GetTickCount();
			findSampleSets(i, maxDists[i], distMat, sampleBufs[i], Vsizes[i], Vmax, Smax);
			list<int> &sampleBuf = sampleBufs[i];
			tFindSample += GetTickCount()-t3;

			//for (j=0; j<sampleBuf.size(); ++j)
			for (list<int>::iterator sampleIt = sampleBuf.begin(); sampleIt!=sampleBuf.end(); ++sampleIt)
			{
				int sampleIdx = *sampleIt;
				++sampleIt;
				float dist = *sampleIt;
				if (sampleIdx==i)
				{
					continue;
				}
				fvec d = _layout[sampleIdx]-_layout[i];
				float normD = norm(d,2);

				/*calculate repulsive force*/
				fvec dispRepulsive;
				if (normD<1.0e-5)
				{
					dispRepulsive = fvec(dim);
					for (int iDim=0; iDim<dim; ++iDim)
					{
						dispRepulsive(iDim) = rand()%100/100.0f;
					}
					dispRepulsive *= temperature;
				} else
				{
					dispRepulsive = d*k*k/pow(normD,2);
				}

				dispBuf[i] -= dispRepulsive;
				dispBuf[sampleIdx] += dispRepulsive;

				/*calculate attractive force*/
				//float dist = i>sampleIdx?distMat[i*(i-1)/2+sampleIdx]:distMat[sampleIdx*(sampleIdx-1)/2+i];
				/*if (dist<50)
				{
					float c3 = dist<15?3.0:1.0;
					fvec dispAttractive = c3*d*normD/k;
					dispBuf[i] += dispAttractive;
					dispBuf[sampleIdx] -= dispAttractive;
				}*/
			}
		}
		DWORD tRepAttrForces = GetTickCount()-t2;

		/*restrict the points from being pushed towards the boundary*/
		t2 = GetTickCount();
		for (i=0; i<nTotal; ++i)
		{
			for (j=0; j<dim; ++j)
			{
				float c1=1.0e6;
				float x = _layout[i](j);
				if (x==boundary[j*2] || x==boundary[j*2+1])
				{
					int stop = 1;
				}
				float d = c1*(1/(x-boundary[j*2]+1.0e-3)-1/(boundary[j*2+1]-x+1.0e-3));
				dispBuf[i](j) += d;
			}
		}
		DWORD tBoundaries = GetTickCount()-t2;

		/*limit the maximum displacement, boundary check*/
		t2 = GetTickCount();
		for (i=0; i<nTotal; ++i)
		{
			float n = norm(dispBuf[i],2);
			fvec newLayout = _layout[i]+dispBuf[i]*min(n, temperature)/n;
			for (j=0; j<dim; ++j)
			{
				int minBoundary = boundary[2*j];
				int maxBoundary = boundary[2*j+1];
				newLayout(j) = newLayout(j) < minBoundary?minBoundary:(newLayout(j)>maxBoundary?maxBoundary:newLayout(j));
			}
		}
		DWORD tLimits = GetTickCount()-t2;

		DWORD perItTime = GetTickCount() - t1;
		t1 = GetTickCount();

		prog.setValue(it);
	}
}
void Hypergraph::layoutPartitioned(int boundary [], bool bUpdate)
{
	int dim = 2;
	int nIteration = bUpdate?50:500;
	float temperature = 10;
	typedef fvec2 LayoutPoint;

	srand(time(NULL));

	int area = 1;
	for (int i=0; i<dim; ++i)
	{
		area *= boundary[2*i+1]-boundary[2*i];
	}
	float k = 1.0*sqrt(area*1.0f/_nVertices);

	/*initialize vertex layout*/
	int nEdges = _edges.size();
	int nTotal = _nVertices+nEdges;
	_layout.resize(nTotal);
	vector<LayoutPoint> dispBuf (nTotal);

	if (!bUpdate)
	{
		for (int i=0; i<nTotal; ++i)
		{
			_layout[i] = fvec(dim);
			for (int j=0; j<dim; ++j)
			{
				_layout[i](j) = boundary[2*j]+rand()%(boundary[2*j+1]-boundary[2*j]);
			}
			dispBuf[i] = fvec(dim);
		}
		_pinWeights.resize(nTotal);
		_pinWeights.assign(nTotal, 1);
	} 

	int nClusters = *max_element(_clusters.begin(), _clusters.end())+1;
	int nPartitions;
	vector<int> partitionSizes;
	getPartitionsByEdge(nPartitions, partitionSizes, _partitions);
	//getPartitionsByCluster(nPartitions, partitionSizes, _partitions);
	//getPartitionsByKDTree(nPartitions, partitionSizes, _partitions);
	vector<LayoutPoint> partCenters (nPartitions);

	vector<vector<int> > edgeBuf (_nVertices);
	for (int i=0; i<_edges.size(); ++i)
	{
		for (int j=0; j<_edges[i].size(); ++j)
		{
			edgeBuf[_edges[i][j]].push_back(i+_nVertices);
		}
	}

	int i,j;
	DWORD t0 = GetTickCount();
	DWORD perItTime = 0;
	DWORD tReplInt = 0;
	DWORD tReplExt = 0;
	DWORD tAttr = 0;
	QProgressDialog prog ("Performing graph layout ...", "", 0, nIteration-1);
	prog.setCancelButton(NULL);
	for (int it=0; it<nIteration; ++it)
	{
		DWORD t1 = GetTickCount();
		bool bChanged = false;
		for (int i=0; i<nTotal; ++i)
		{
			dispBuf[i].fill(0);
		}

		for (int i=0; i<nPartitions; ++i)
		{
			partCenters[i].fill(0);
			for (int j=0; j<nTotal; ++j)
			{
				if (i!=_partitions[j])
				{
					continue;
				}
				partCenters[i] += _layout[j];
			}
			partCenters[i] /= partitionSizes[i];
		}

		for (int i=0; i<nTotal; ++i)
		{
			if (_pinWeights[i]<1.0e-3)
			{
				continue;
			}

			float edgeLength = (i<_nVertices&&_clusters[i]==-1)?1.5*k:k;

			/*interior repulsive forces*/
			DWORD t2 = GetTickCount();
			for (int j=0; j<i; ++j)
			{
				if (_partitions[i]!=_partitions[j])
				{
					continue;
				}
				int vertexIdx = j;
				fvec disp = getRepulsiveForce(_layout[i], _layout[j], k);
				dispBuf[i] -= disp;
				dispBuf[j] += disp;
			}
			tReplInt += GetTickCount() - t2;

			/*exterior repulsive forces*/
			t2 = GetTickCount();
			for (int j=0; j<nPartitions; ++j)
			{
				if (j==_partitions[i])
				{
					continue;
				}
				if (partitionSizes[j]!=0)
				{
					fvec disp = partitionSizes[j]*getRepulsiveForce(_layout[i], partCenters[j], k);
					dispBuf[i] -= disp;
				}
			}
			tReplExt += GetTickCount() - t2;

			/*attractive forces*/
			t2 = GetTickCount();
			if (i<_nVertices)
			{
				for (int j=0; j<edgeBuf[i].size(); ++j)
				{
					int edgeIdx = edgeBuf[i][j];
					fvec disp = getAttractiveForce(_layout[i], _layout[edgeIdx], edgeLength);
					dispBuf[i] += 3.0*disp;
					dispBuf[edgeIdx] -= 3.0*disp;
				}
			}
			tAttr += GetTickCount() - t2;

		}

		/*cooling*/
		for (int i=0; i<nTotal; ++i)
		{
			/*adjust forces*/
			for (int j=0; j<dim; ++j)
			{
				float c1=1.0e5;
				float x = _layout[i](j);
				float d = c1*(1.0/(x-boundary[j*2]+1.0e-3)-1.0/(boundary[j*2+1]-x+1.0e-3));
				dispBuf[i](j) += d;
			}
			float n = norm(dispBuf[i],2);
			fvec newLayout = _layout[i]+dispBuf[i]*min(n, temperature*_pinWeights[i])/n;
			for (int j=0; j<dim; ++j)
			{
				int minBoundary = boundary[2*j];
				int maxBoundary = boundary[2*j+1];
				newLayout(j) = newLayout(j) < minBoundary?minBoundary:(newLayout(j)>maxBoundary?maxBoundary:newLayout(j));
			}
			_layout[i] = newLayout;
		}

		perItTime += GetTickCount() - t1;
		prog.setValue(it);
	}
	DWORD totalTime = GetTickCount()-t0;
	tReplInt /= nIteration;
	tReplExt /= nIteration;
	tAttr /= nIteration;
	perItTime /= nIteration;
	return;
}
void Hypergraph::layoutClustered(int boundary [], int nIteration, int dim/* =2 */, float c/* =1.0 */)
{
	_layoutDim = dim;
	float temperature = 10;
	int nEdges = _edges.size();
	int nTotal = _nVertices+nEdges;

	srand(time(NULL));

	int area = 1;
	for (int i=0; i<dim; ++i)
	{
		area *= boundary[2*i+1]-boundary[2*i];
	}
	float k = c*sqrt(area*1.0f/nTotal);

	/*initialize vertex layout*/
	_layout.resize(nTotal);
	vector<fvec> dispBuf (nTotal);
	for (int i=0; i<nTotal; ++i)
	{
		_layout[i] = fvec(dim);
		for (int j=0; j<dim; ++j)
		{
			_layout[i](j) = boundary[2*j]+rand()%(boundary[2*j+1]-boundary[2*j]);
		}

		dispBuf[i] = fvec(dim);
	}

	int i,j;

	QProgressDialog prog ("Performing graph layout ...", "", 0, nIteration-1);
	prog.setCancelButton(NULL);
	for (int it=0; it<nIteration; ++it)
	{
		DWORD t1 = GetTickCount();
		bool bChanged = false;
		for (i=0; i<nTotal; ++i)
		{
			dispBuf[i].fill(0);
		}

		DWORD t2 = GetTickCount();
		/*calculate repulsive force*/
		for (i=0; i<nTotal; ++i)
		{
			int clusterI = i<_nVertices?_clusters[i]:i-_nVertices;
			for (j=0; j<i; ++j)
			{
				int clusterJ = j<_nVertices?_clusters[j]:j-_nVertices;
				float edgeLengthSqr = 1;
				if (i<_nVertices)
				{
					edgeLengthSqr = clusterI==clusterJ?1.5:4;
				} else
				{
					if (j<_nVertices)
					{
						edgeLengthSqr = clusterI==clusterJ?1:4;
					} else
					{
						edgeLengthSqr = 9;
					}
				}
				edgeLengthSqr*=k*k;

				fvec d = _layout[j]-_layout[i];
				fvec disp;
				float normD = norm(d,2);
				if (normD<1.0e-5)
				{
					disp = fvec(dim);
					for (int iDim=0; iDim<dim; ++iDim)
					{
						disp(iDim) = rand()%100/100.0f;
					}
					disp *= temperature;
				} else
				{
					//disp = d*k*k/pow(normD,2);
					disp = edgeLengthSqr/pow(normD, 2)*d;
				}
				dispBuf[j] += disp;
				dispBuf[i] -= disp;
			}
		}

		DWORD tRepForce = GetTickCount()-t2;

		/*calculate attractive force*/
		for (i=0; i<_edges.size(); ++i)
		{
			int edgeIdx = i+_nVertices;
			for (j=0; j<_edges[i].size(); ++j)
			{
				float c2 = 10;
				float edgeLengthSqr = _clusters[_edges[i][j]]==i?1:9.0;
				edgeLengthSqr *= k;
				fvec d = _layout[edgeIdx] - _layout[_edges[i][j]];
				fvec disp = c2*d*norm(d,2)/edgeLengthSqr;
				dispBuf[edgeIdx] -= disp;
				dispBuf[_edges[i][j]] += disp;

				/*for (int m=0; m<j; ++m)
				{
					if (m==j)
					{
					continue;
					}
					float edgeLengthSqr = _clusters[_edges[i][j]]==_clusters[_edges[i][m]]?1:16.0;
					edgeLengthSqr *= k;
					fvec d = _layout[_edges[i][m]] - _layout[_edges[i][j]];
					fvec disp = c2*d*norm(d,2)/edgeLengthSqr;
					dispBuf[_edges[i][m]] -= disp;
					dispBuf[_edges[i][j]] += disp;
				}*/
			}
		}
		DWORD tRepAttrForces = GetTickCount()-t2;

		/*restrict the points from being pushed towards the boundary*/
		for (i=0; i<nTotal; ++i)
		{
			for (j=0; j<dim; ++j)
			{
				float c1=1.0e6;
				float x = _layout[i](j);
				if (x==boundary[j*2] || x==boundary[j*2+1])
				{
					int stop = 1;
				}
				float d = c1*(1/(x-boundary[j*2]+1.0e-3)-1/(boundary[j*2+1]-x+1.0e-3));
				dispBuf[i](j) += d;
			}
		}

		/*limit the maximum displacement, boundary check*/
		for (i=0; i<nTotal; ++i)
		{
			float n = norm(dispBuf[i],2);
			fvec newLayout = _layout[i]+dispBuf[i]*min(n, temperature)/n;
			for (j=0; j<dim; ++j)
			{
				int minBoundary = boundary[2*j];
				int maxBoundary = boundary[2*j+1];
				newLayout(j) = newLayout(j) < minBoundary?minBoundary:(newLayout(j)>maxBoundary?maxBoundary:newLayout(j));
			}
			if (norm(newLayout-_layout[i], 2)>1.0e-3)
			{
				_layout[i] = newLayout;
				bChanged = true;
			}
		}

		if (!bChanged)
		{
			break;
		}

		DWORD perItTime = GetTickCount() - t1;
		t1 = GetTickCount();

		prog.setValue(it);
	}
}