Let's quantitatively evaluate the ** beauty ** of the structure. I am doing research. As a quantification method, ** fractal dimension ** is used as one index.
And, in order to find the fractal dimension, we use a method called ** box counting method **. I did not find an example of dealing with this in 3D, so I wrote an article.
[Fractal dimension](https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%AB%E6% AC% A1% E5% 85% 83) Wikipedia has it like this. To put it simply, the dimensions between 1D and 2D, and between 2D and 3D can be represented by ** non-integer values **. You can express ** complexity **. Quantitative evaluation of landscapes and paintings is performed using this.
This time, as an example, we will use a * 200 × 200 × 200 * cube. Let's experiment as a 3D * numpy * array initialized with * 1 *.
Actually read * STL * file
numpy-stl
Arrange using.
(Details will be written in the future)
Regarding the box counting method, I think this article is easy to understand, so I will link to it. Fractal analysis of surface roughness curve
Think of this three-dimensionally.
We will change the size of this grid one by one.
Scan the 3D array in the order of x direction → y direction → z direction
np.any
.3d_fractal.py
def count(arr, x, y, z, b):
i = j = k = 0
b_tmp = b
b_tmp2 = b
ct = 0
j_tmp = b
k_tmp = b
while k < z:
while j < y:
while i < x:
if (np.any(arr[i:b, j:j_tmp, k:k_tmp] == 1)):
ct += 1
i += b_tmp
b += b_tmp
#Wrap back
j += b_tmp2
j_tmp += b_tmp2
b = b_tmp2
i = 0
#Wrap back
k += b_tmp2
k_tmp += b_tmp2
b = b_tmp2
j = b_tmp2
i = 0
j = 0
Repeat the process of count ()
until the grid size changes from * 200 * to * 1/2 * by 100, 50, ... and * 1 *.
When the grid size is * 1 *, the count should be * 200 x 200 x 200 = 80,00,000 *.
3d_fractal.py
def main():
x = y = z = 200
graph_x = []
graph_y = []
array3d = np.ones((x, y, z))
ct_1 = np.count_nonzero(array3d == 1)
grid_size = max(x, y, z)
while grid_size >= 1:
n = count(array3d, x, y, z, grid_size)
graph_x.append(math.log(grid_size))
graph_y.append(math.log(n))
print(grid_size, n)
print (math.log(grid_size), math.log(n))
grid_size = int(grid_size / 2)
Perform linear regression from the counted result.
Scikit-learn
class for regression processing
Use sklearn.linear_model.LinearRegression
.
3d_fractal.py
graph_x = np.array(graph_x).reshape((len(graph_x), 1)) #Make one row
graph_y = np.array(graph_y).reshape((len(graph_y), 1))
model_lr = LinearRegression()
#Predictive model creation
model_lr.fit(graph_x, graph_y)
plt.xlabel("log(grid_size)")
plt.ylabel("log(n)")
plt.plot(graph_x, graph_y, 'o')
plt.plot(graph_x, model_lr.predict(graph_x), linestyle="solid")
plt.grid()
plt.show()
#Fractal dimension=Regression coefficient
fractal = model_lr.coef_[0][0] * -1
print("Fractal : ", fractal)
Here is the logarithmic graph of the result. Grid size * log * on the horizontal axis
200 1
5.298317366548036 0.0
100 8
4.605170185988092 2.0794415416798357
50 64
3.912023005428146 4.1588830833596715
25 512
3.2188758248682006 6.238324625039508
12 4913
2.4849066497880004 8.499640032168648
6 39304
1.791759469228055 10.579081573848484
3 300763
1.0986122886681098 12.614077858172898
1 8000000
0.0 15.89495209964411
Fractal : 3.004579190748091
The result looks like this. The fractal dimension is * 3.004579190748091 * So it's almost a theoretical value. When repeating from * 200 *, there was a case where it was not divisible by * 25/2 = 12 *, so there was a slight deviation.
--We were able to verify the three-dimensional fractal dimension analysis by the box count method. -Next time, I would like to write a method to calculate the fractal dimension directly from the * STL * file.
"Fractal analysis of surface roughness curve", Takeo Kono, (2010), Nagano Prefectural Institute of Technology Research Bulletin, No.5, p.P52-P55.
Recommended Posts