How to change 'cost' of path here? - python

I'm reading this python code about A star algorithm. For me, I understand how this algorithm work, but when I come to the code I got some confusing things until to understand. I want to be able to change the cost of paths here. I mean I need to be able to set a cost to each pixel here while calculating the best path but I couldn't figure out where to do it. I have 2 paths and I want the algorithm to choose the bottom path because of the cost of the top path. How do I do that?
Image of the paths. I want algorithm to choose bottom one.
Entire code of the algorithm:
"""
A* grid planning
author: Atsushi Sakai(#Atsushi_twi)
Nikos Kanargias (nkana#tee.gr)
See Wikipedia article (https://en.wikipedia.org/wiki/A*_search_algorithm)
"""
import math
import matplotlib.pyplot as plt
show_animation = True
class AStarPlanner:
def __init__(self, ox, oy, reso, rr):
"""
Initialize grid map for a star planning
ox: x position list of Obstacles [m]
oy: y position list of Obstacles [m]
reso: grid resolution [m]
rr: robot radius[m]
"""
self.reso = reso
self.rr = rr
self.calc_obstacle_map(ox, oy)
self.motion = self.get_motion_model()
class Node:
def __init__(self, x, y, cost, pind):
self.x = x # index of grid
self.y = y # index of grid
self.cost = cost
self.pind = pind
def __str__(self):
return str(self.x) + "," + str(self.y) + "," + str(
self.cost) + "," + str(self.pind)
def planning(self, sx, sy, gx, gy):
"""
A star path search
input:
sx: start x position [m]
sy: start y position [m]
gx: goal x position [m]
gy: goal y position [m]
output:
rx: x position list of the final path
ry: y position list of the final path
"""
nstart = self.Node(self.calc_xyindex(sx, self.minx),
self.calc_xyindex(sy, self.miny), 0.0, -1)
ngoal = self.Node(self.calc_xyindex(gx, self.minx),
self.calc_xyindex(gy, self.miny), 0.0, -1)
open_set, closed_set = dict(), dict()
open_set[self.calc_grid_index(nstart)] = nstart
while 1:
if len(open_set) == 0:
print("Open set is empty..")
break
c_id = min(
open_set,
key=lambda o: open_set[o].cost + self.calc_heuristic(ngoal,
open_set[
o]))
current = open_set[c_id]
# show graph
if show_animation: # pragma: no cover
plt.plot(self.calc_grid_position(current.x, self.minx),
self.calc_grid_position(current.y, self.miny), "xc")
# for stopping simulation with the esc key.
plt.gcf().canvas.mpl_connect('key_release_event',
lambda event: [exit(
0) if event.key == 'escape' else None])
if len(closed_set.keys()) % 10 == 0:
plt.pause(0.001)
if current.x == ngoal.x and current.y == ngoal.y:
print("Find goal")
ngoal.pind = current.pind
ngoal.cost = current.cost
break
# Remove the item from the open set
del open_set[c_id]
# Add it to the closed set
closed_set[c_id] = current
# expand_grid search grid based on motion model
for i, _ in enumerate(self.motion):
node = self.Node(current.x + self.motion[i][0],
current.y + self.motion[i][1],
current.cost + self.motion[i][2], c_id)
n_id = self.calc_grid_index(node)
# If the node is not safe, do nothing
if not self.verify_node(node):
continue
if n_id in closed_set:
continue
if n_id not in open_set:
open_set[n_id] = node # discovered a new node
else:
if open_set[n_id].cost > node.cost:
# This path is the best until now. record it
open_set[n_id] = node
rx, ry = self.calc_final_path(ngoal, closed_set)
return rx, ry
def calc_final_path(self, ngoal, closedset):
# generate final course
rx, ry = [self.calc_grid_position(ngoal.x, self.minx)], [
self.calc_grid_position(ngoal.y, self.miny)]
pind = ngoal.pind
while pind != -1:
n = closedset[pind]
rx.append(self.calc_grid_position(n.x, self.minx))
ry.append(self.calc_grid_position(n.y, self.miny))
pind = n.pind
return rx, ry
#staticmethod
def calc_heuristic(n1, n2):
w = 1.0 # weight of heuristic
d = w * math.hypot(n1.x - n2.x, n1.y - n2.y)
return d
def calc_grid_position(self, index, minp):
"""
calc grid position
:param index:
:param minp:
:return:
"""
pos = index * self.reso + minp
return pos
def calc_xyindex(self, position, min_pos):
return round((position - min_pos) / self.reso)
def calc_grid_index(self, node):
return (node.y - self.miny) * self.xwidth + (node.x - self.minx)
def verify_node(self, node):
px = self.calc_grid_position(node.x, self.minx)
py = self.calc_grid_position(node.y, self.miny)
if px < self.minx:
return False
elif py < self.miny:
return False
elif px >= self.maxx:
return False
elif py >= self.maxy:
return False
# collision check
if self.obmap[node.x][node.y]:
return False
return True
def calc_obstacle_map(self, ox, oy):
self.minx = round(min(ox))
self.miny = round(min(oy))
self.maxx = round(max(ox))
self.maxy = round(max(oy))
print("minx:", self.minx)
print("miny:", self.miny)
print("maxx:", self.maxx)
print("maxy:", self.maxy)
self.xwidth = round((self.maxx - self.minx) / self.reso)
self.ywidth = round((self.maxy - self.miny) / self.reso)
print("xwidth:", self.xwidth)
print("ywidth:", self.ywidth)
# obstacle map generation
self.obmap = [[False for i in range(self.ywidth)]
for i in range(self.xwidth)]
for ix in range(self.xwidth):
x = self.calc_grid_position(ix, self.minx)
for iy in range(self.ywidth):
y = self.calc_grid_position(iy, self.miny)
for iox, ioy in zip(ox, oy):
d = math.hypot(iox - x, ioy - y)
if d <= self.rr:
self.obmap[ix][iy] = True
break
#staticmethod
def get_motion_model():
# dx, dy, cost
motion = [[1, 0, 1],
[0, 1, 1],
[-1, 0, 1],
[0, -1, 1],
[-1, -1, math.sqrt(2)],
[-1, 1, math.sqrt(2)],
[1, -1, math.sqrt(2)],
[1, 1, math.sqrt(2)]]
return motion
def main():
print(__file__ + " start!!")
# start and goal position
sx = 1.0 # [m]
sy = 1.0 # [m]
gx = 50.0 # [m]
gy = 50.0 # [m]
grid_size = 10.0 # [m]
robot_radius = 1.0 # [m]
# set obstacle positions
ox, oy = [], []
for i in range(-10, 60):
ox.append(i)
oy.append(-10.0)
for i in range(-10, 60):
ox.append(60.0)
oy.append(i)
for i in range(-10, 61):
ox.append(i)
oy.append(60.0)
for i in range(-10, 61):
ox.append(-10.0)
oy.append(i)
for i in range(-10, 40):
ox.append(20.0)
oy.append(i)
for i in range(0, 10):
ox.append(40.0)
oy.append(i)
for i in range(0, 40):
ox.append(40.0)
oy.append(60.0 - i)
if show_animation: # pragma: no cover
plt.plot(ox, oy, ".k")
plt.plot(sx, sy, "og")
plt.plot(gx, gy, "xb")
plt.grid(True)
plt.axis("equal")
a_star = AStarPlanner(ox, oy, grid_size, robot_radius)
rx, ry = a_star.planning(sx, sy, gx, gy)
if show_animation: # pragma: no cover
plt.plot(rx, ry, "-r")
plt.show()
plt.pause(0.001)
if __name__ == '__main__':
main()

