Finding the perimeter of evolving objects in Fortran

  • Context: Comp Sci 
  • Thread starter Thread starter Dgrosser
  • Start date Start date
  • Tags Tags
    Fortran Perimeter
Click For Summary

Discussion Overview

The discussion revolves around a Fortran program designed to calculate the perimeter of multiple squares that move and cluster together over time. Participants explore the implementation of a flood-fill algorithm and methods for determining the perimeter based on the positions of these squares in a lattice plane.

Discussion Character

  • Exploratory
  • Technical explanation
  • Mathematical reasoning
  • Debate/contested

Main Points Raised

  • One participant describes their approach to defining the positions of squares in a Fortran program, including the use of a flood-fill algorithm to identify clusters.
  • Another participant suggests a method for calculating the perimeter by checking adjacent cells for empty spaces and proposes a code structure to implement this idea.
  • A different participant clarifies the perimeter calculation for clusters of squares, indicating that the number of shared sides with empty cells varies based on the arrangement of the squares.
  • There is a suggestion to modify the flood-fill function to return values that could help in counting the perimeter more effectively.
  • Concerns are raised about handling the edges of the array correctly, especially in relation to the wrapping behavior of the flood-fill algorithm.

Areas of Agreement / Disagreement

Participants express differing views on the best method to calculate the perimeter, with some proposing modifications to existing algorithms while others suggest alternative approaches. The discussion remains unresolved regarding the most effective implementation.

Contextual Notes

Participants note potential limitations in their approaches, such as the need to account for array edges and the specific definitions of clusters and empty spaces in the program.

Dgrosser
Messages
3
Reaction score
0
Hello fellows,

I am writing a computer program in Fortran, to find the perimeter of multiple squares. These squares move as "time" goes along, and if they come in contact with each other, they stick together, forming clusters. The reason why I'm doing this in Fortran is because the original program that randomly places the cubes and moves them is also in Fortran.

To help, I know the program has the position of each square (Which looks like this):
*L is the dimensions of the field)
do i = 1, N
10 x(i) = int(L*ranr()) + 1
y(i) = int(L*ranr()) + 1
if (occ(x(i),y(i)).eq.1) goto 10
occ(x(i),y(i)) = 1
id(x(i),y(i)) = i
write(11,*) x(i), y(i) !Write into pos.dat
enddo

This gives the definition of the squares, which it then transfers to a file (pos.dat).
There is also code to define the clusters, so that each cluster has its own area:

iclust = 0 ! iclust: the temporary number of clusters
csize = 0.0
do i = 1, N
xc = x(i) ! current position in x
yc = y(i) ! current position in y
x1 = xc
y1 = yc
if (fill(x(i),y(i)).eq.1) then
iclust = iclust + 1
tab = 0
clustN(iclust) = tab
clustI(iclust,:) = ids(:)
csize = csize + tab


Finally, all the clusters are figured out by a flood-fill algorithm, which I think may be relavent:
*Note old = 1*
one = 1

if (fill(x1,y1).eq.old) then

fill(x1,y1) = new
tab = tab + 1
ids(tab) = id(x1,y1)
if (x1.eq.L) then
call floodPBC(xc,yc,one,y1,new,old,fill,tab,ids,id)
else
call floodPBC(xc,yc,x1+1,y1,new,old,fill,tab,ids,id)
endif

if (y1.eq.L) then
call floodPBC(xc,yc,x1,one,new,old,fill,tab,ids,id)
else
call floodPBC(xc,yc,x1,y1+1,new,old,fill,tab,ids,id)
endif

if (x1.eq.1) then
call floodPBC(xc,yc,L,y1,new,old,fill,tab,ids,id)
else
call floodPBC(xc,yc,x1-1,y1,new,old,fill,tab,ids,id)
endif

if (y1.eq.1) then
call floodPBC(xc,yc,x1,L,new,old,fill,tab,ids,id)
else
call floodPBC(xc,yc,x1,y1-1,new,old,fill,tab,ids,id)
endif

endif

return
Where yc and xc are original positions, and x1 and y1 are the new updated positions.

Any advice will help. I am not a programer, but I am beginning to learn it. Thank you.
 
Physics news on Phys.org
Dgrosser said:
Hello fellows,

I am writing a computer program in Fortran, to find the perimeter of multiple squares. These squares move as "time" goes along, and if they come in contact with each other, they stick together, forming clusters. The reason why I'm doing this in Fortran is because the original program that randomly places the cubes and moves them is also in Fortran.

