I have never worked on 3D objects with Python so I feel a bit lost.
I would like to know if it is possible to create a program that would detect the highest points of a 3D object (.obj format) and give their coordinates.
I had an idea about comparing each point of the 3D object and only returning the coordinates of the highest one.
I would appreciate any help, even by just telling me where to look at.
EDIT: I created a program that returns the maximum elevation of the object.
It works, but how could I make it return not only the maximum elevation of the highest point, but also its coordinates alongside the other axis?
As an example, it would return: the highest point is at 5.04 m. Its coordinates are (xxx, xxx, 5.04). Is there a way to print the coordinates of a given point?
EDIT 2: Here is my actual code. It returns the maximum height of a .obj. I would like it to return the 3-axis coordinates of the highest point.
Could it be possible to apply this code not to the entire object, but only to a part of it? (example: detect the highest point on z between a precise interval on the x and y axis?) I don't know how to work on coordinates with python
import sys
filename = 'test2.obj' # sys.argv[1]
x, y, z = [], [], []
with open(filename) as f:
for line in f:
line = line[:-1].split(' ')
if line[0] == 'v':
y.append(float(line[2]))
print('height max = ' + str(max(y)) + ' m')
input()
EDIT 2: Here is my actual code. It returns the maximum height of a .obj. I would like it to return the 3-axis coordinates of the highest point.
In your code you only append to the list y
. You'll also need to append to the respective x
and y
lists. You could then find the index of the max value in the y
list, and then index into the x
and z
lists with the same index.
Keeping the x, y, and z values in separate lists is a bit cumbersome. Consider keeping them in a namedtuple
. All you then need is a single list of these namedtuples.
Consider this as your input file:
v 10.307 4.083 4.905
v 1.920 11.778 13.118
v 7.883 17.747 0.258
v 5.085 0.353 10.356
v 8.999 9.146 8.047
And the code:
import sys
from collections import namedtuple
Point = namedtuple('Point', 'x y z')
points = []
filename = 'test2.obj' # sys.argv[1]
with open(filename) as f:
for line in f:
line = line[:-1].split(' ')
if line[0] == 'v':
x, y, z = map(float, line[1:])
points.append(Point(x, y, z))
highest_point = max(points, key=lambda point: point.z)
print('Highest point on the z-axis:', highest_point)
print(highest_point.x, highest_point.y, highest_point.z)
Output:
Highest point on the z-axis: Point(x=1.92, y=11.778, z=13.118)
1.92 11.778 13.118
max()
takes a keyword argument key that allows you to, in this case, make the comparisons on the z
attribute, instead of the Point
namedtuple.
Could it be possible to apply this code not to the entire object, but only to a part of it? (example: detect the highest point on z between a precise interval on the x and y axis?)
Sure. Before finding the max point, filter the list so it only contains points within the interval. For example:
filtered_points = []
for point in points:
if 9 > point.x > 3 and 10 > point.y > 5:
filtered_points.append(point)
highest_point = max(filtered_points, key=lambda point: point.z)
print('Highest point on the z-axis between some interval on the x and y axis:', highest_point)
Output:
Highest point on the z-axis between some interval on the x and y axis: Point(x=8.999, y=9.146, z=8.04)