I did it with adding a part of code like that
# expand_grid search grid based on motion model
for i, _ in enumerate(self.motion):
cost = 0
if(current.x + self.motion[i][0] >= 45 and (current.x + self.motion[i][0]) <= 55 and current.y + self.motion[i][1] >= 20 and current.y + self.motion[i][1] <= 31):
cost = 15
node = self.Node(current.x + self.motion[i][0],
current.y + self.motion[i][1],
current.cost + self.motion[i][2] + cost, c_id)
n_id = self.calc_grid_index(node)

Related

tkinter - Infinite Canvas "world" / "view" - keeping track of items in view

I feel like this is a little bit complicated or at least I'm confused on it, so I'll try to explain it by rendering the issue. Let me know if the issue isn't clear.
I get the output from my viewing_box through the __init__ method and it shows:
(0, 0, 378, 265)
Which is equivalent to a width of 378 and a height of 265.
When failing, I track the output:
1 false
1 false
here ([0.0, -60.0], [100.0, 40.0]) (0, 60, 378, 325)
The tracking is done in _scan_view with the code:
if not viewable:
current = self.itemcget(item,'tags')
if isinstance(current, tuple):
new = current-('viewable',)
else:
print('here',points, (x1,y1,x2,y2))
new = ''
self.inview_items.discard(item)
So the rectangle stays with width and height of 100, the coords however failing to be the expected ones. While view width and height stays the same and moves correctly in my current understanding. Expected:
if x1 <= point[0] <= x2 and y1 <= point[1] <= y2: and it feels like I've created two coordinate systems but I don't get it. Is someone looking on it and see it immediately?
Full Code:
import tkinter as tk
class InfiniteCanvas(tk.Canvas):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self.inview_items = set() #in view
self.niview_items = set() #not in view
self._xshifted = 0 #view moved in x direction
self._yshifted = 0 #view moved in y direction
self._multi = 0
self.configure(confine=False,highlightthickness=0,bd=0)
self.bind('<MouseWheel>', self._vscroll)
self.bind('<Shift-MouseWheel>', self._hscroll)
root.bind('<Control-KeyPress>',lambda e:setattr(self,'_multi', 10))
root.bind('<Control-KeyRelease>',lambda e:setattr(self,'_multi', 0))
print(self.viewing_box())
return None
def viewing_box(self):
'returns x1,y1,x2,y2 of the currently visible area'
x1 = 0 - self._xshifted
y1 = 0 - self._yshifted
x2 = self.winfo_reqwidth()-self._xshifted
y2 = self.winfo_reqheight()-self._yshifted
return x1,y1,x2,y2
def _scan_view(self):
x1,y1,x2,y2 = self.viewing_box()
for item in self.find_withtag('viewable'):
#check if one felt over the edge
coords = self.coords(item)
#https://www.geeksforgeeks.org/python-split-tuple-into-groups-of-n/
points = tuple(
coords[x:x + 2] for x in range(0, len(coords), 2))
viewable = False
for point in points:
if x1 <= point[0] <= x2 and y1 <= point[1] <= y2:
#if any point is in viewing box
viewable = True
print(item, 'true')
else:
print(item, 'false' )
if not viewable:
current = self.itemcget(item,'tags')
if isinstance(current, tuple):
new = current-('viewable',)
else:
print('here',points, (x1,y1,x2,y2))
new = ''
self.inview_items.discard(item)
self.itemconfigure(item,tags=new)
for item in self.find_overlapping(x1,y1,x2,y2):
#check if item inside of viewing_box not in inview_items
if item not in self.inview_items:
self.inview_items.add(item)
current = self.itemcget(item,'tags')
if isinstance(current, tuple):
new = current+('viewable',)
elif isinstance(current, str):
if str:
new = (current, 'viewable')
else:
new = 'viewable'
self.itemconfigure(item,tags=new)
print(self.inview_items)
def _create(self, *args):
if (current:=args[-1].get('tags', False)):
args[-1]['tags'] = current+('viewable',)
else:
args[-1]['tags'] = ('viewable',)
ident = super()._create(*args)
self._scan_view()
return ident
def _hscroll(self,event):
offset = int(event.delta/120)
if self._multi:
offset = int(offset*self._multi)
canvas.move('all', offset,0)
self._xshifted += offset
self._scan_view()
def _vscroll(self,event):
offset = int(event.delta/120)
if self._multi:
offset = int(offset*self._multi)
canvas.move('all', 0,offset)
self._yshifted += offset
self._scan_view()
root = tk.Tk()
canvas = InfiniteCanvas(root)
canvas.pack(fill=tk.BOTH, expand=True)
size, offset, start = 100, 10, 0
canvas.create_rectangle(start,start, size,size, fill='green')
canvas.create_rectangle(
start+offset,start+offset, size+offset,size+offset, fill='darkgreen')
root.mainloop()
PS: Before thinking this is over-complicated and using just find_overlapping isn't working, since it seems the item needs to be at least 51% in the view to get tracked with tkinters algorithm.
You can find an improved version now on CodeReview!
I still don't know what I have done wrong but it works with scan_dragto.
import tkinter as tk
class InfiniteCanvas(tk.Canvas):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self.inview_items = set() #in view
self.niview_items = set() #not in view
self._xshifted = 0 #view moved in x direction
self._yshifted = 0 #view moved in y direction
self._multi = 0
self.configure(confine=False,highlightthickness=0,bd=0)
self.bind('<MouseWheel>', self._vscroll)
self.bind('<Shift-MouseWheel>', self._hscroll)
root.bind('<Control-KeyPress>',lambda e:setattr(self,'_multi', 10))
root.bind('<Control-KeyRelease>',lambda e:setattr(self,'_multi', 0))
return None
def viewing_box(self):
'returns x1,y1,x2,y2 of the currently visible area'
x1 = 0 - self._xshifted
y1 = 0 - self._yshifted
x2 = self.winfo_reqwidth()-self._xshifted
y2 = self.winfo_reqheight()-self._yshifted
return x1,y1,x2,y2
def _scan_view(self):
x1,y1,x2,y2 = self.viewing_box()
for item in self.find_withtag('viewable'):
#check if one felt over the edge
coords = self.coords(item)
#https://www.geeksforgeeks.org/python-split-tuple-into-groups-of-n/
points = tuple(
coords[x:x + 2] for x in range(0, len(coords), 2))
viewable = False
for point in points:
if x1 <= point[0] <= x2 and y1 <= point[1] <= y2:
#if any point is in viewing box
viewable = True
if not viewable:
current = self.itemcget(item,'tags')
if isinstance(current, tuple):
new = current-('viewable',)
else:
print('here',points, (x1,y1,x2,y2))
new = ''
self.inview_items.discard(item)
self.itemconfigure(item,tags=new)
for item in self.find_overlapping(x1,y1,x2,y2):
#check if item inside of viewing_box not in inview_items
if item not in self.inview_items:
self.inview_items.add(item)
current = self.itemcget(item,'tags')
if isinstance(current, tuple):
new = current+('viewable',)
elif isinstance(current, str):
if str:
new = (current, 'viewable')
else:
new = 'viewable'
self.itemconfigure(item,tags=new)
print(self.inview_items)
def _create(self, *args):
if (current:=args[-1].get('tags', False)):
args[-1]['tags'] = current+('viewable',)
else:
args[-1]['tags'] = ('viewable',)
ident = super()._create(*args)
self._scan_view()
return ident
def _hscroll(self,event):
offset = int(event.delta/120)
if self._multi:
offset = int(offset*self._multi)
cx,cy = self.winfo_rootx(), self.winfo_rooty()
self.scan_mark(cx, cy)
self.scan_dragto(cx+offset, cy, gain=1)
self._xshifted += offset
self._scan_view()
def _vscroll(self,event):
offset = int(event.delta/120)
if self._multi:
offset = int(offset*self._multi)
cx,cy = self.winfo_rootx(), self.winfo_rooty()
self.scan_mark(cx, cy)
self.scan_dragto(cx, cy+offset, gain=1)
self._yshifted += offset
self._scan_view()
root = tk.Tk()
canvas = InfiniteCanvas(root)
canvas.pack(fill=tk.BOTH, expand=True)
size, offset, start = 100, 10, 0
canvas.create_rectangle(start,start, size,size, fill='green')
canvas.create_rectangle(
start+offset,start+offset, size+offset,size+offset, fill='darkgreen')
root.mainloop()