To help, I know the program has the position of each square (Which looks like this):
*L is the dimensions of the field)
do i = 1, N
10 x(i) = int(L*ranr()) + 1
y(i) = int(L*ranr()) + 1
if (occ(x(i),y(i)).eq.1) goto 10
occ(x(i),y(i)) = 1
id(x(i),y(i)) = i
write(11,*) x(i), y(i) !Write into pos.dat
enddo

This gives the definition of the squares, which it then transfers to a file (pos.dat).
There is also code to define the clusters, so that each cluster has its own area:

iclust = 0 ! iclust: the temporary number of clusters
csize = 0.0
do i = 1, N
xc = x(i) ! current position in x
yc = y(i) ! current position in y
x1 = xc
y1 = yc
if (fill(x(i),y(i)).eq.1) then
iclust = iclust + 1
tab = 0
clustN(iclust) = tab
clustI(iclust,:) = ids(:)
csize = csize + tab


Finally, all the clusters are figured out by a flood-fill algorithm, which I think may be relavent:
*Note old = 1*
one = 1

if (fill(x1,y1).eq.old) then

fill(x1,y1) = new
tab = tab + 1
ids(tab) = id(x1,y1)
if (x1.eq.L) then
call floodPBC(xc,yc,one,y1,new,old,fill,tab,ids,id)
else
call floodPBC(xc,yc,x1+1,y1,new,old,fill,tab,ids,id)
endif

if (y1.eq.L) then
call floodPBC(xc,yc,x1,one,new,old,fill,tab,ids,id)
else
call floodPBC(xc,yc,x1,y1+1,new,old,fill,tab,ids,id)
endif

if (x1.eq.1) then
call floodPBC(xc,yc,L,y1,new,old,fill,tab,ids,id)
else
call floodPBC(xc,yc,x1-1,y1,new,old,fill,tab,ids,id)
endif

if (y1.eq.1) then
call floodPBC(xc,yc,x1,L,new,old,fill,tab,ids,id)
else
call floodPBC(xc,yc,x1,y1-1,new,old,fill,tab,ids,id)
endif

endif

return
Where yc and xc are original positions, and x1 and y1 are the new updated positions.

Any advice will help. I am not a programer, but I am beginning to learn it. Thank you.

What's your question?
 
My question is how can I find the perimeter of these plotted points in a lattice plane. Each of the squares has a unit side of 1, and one thing I did not mention is that the cubes have a natural value of "1", where the empty space has a natural value of "0". I was thinking I could write a program that would track each cube and check the area around it. If the area above and to the left is empty (y1+1; x1-1), then the perimeter would be 2, as the other areas would be cut off by other cubes. So the code would look something like:

Do i 1,N !(N=Number of cubes)

if (xi+1.eq.0) Perimeter=perimeter+1
if (xi-1.eq.0) Perimeter=perimeter+1
if (yi+1.eq.0) Perimeter=perimeter+1
if (yi-1.eq.0) Perimeter=perimeter+1
enddo

Would this work, or is there something I'm missing?
 
I gather that you are trying to determine the total number of sides that a given custer has that are shared with empty cells. So for a single cell, the answer would be four. For two adjacent cells forming a rectangle the answer would be six. For three cells forming an L it would be eight. Am I understanding you right? If so, two ideas spring to mind.

One would be to modify that flood fill function so that it returns a value, and return the sum of the return values of any calls to itself that it makes plus the number of sides in the cell (x1,y1). Your code in your last post will almost do the edge counting - you need to actually look at the array (so fill(x1+1,y1).eq.0 etc inside the brackets) but it is on the right lines. Watch out for the array edges, though - the flood fill algorithm appears to wrap around the edge of the world, and you need to do the same.

The other option is to look at the array fill, which I gather has a different number for each cluster - so 0 means empty, 1 means "part of first cluster", 2 means "part of second cluster" and so on. Create an array with one entry for each cluster, then loop over each cell in fill. If the cell value is non-zero, count the edges using your idea (as modified in the previous paragraph) and add it to the appropriate entry in your new array.
 

Similar threads

  • · Replies 11 ·
Replies
11
Views
6K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
18
Views
3K
  • · Replies 10 ·
Replies
10
Views
2K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
Replies
5
Views
4K
  • · Replies 2 ·
Replies
2
Views
5K
  • · Replies 4 ·
Replies
4
Views
10K