IndexError: list index out of range error while enter value like 1 2 3 in Python

I am generating a graph/drawing using pyhton.
When I am entering value from backward like 6 5 4 3 it's working fine but When I am giving input like 1 2 3 it's throwing list index out of range error.
I am new to python. Please help me to fix this.
**EDIT : ** it's only accepting when first value is greater than second value for example it's working with 7 6 but not with 6 7.
here is my python code:
HUMAN_HEIGHT = 3
HUMAN_WIDTH = 3
HUMAN_LEG_OFFSET = 1
def print_2d_array(arr):
"""Print the 2D Array"""
print(f"Height = {len(arr)}, Width = {len(arr[0])}")
for row in arr:
for item in row:
print(f"{item}", end="")
print()
def increasing_slope(index):
"""Returns if the slope is increasing which is the even number"""
return index % 2 == 0
def get_indicator(index):
"""Returns the indicator for increasing or decreasing slope"""
return "/" if increasing_slope(index) else "\\"
def add_human_at(new_arr, human_location, height):
"""Adds Human to the Array"""
human_x = human_location[0]
human_y = human_location[1]
new_arr[height - human_y - 1][human_x - 1] = " "
new_arr[height - human_y - 1][human_x] = "○"
new_arr[height - human_y - 1][human_x + 1] = " "
new_arr[height - human_y][human_x - 1] = "/"
new_arr[height - human_y][human_x] = "|"
new_arr[height - human_y][human_x + 1] = "\\"
new_arr[height - human_y + 1][human_x - 1] = "<"
new_arr[height - human_y + 1][human_x] = " "
new_arr[height - human_y + 1][human_x + 1] = ">"
def create_line(y0, x0, y1, x1, index):
"""Generator that Returns the diagonal line from x,y to x1,y1"""
yield y0, x0
while y0 != y1 and x0 != x1:
y0 = y0 + (-1 if increasing_slope(index) else 1)
x0 += 1
yield y0, x0
def get_2d_mountains_from_1d_sum(arr, height, width, human_location):
new_arr = []
for i in range(height + HUMAN_HEIGHT):
mountain_row = []
for j in range(width + HUMAN_LEG_OFFSET):
mountain_row.append(" ")
new_arr.append(mountain_row)
ground = height + HUMAN_HEIGHT
prev_x, prev_y = 0, 0
for index, [x, y] in enumerate(arr):
indicator = get_indicator(index)
if prev_x >= human_location[0]:
start_x, start_y = ground - prev_y - 1, prev_x + HUMAN_LEG_OFFSET
end_x, end_y = ground - y - 1, x - 1 + HUMAN_LEG_OFFSET
else:
start_x, start_y = ground - prev_y - 1, prev_x
end_x, end_y = ground - y - 1, x - 1
for (point_y, point_x) in create_line(start_x, start_y, end_x, end_y, index):
new_arr[point_y][point_x] = indicator
prev_y = y
prev_x = x
add_human_at(new_arr, human_location, height)
print_2d_array(new_arr)
def generate_mountains(nums):
sum_nums = []
sum_at_position = 0
previous_sum = 0
total_width = 0
max_height = 0
human_location = []
for index, item in enumerate(nums):
# + or - numbers to get prefix list
if index % 2 == 0:
sum_at_position += (item - 1)
else:
sum_at_position -= (item - 1)
total_width += abs(sum_at_position - previous_sum) + 1
if sum_at_position > max_height:
max_height = sum_at_position
human_location = [total_width, max_height]
previous_sum = sum_at_position
sum_nums.append([total_width, sum_at_position])
get_2d_mountains_from_1d_sum(sum_nums, max_height + 1, total_width, human_location)
def print_mountains_human_from_input(nums):
generate_mountains(nums)
print("Enter the inputs")
a = [int(x) for x in input().split()]
print_mountains_human_from_input(a)
I added the screenshot of error..
thanks in advance.
You can add a sorting to your function to avoid a wrong input error but it will not fix the actual error:
def print_mountains_human_from_input(nums):
nums.sort(reverse=True)
generate_mountains(nums)

Why doesn't update repaint a scene?

I am making a marching cubes project in python using PyQt5 and PyOpenGL. I am trying to hide the wireframe cube which marches across the screen, referenced as mainWindow.marchingCube to disappear after cycling through. I managed to get the disappearing cycle to occur, but the cube does not actually disappear. I called the QOpenGLWidget's update function, but the cube still did not disappear.
import sys
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QSlider,
QOpenGLWidget, QLabel, QPushButton
)
from PyQt5.QtCore import Qt
from OpenGL.GL import (
glLoadIdentity, glTranslatef, glRotatef,
glClear, glBegin, glEnd,
glColor3fv, glVertex3fv,
GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT,
GL_QUADS, GL_LINES
)
from OpenGL.GLU import gluPerspective
from numerics import sin, cos, tan, avg, rnd #Numerics is my custom math library.
import random, time
class mainWindow(QMainWindow): #Main class.
shapes = [] #this will hold instances of the following classes: cube
dataPoints = []
zoomLevel = -10
rotateDegreeV = -90
rotateDegreeH = 0
marchActive = False
limit = -1
meshPoints = []
class cube():
render = True
solid = False
color = (1, 1, 1)
def config(self, x, y, z, size = 0.1, solid = False, color = (1, 1, 1)):
self.solid = solid
self.color = color
self.size = size / 2
s = self.size
self.vertices = [
(-s + x, s + y, -s + z),
(s + x, s + y, -s + z),
(s + x, -s + y, -s + z),
(-s + x, -s + y, -s + z),
(-s + x, s + y, s + z),
(s + x, s + y, s + z),
(s + x, -s + y, s + z),
(-s + x, -s + y, s + z)
]
self.edges = [
(0,1), (0,3), (0,4), (2,1),
(2,3), (2,6), (7,3), (7,4),
(7,6), (5,1), (5,4), (5,6)
]
self.facets = [
(0, 1, 2, 3), (0, 1, 6, 5),
(0, 3, 7, 4), (6, 5, 1, 2),
(6, 7, 4, 5), (6, 7, 3, 2)
]
def show(self):
self.render = True
def hide(self):
self.render = False
class dataPoint():
location = (0, 0, 0)
value = 0
shape = None
def place(self, x, y, z):
self.location = (x, y, z)
def set(self, val):
self.value = val
def setShape(self, shape):
self.shape = shape
class meshPoint():
location = (0, 0, 0)
shape = None
def place(self, x, y, z):
self.location = (x, y, z)
def setShape(self, shape):
self.shape = shape
def keyPressEvent(self, event): #This is the keypress detector. I use this to determine input to edit grids.
try:
key = event.key()
#print(key)
if key == 87:
self.rotateV(5)
elif key == 65:
self.rotateH(5)
elif key == 83:
self.rotateV(-5)
elif key == 68:
self.rotateH(-5)
elif key == 67:
self.zoom(1)
elif key == 88:
self.zoom(-1)
elif key == 77:
self.marchStep()
except:
pass
def __init__(self):
super(mainWindow, self).__init__()
self.currentStep = 0
self.width = 700 #Variables used for the setting of the size of everything
self.height = 600
self.setGeometry(0, 0, self.width + 50, self.height) #Set the window size
self.initData(3, 3, 3)
def setupUI(self):
self.openGLWidget = QOpenGLWidget(self) #Create the GLWidget
self.openGLWidget.setGeometry(0, 0, self.width, self.height)
self.openGLWidget.initializeGL()
self.openGLWidget.resizeGL(self.width, self.height) #Resize GL's knowledge of the window to match the physical size?
self.openGLWidget.paintGL = self.paintGL #override the default function with my own?
self.filterSlider = QSlider(Qt.Vertical, self)
self.filterSlider.setGeometry(self.width + 10, int(self.height / 2) - 100, 30, 200)
self.filterSlider.valueChanged[int].connect(self.filter)
self.limitDisplay = QLabel(self)
self.limitDisplay.setGeometry(self.width, int(self.height / 2) - 130, 50, 30)
self.limitDisplay.setAlignment(Qt.AlignCenter)
self.limitDisplay.setText('-1')
self.marchButton = QPushButton(self)
self.marchButton.setGeometry(self.width, int(self.height / 2) - 160, 50, 30)
self.marchButton.setText('March!')
self.marchButton.clicked.connect(self.marchStep)
def marchStep(self):
if not self.marchActive:
marchAddr = len(self.shapes)
self.shapes.append(self.cube())
self.marchingCube = self.shapes[marchAddr]
self.marchActive = True
self.currentStep = 0
if self.currentStep == len(self.marchPoints):
self.currentStep = 0
#print('meshPoints: {}'.format(self.meshPoints))
for mp in self.meshPoints:
#print(mp.shape)
self.shapes.remove(mp.shape)
self.meshPoints.clear()
self.marchingCube.hide()
return
if self.currentStep == 0:
self.marchingCube.show()
p = self.marchPoints[self.currentStep]
x, y, z = p
self.marchingCube.config(x, y, z, size = 1)
points = []
for i in range(8):
point = self.getDataPointByLocation(self.marchingCube.vertices[i])
points.append(point)
self.openGLWidget.update()
#print('step: {} x: {} y: {} z: {}'.format(self.currentStep, x, y, z))
#for point in points:
# print(point.location, end = ' ')
#print()
for pair in self.marchingCube.edges:
pointA = points[pair[0]]
pointB = points[pair[1]]
#print('pointA.value: {} pointB.value: {} limit: {}'.formatpointA.value, pointB.value, self.limit)
if (pointA.value < self.limit and pointB.value > self.limit) or (pointA.value > self.limit and pointB.value < self.limit):
xA, yA, zA = pointA.location
xB, yB, zB = pointB.location
valA = (pointA.value + 1) / 2
valB = (pointB.value + 1) / 2
xC = float(avg([xA, xB]))
yC = float(avg([yA, yB]))
zC = float(avg([zA, zB]))
mp = self.meshPoint()
mp.place(xC, yC, zC)
mp.setShape(self.cube())
mp.shape.config(xC, yC, zC, size = 0.05, solid = True, color = (1, 0, 0))
self.shapes.append(mp.shape)
self.meshPoints.append(mp)
self.currentStep += 1
self.openGLWidget.update()
def zoom(self, value):
self.zoomLevel += value
self.openGLWidget.update()
def rotateV(self, value):
self.rotateDegreeV += value
self.openGLWidget.update()
def rotateH(self, value):
self.rotateDegreeH += value
self.openGLWidget.update()
def filter(self, value):
self.limit = rnd((value / 49.5) -1, -2)
for d in self.dataPoints:
if d.value < self.limit:
d.shape.hide()
else:
d.shape.show()
self.limitDisplay.setText(str(self.limit))
self.openGLWidget.update()
def getDataPointByLocation(self, coord):
x, y, z = coord
for dp in self.dataPoints:
if dp.location == (x, y, z):
return dp
return False
def paintGL(self):
glLoadIdentity()
gluPerspective(45, self.width / self.height, 0.1, 110.0) #set perspective?
glTranslatef(0, 0, self.zoomLevel) #I used -10 instead of -2 in the PyGame version.
glRotatef(self.rotateDegreeV, 1, 0, 0) #I used 2 instead of 1 in the PyGame version.
glRotatef(self.rotateDegreeH, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
if len(self.shapes) != 0:
glBegin(GL_LINES)
for s in self.shapes:
glColor3fv(s.color)
if s.render and not s.solid:
for e in s.edges:
for v in e:
glVertex3fv(s.vertices[v])
glEnd()
glBegin(GL_QUADS)
for s in self.shapes:
glColor3fv(s.color)
if s.render and s.solid:
for f in s.facets:
for v in f:
glVertex3fv(s.vertices[v])
glEnd()
def initData(self, sizeX, sizeY, sizeZ):
marchSizeX = sizeX - 1
marchSizeY = sizeY - 1
marchSizeZ = sizeZ - 1
xOff = -(sizeX / 2) + 0.5
yOff = -(sizeY / 2) + 0.5
zOff = -(sizeZ / 2) + 0.5
xMarchOff = -(marchSizeX / 2) + 0.5
yMarchOff = -(marchSizeY / 2) + 0.5
zMarchOff = -(marchSizeZ / 2) + 0.5
vals = []
self.marchPoints = []
for z in range(marchSizeZ):
for y in range(marchSizeY):
for x in range(marchSizeX):
self.marchPoints.append((x + xMarchOff, y + yMarchOff ,z + zMarchOff))
for z in range(sizeZ):
for y in range(sizeY):
for x in range(sizeX):
loc = len(self.dataPoints)
val = self.generate(x + xOff, y + yOff, z + zOff)
self.dataPoints.append(self.dataPoint())
self.dataPoints[loc].place(x + xOff, y + yOff, z + zOff)
self.dataPoints[loc].set(val)
loc2 = len(self.shapes)
self.shapes.append(self.cube())
self.shapes[loc2].config(x + xOff, y + yOff, z + zOff, solid = True, color = (0, (val + 1) / 2, (val + 1) / -2 + 1))
self.dataPoints[loc].setShape(self.shapes[loc2])
vals.append(val)
print(avg(vals))
def generate(self, xIn, yIn, zIn): #Function which produces semi-random values based on the supplied coordinates.
i = -(xIn * yIn * (10 + zIn))
j = xIn * yIn * (10 + zIn)
if i < j:
mixer = random.randint(i, j)
else:
mixer = random.randint(j, i + 1)
a = avg([sin(cos(xIn)), tan(tan(yIn)), cos(tan(zIn))])
out = mixer * a
while out > 10:
out -= 5
while out < -10:
out += 5
return float(out / 10)
app = QApplication([])
window = mainWindow()
window.setupUI()
window.show()
sys.exit(app.exec_())
Why doesn't the cube disappear? I have caught wind during my web searches on the subject that update does not always work as expected. Directly calling self.openGLWidget.paintGL() does not work either. What must I do to make the cube disappear?
EDIT:
If I make a call to rotate, rotate, or zoom, the screen refreshes and the meshpoints as well as the marching cube all disappear. I think I may end up making a workaround by calling one of those with a zero value.
To test, save the following code in a file named numerics.py in the same directory as the rest of the code.
from decimal import Decimal as dec
degrad = 'deg'
pi = 3.14159265358979323846
terms = dec(9) #number of terms used for the trig calculations
def version():
print('numerics.py version 1.0.0')
print('Packaged with the cubes project')
def mode(modeinput = ''): #switch between degrees and radians or check the current mode
global degrad
if modeinput == 'deg':
degrad = 'deg'
return 'deg'
if modeinput == 'rad':
degrad = 'rad'
return 'rad'
if modeinput == '':
return degrad
else:
return False
def accuracy(accinput = ''):
global terms
global pi
if accinput == '':
return terms
terms = dec(accinput)
PI = calculatePi(accinput)
print('Pi is: {}'.format(PI))
return terms
def calculatePi(placeIn = terms):
if placeIn > 15:
if input("Warning: You have chosen to calculate more than 20 digits of pi. This may take a LONG TIME and may be inacurate. Enter 'yes' if you wish to proceed. If you enter anything else, this function will revert to 10 digits.") == 'yes':
place = placeIn
else:
place = 10
else:
place = placeIn
print('Calculating Pi...\nPlease wait, as this may take a while.')
PI = dec(3)
addSub = True
for i in range(2, 2 * (int(place) ** 6) + 1, 2):
if addSub:
PI += dec(4) / (dec(i) * dec(i + 1) * dec(i + 2))
elif not addSub:
PI -= dec(4) / (dec(i) * dec(i + 1) * dec(i + 2))
addSub = not addSub
return rnd(PI, -(place), mode = 'cutoff')
def radToDeg(radin):
return (dec(radin) * dec(180 / pi))
def degToRad(degin):
return (dec(degin) * dec(pi / 180))
def avg(numsIn): #return the average of two numbers, specified as an integer or float
num1 = dec(0)
for i in numsIn:
num1 += dec(i)
return rnd(dec(num1 / dec(len(numsIn))))
def sin(anglein, dr = degrad): #return sine of the supplied angle using the predetermined mode or the supplied mode
if dr == 'deg':
while anglein > 180:
anglein -= 360
while anglein < -180:
anglein += 360
angle = degToRad(anglein)
if dr == 'rad':
while anglein > pi:
anglein -= (2 * pi)
while anglein < -pi:
anglein += (2 * pi)
angle = anglein
return rnd(rawsin(dec(angle)), -terms)
def arcsin(ratioin, dr = degrad): #return arcsine of the supplied ratio using the predetermined mode or the supplied mode
if ratioin > 1 or ratioin < -1: #if the input is illegal
return False
attempt = dec(0) #start at 0
target = rnd(dec(ratioin), -terms) #identify the target value
#print('target is: {}'.format(target))
for i in range(-1, int(terms) + 1): #for each place from 10s to terms decimal place (use -i, not i)
#print('Editing place {0}'.format(10 ** -i)) #debugging
for j in range(10): #for 10 steps
#print('current attempt: {}'.format(attempt), end = ' ')
if rnd(sin(attempt, dr), -terms) == target:
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return final
if rnd(sin(attempt, dr), -terms) < target:
#add some
attempt += (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
if rnd(sin(attempt, dr), -terms) > target:
#subtract some
attempt -= (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
#print('')
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return (final)
def cos(anglein, dr = degrad): #return cosine of the supplied angle
if dr == 'deg':
return rawsin(degToRad(90 - anglein))
else:
angle = anglein
return rnd(rawsin(90 - angle), -terms)
def arccos(ratioin, dr = degrad): #return arccosine of the supplied ratio
if ratioin > 1 or ratioin < -1:
return False
attempt = dec(0) #start at 0
target = rnd(dec(ratioin), -terms) #identify the target value
#print('target is: {}'.format(target))
for i in range(-1, int(terms) + 1): #for each place from 10s to terms decimal place (use -i, not i)
#print('Editing place {0}'.format(10 ** -i)) #debugging
for j in range(10): #for 10 steps
#print('current attempt: {}'.format(attempt), end = ' ')
if rnd(cos(attempt, dr), -terms) == target:
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return final
if rnd(cos(attempt, dr), -terms) < target:
#add some
attempt += (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
if rnd(cos(attempt, dr), -terms) > target:
#subtract some
attempt -= (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
#print('')
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return (final)
def tan(anglein, dr = degrad): #return tangent of the supplied angle
a = sin(anglein, dr)
b = cos(anglein, dr)
if (not a == 0) and (not b == 0):
return rnd((a / b), -terms)
else:
return False
def arctan(ratioin, dr = degrad): #return arctangent of the supplied ratio
if ratioin > 1 or ratioin < -1:
return False
attempt = dec(0) #start at 0
target = rnd(dec(ratioin), -terms) #identify the target value
#print('target is: {}'.format(target))
for i in range(-1, int(terms) + 1): #for each place from 10s to terms decimal place (use -i, not i)
#print('Editing place {0}'.format(10 ** -i)) #debugging
for j in range(10): #for 10 steps
#print('current attempt: {}'.format(attempt), end = ' ')
if rnd(tan(attempt, dr), -terms) == target:
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return final
if rnd(tan(attempt, dr), -terms) < target:
#add some
attempt += (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
if rnd(tan(attempt, dr), -terms) > target:
#subtract some
attempt -= (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
#print('')
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return (final)
def rawsin(anglein): #return the result of sine of the supplied angle, using radians
#This is the taylor series used.
#final = x - (x^3 / 3!) + (x^5 / 5!) - (x^7 / 7!) + (x^9 / 9!) - (x^11 / 11!)...
angle = dec(anglein)
final = angle
add = False
for i in range(3, int(terms) * 3, 2):
if add:
final += dec(angle ** i) / fact(i)
elif not add:
final -= dec(angle ** i) / fact(i)
add = not add
return final
def fact(intin): #return the factorial of the given integer, return False if not given an int
if intin == int(intin):
intout = 1
for i in range(1, intin + 1):
intout *= i
return intout
else:
return False
def rnd(numIn, decPlcIn = -terms, mode = 'fiveHigher'): #return the given number, rounded to the given decimal place.
#use 1 to indicate 10s, 0 to indicate 1s, -2 to indicate 100ths, etc.
num1 = dec(numIn)
decPlc = dec(decPlcIn)
if mode == 'fiveHigher':
return dec(str(dec(round(num1 * (dec(10) ** -decPlc))) * (dec(10) ** decPlc)).rstrip('0'))
elif mode == 'cutoff':
return dec(str(dec(int(num1 * (dec(10) ** -decPlc))) * (dec(10) ** decPlc)).rstrip('0'))
def root(numIn, rootVal):
num = dec(numIn)
rt = dec(dec(1) / rootVal)
num1 = num ** rt
return rnd(num1, -terms)
def quad(aIn, bIn, cIn): #Plugin for the quadratic formula. Provide a, b, and c.
a = dec(aIn)
b = dec(bIn)
c = dec(cIn)
try:
posResult = (-b + root((b ** dec(2)) - (dec(4) * a * c), 2)) / (dec(2) * a)
except:
posResult = False
try:
negResult = (-b - root((b ** dec(2)) - (dec(4) * a * c), 2)) / (dec(2) * a)
except:
negResult = False
return (posResult, negResult)
You are missing 1 call to self.openGLWidget.update(). There is a return statement in the instruction block of the if. The function is terminated at this point and the self.openGLWidget.update() instruction at the end of the code is never executed.
Add self.openGLWidget.update() right before return, to solve the issue:
class mainWindow(QMainWindow):
# [...]
def marchStep(self):
if not self.marchActive:
# [...]
self.currentStep = 0
if self.currentStep == len(self.marchPoints):
# [...]
self.meshPoints.clear()
self.marchingCube.hide()
self.openGLWidget.update() # <--------- ADD
return
if self.currentStep == 0:
self.marchingCube.show()
# [...]

How to pretty print a quadtree in python?

I have some code that can make a quad tree from data points. I know how to print out binary tree with slashes, but I don't even know where to start to print/draw out a tree with 4 children instead of 2 each to be able to visualize my tree.
I've been testing it by using my search_pqtreee function. For example, to list all the points in the northeast quadrant, I can test it by making a list like: [search_pqtree(q.ne,p) for p in points]
#The point import is a class for points in Cartesian coordinate systems
from point import *
class PQuadTreeNode():
def __init__(self,point,nw=None,ne=None,se=None,sw=None):
self.point = point
self.nw = nw
self.ne = ne
self.se = se
self.sw = sw
def __repr__(self):
return str(self.point)
def is_leaf(self):
return self.nw==None and self.ne==None and \
self.se==None and self.sw==None
def search_pqtree(q, p, is_find_only=True):
if q is None:
return
if q.point == p:
if is_find_only:
return q
else:
return
dx,dy = 0,0
if p.x >= q.point.x:
dx = 1
if p.y >= q.point.y:
dy = 1
qnum = dx+dy*2
child = [q.sw, q.se, q.nw, q.ne][qnum]
if child is None and not is_find_only:
return q
return search_pqtree(child, p, is_find_only)
def insert_pqtree(q, p):
n = search_pqtree(q, p, False)
node = PQuadTreeNode(point=p)
if p.x < n.point.x and p.y < n.point.y:
n.sw = node
elif p.x < n.point.x and p.y >= n.point.y:
n.nw = node
elif p.x >= n.point.x and p.y < n.point.y:
n.se = node
else:
n.ne = node
def pointquadtree(data):
root = PQuadTreeNode(point = data[0])
for p in data[1:]:
insert_pqtree(root, p)
return root
#Test
data1 = [ (2,2), (0,5), (8,0), (9,8), (7,14), (13,12), (14,13) ]
points = [Point(d[0], d[1]) for d in data1]
q = pointquadtree(points)
print([search_pqtree(q.ne, p) for p in points])
What I'm trying to say is if I was pretty printing a binary tree, it might look like this:
(2, 2)
/ \
(0, 5) (8, 0)
/ \ / \
Is there a way to write a function that print out 4 lines each? Or maybe print it out sideways?
As you classified your question with GIS and spatial, this problem made me think of a map with north-east, north-west, south-east and south-west in each corner.
A single node quadtree would simply be :
(0,0)
A two node quadtree would be :
.|( 1, 1)
----( 0, 0)----
.|.
With 3 nodes in depth that would go to :
| .|( 2, 2)
|----( 1, 1)----
.| .|.
------------( 0, 0)------------
.|.
|
|
I've implemented this idea, with some changes to your code to make it easier:
I've added a trivial point class, with the __repr__ method I needed for number formatting
I made quadrants into a dictionary to be able to loop on them
I thought I would need the get_depth method, but it's not used...
I also think that search and insert functions should be methods of the class PQuadTreeNode, but I leave it to you as an exercise :)
The implementation works with the following steps:
If the quadtree is a leaf, its map is the central point
Get the maps of the 4 quadrants (if empty, it's a dot)
Normalize them using the size of the largest, and puts them near the center of the parent
Combine the 4 quadrants with the quadtree point at the center.
This is of course higly recursive, and I didn't made any attempt at optimization.
If numbers have a length greater than 2 (like 100 or -10), you can adjust the num_length variable.
num_length = 2
num_fmt = '%' + str(num_length) + 'd'
class Point():
def __init__(self,x=None,y=None):
self.x = x
self.y = y
def __repr__(self):
return '(' + (num_fmt % self.x) + ',' + (num_fmt % self.y) + ')'
def normalize(corner, quadmap, width, height):
old_height = len(quadmap)
old_width = len(quadmap[0])
if old_height == height and old_width == width:
return quadmap
else:
blank_width = width - old_width
if corner == 'nw':
new = [' '*width for i in range(height - old_height)]
for line in quadmap:
new.append(' '*blank_width + line)
elif corner == 'ne':
new = [' '*width for i in range(height - old_height)]
for line in quadmap:
new.append(line + ' '*blank_width)
elif corner == 'sw':
new = []
for line in quadmap:
new.append(' '*blank_width + line)
for i in range(height - old_height):
new.append(' '*width)
elif corner == 'se':
new = []
for line in quadmap:
new.append(line + ' '*blank_width)
for i in range(height - old_height):
new.append(' '*width)
return new
class PQuadTreeNode():
def __init__(self,point,nw=None,ne=None,se=None,sw=None):
self.point = point
self.quadrants = {'nw':nw, 'ne':ne, 'se':se, 'sw':sw}
def __repr__(self):
return '\n'.join(self.get_map())
def is_leaf(self):
return all(q == None for q in self.quadrants.values())
def get_depth(self):
if self.is_leaf():
return 1
else:
return 1 + max(q.get_depth() if q else 0 for q in self.quadrants.values())
def get_map(self):
if self.is_leaf():
return [str(self.point)]
else:
subquadmaps = {
sqn:sq.get_map() if sq else ['.']
for sqn, sq
in self.quadrants.items()
}
subheight = max(len(map) for map in subquadmaps.values())
subwidth = max(len(mapline) for map in subquadmaps.values() for mapline in map)
subquadmapsnorm = {
sqn:normalize(sqn, sq, subwidth, subheight)
for sqn, sq
in subquadmaps.items()
}
map = []
for n in range(subheight):
map.append(subquadmapsnorm['nw'][n] + '|' + subquadmapsnorm['ne'][n])
map.append('-' * (subwidth-num_length-1) + str(self.point) + '-' * (subwidth-num_length-1))
for n in range(subheight):
map.append(subquadmapsnorm['sw'][n] + '|' + subquadmapsnorm['se'][n])
return map
def search_pqtree(q, p, is_find_only=True):
if q is None:
return
if q.point == p:
if is_find_only:
return q
else:
return
dx,dy = 0,0
if p.x >= q.point.x:
dx = 1
if p.y >= q.point.y:
dy = 1
qnum = dx+dy*2
child = [q.quadrants['sw'], q.quadrants['se'], q.quadrants['nw'], q.quadrants['ne']][qnum]
if child is None and not is_find_only:
return q
return search_pqtree(child, p, is_find_only)
def insert_pqtree(q, p):
n = search_pqtree(q, p, False)
node = PQuadTreeNode(point=p)
if p.x < n.point.x and p.y < n.point.y:
n.quadrants['sw'] = node
elif p.x < n.point.x and p.y >= n.point.y:
n.quadrants['nw'] = node
elif p.x >= n.point.x and p.y < n.point.y:
n.quadrants['se'] = node
else:
n.quadrants['ne'] = node
def pointquadtree(data):
root = PQuadTreeNode(point = data[0])
for p in data[1:]:
insert_pqtree(root, p)
return root
#Test
data1 = [ (2,2), (0,5), (8,0), (9,8), (7,14), (13,12), (14,13) ]
points = [Point(d[0], d[1]) for d in data1]
q = pointquadtree(points)
print(q)
With your example data:
| | .|(14,13)
| |----(13,12)----
| ( 7,14)| .|.
|------------( 9, 8)------------
| .|.
| |
( 0, 5)| |
----------------------------( 2, 2)----------------------------
.|( 8, 0)
|
|
|
|
|
|
Tell me if you find it useful !

Too many values to unpack with python

I have a little problem with Python.
I'm try to write an application for DCM standard who some slice and draw the final model.
This is my code:
from lar import *
from scipy import *
import scipy
import numpy as np
from time import time
from pngstack2array3d import pngstack2array3d
colors = 2
theColors = []
DEBUG = False
MAX_CHAINS = colors
# It is VERY important that the below parameter values
# correspond exactly to each other !!
# ------------------------------------------------------------
MAX_CHUNKS = 75
imageHeight, imageWidth = 250,250 # Dx, Dy
# configuration parameters
# ------------------------------------------------------------
beginImageStack = 430
endImage = beginImageStack
nx = ny = 50
imageDx = imageDy = 50
count = 0
# ------------------------------------------------------------
# Utility toolbox
# ------------------------------------------------------------
def ind(x,y): return x + (nx+1) * (y + (ny+1) )
def invertIndex(nx,ny):
nx,ny = nx+1,ny+1
def invertIndex0(offset):
a0, b0 = offset / nx, offset % nx
a1, b1 = a0 / ny, a0 % ny
return b0,b1
return invertIndex0
def invertPiece(nx,ny):
def invertIndex0(offset):
a0, b0 = offset / nx, offset % nx
a1, b1 = a0 / ny, a0 % ny
return b0,b1
return invertIndex0
# ------------------------------------------------------------
# computation of d-chain generators (d-cells)
# ------------------------------------------------------------
# cubic cell complex
# ------------------------------------------------------------
def the3Dcell(coords):
x,y= coords
return [ind(x,y),ind(x+1,y),ind(x,y+1),ind(x+1,y+1)]
# construction of vertex coordinates (nx * ny )
# ------------------------------------------------------------
V = [[x,y] for y in range(ny+1) for x in range(nx+1) ]
if __name__=="__main__" and DEBUG == True:
print "\nV =", V
# construction of CV relation (nx * ny)
# ------------------------------------------------------------
CV = [the3Dcell([x,y]) for y in range(ny) for x in range(nx)]
if __name__=="__main__" and DEBUG == True:
print "\nCV =", CV
#hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,CV[:500]+CV[-500:])))
#box = SKELETON(1)(BOX([1,2,3])(hpc))
#VIEW(STRUCT([box,hpc]))
# construction of FV relation (nx * ny )
# ------------------------------------------------------------
FV = []
v2coords = invertIndex(nx,ny)
for h in range(len(V)):
x,y= v2coords(h)
if (x < nx) and (y < ny): FV.append([h,ind(x+1,y),ind(x,y+1),ind(x+1,y+1)])
if __name__=="__main__" and DEBUG == True:
print "\nFV =",FV
#hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,FV[:500]+FV[-500:])))
#box = SKELETON(1)(BOX([1,2,3])(hpc))
#VIEW(STRUCT([box,hpc]))
# construction of EV relation (nx * ny )
# ------------------------------------------------------------
EV = []
v2coords = invertIndex(nx,ny)
for h in range(len(V)):
x,y = v2coords(h)
if x < nx: EV.append([h,ind(x+1,y)])
if y < ny: EV.append([h,ind(x,y+1)])
if __name__=="__main__" and DEBUG == True:
print "\nEV =",EV
#hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,EV[:500]+EV[-500:])))
#box = SKELETON(1)(BOX([1,2,3])(hpc))
#VIEW(STRUCT([box,hpc]))
# ------------------------------------------------------------
# computation of boundary operators (∂3 and ∂2s)
# ------------------------------------------------------------
"""
# computation of the 2D boundary complex of the image space
# ------------------------------------------------------------
Fx0V, Ex0V = [],[] # x == 0
Fx1V, Ex1V = [],[] # x == nx-1
Fy0V, Ey0V = [],[] # y == 0
Fy1V, Ey1V = [],[] # y == ny-1
v2coords = invertIndex(nx,ny)
for h in range(len(V)):
x,y = v2coords(h)
if (y == 0):
if x < nx: Ey0V.append([h,ind(x+1,y)])
if (x < nx):
Fy0V.append([h,ind(x+1,y),ind(x,y)])
elif (y == ny):
if x < nx: Ey1V.append([h,ind(x+1,y)])
if (x < nx):
Fy1V.append([h,ind(x+1,y),ind(x,y)])
if (x == 0):
if y < ny: Ex0V.append([h,ind(x,y+1)])
if (y < ny):
Fx0V.append([h,ind(x,y+1),ind(x,y)])
elif (x == nx):
if y < ny: Ex1V.append([h,ind(x,y+1)])
if (y < ny):
Fx1V.append([h,ind(x,y+1),ind(x,y)])
FbV = Fy0V+Fy1V+Fx0V+Fx1V
EbV = Ey0V+Ey1V+Ex0V+Ex1V
"""
"""
if __name__=="__main__" and DEBUG == True:
hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,FbV)))
VIEW(hpc)
hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,EbV)))
VIEW(hpc)
"""
# computation of the ∂2 operator on the boundary space
# ------------------------------------------------------------
print "start partial_2_b computation"
#partial_2_b = larBoundary(EbV,FbV)
print "end partial_2_b computation"
# computation of ∂3 operator on the image space
# ------------------------------------------------------------
print "start partial_3 computation"
partial_3 = larBoundary(FV,CV)
print "end partial_3 computation"
# ------------------------------------------------------------
# input from volume image (test: 250 x 250 x 250)
# ------------------------------------------------------------
out = []
Nx,Ny = imageHeight/imageDx, imageWidth/imageDx
segFaces = set(["Fy0V","Fy1V","Fx0V","Fx1V"])
for inputIteration in range(imageWidth/imageDx):
startImage = endImage
endImage = startImage + imageDy
xEnd, yEnd = 0,0
theImage,colors,theColors = pngstack2array3d('SLICES2/', startImage, endImage, colors)
print "\ntheColors =",theColors
theColors = theColors.reshape(1,2)
background = max(theColors[0])
foreground = min(theColors[0])
print "\n(background,foreground) =",(background,foreground)
if __name__=="__main__" and DEBUG == True:
print "\nstartImage, endImage =", (startImage, endImage)
for i in range(imageHeight/imageDx):
for j in range(imageWidth/imageDy):
xStart, yStart = i * imageDx, j * imageDy
xEnd, yEnd = xStart+imageDx, yStart+imageDy
image = theImage[:, xStart:xEnd, yStart:yEnd]
nx,ny = image.shape
if __name__=="__main__" and DEBUG == True:
print "\n\tsubimage count =",count
print "\txStart, yStart =", (xStart, yStart)
print "\txEnd, yEnd =", (xEnd, yEnd)
print "\timage.shape",image.shape
# ------------------------------------------------------------
# image elaboration (chunck: 50 x 50)
# ------------------------------------------------------------
"""
# Computation of (local) boundary to be removed by pieces
# ------------------------------------------------------------
if pieceCoords[0] == 0: boundaryPlanes += ["Fx0V"]
elif pieceCoords[0] == Nx-1: boundaryPlanes += ["Fx1V"]
if pieceCoords[1] == 0: boundaryPlanes += ["Fy0V"]
elif pieceCoords[1] == Ny-1: boundaryPlanes += ["Fy1V"]
"""
#if __name__=="__main__" and DEBUG == True:
#planesToRemove = list(segFaces.difference(boundaryPlanes))
#FVtoRemove = CAT(map(eval,planesToRemove))
count += 1
# compute a quotient complex of chains with constant field
# ------------------------------------------------------------
chains2D = [[] for k in range(colors)]
def addr(x,y): return x + (nx) * (y + (ny))
for x in range(nx):
for y in range(ny):
if (image[x,y] == background):
chains2D[1].append(addr(x,y))
else:
chains2D[0].append(addr(x,y))
#if __name__=="__main__" and DEBUG == True:
#print "\nchains3D =\n", chains3D
# compute the boundary complex of the quotient cell
# ------------------------------------------------------------
objectBoundaryChain = larBoundaryChain(partial_3,chains2D[1])
b2cells = csrChainToCellList(objectBoundaryChain)
sup_cell_boundary = MKPOLS((V,[FV[f] for f in b2cells]))
# remove the (local) boundary (shared with the piece boundary) from the quotient cell
# ------------------------------------------------------------
"""
cellIntersection = matrixProduct(csrCreate([FV[f] for f in b2cells]),csrCreate(FVtoRemove).T)
#print "\ncellIntersection =", cellIntersection
cooCellInt = cellIntersection.tocoo()
b2cells = [cooCellInt.row[k] for k,val in enumerate(cooCellInt.data) if val >= 4]
"""
# ------------------------------------------------------------
# visualize the generated model
# ------------------------------------------------------------
print "xStart, yStart =", xStart, yStart
if __name__=="__main__":
sup_cell_boundary = MKPOLS((V,[FV[f] for f in b2cells]))
if sup_cell_boundary != []:
out += [T([1,2])([xStart,yStart]) (STRUCT(sup_cell_boundary))]
if count == MAX_CHUNKS:
VIEW(STRUCT(out))
# ------------------------------------------------------------
# interrupt the cycle of image elaboration
# ------------------------------------------------------------
if count == MAX_CHUNKS: break
if count == MAX_CHUNKS: break
if count == MAX_CHUNKS: break
And this is the error take from the terminal :
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-4-2e498c6090a0> in <module>()
213
214 image = theImage[:, xStart:xEnd, yStart:yEnd]
--> 215 nx,ny = image.shape
216
217 if __name__=="__main__" and DEBUG == True:
ValueError: too many values to unpack
Someone can help me to solve this issue????
Based on the line:
image = theImage[:, xStart:xEnd, yStart:yEnd]
image is a 3d array, not a 2d array (it appears to be multiple slices of an image), with the 2nd and 3rd dimensions representing x and y respectively. Thus, if you want to get its dimensions you'll need to unpack it into three dimensions, something like:
nslice, nx, ny = image.shape

Categories