SymPy's nullspace struggling when Mathematica succeeds with ease - python

I have been trying to find the nullspace of a symbolic matrix A in SymPy using the command A.nullspace. Now the computation does not finish (or takes longer than I waited for) for the matrix I entered.
The strange thing is that Mathematica does this computation within a fraction of a second. I'll give the specific example I am using as Mathematica input code (should run)
L = ({{0, -I a Sqrt[b] Conjugate[g] Conjugate[w], 0, I a Sqrt[b] g w,
2 g2 + 2 b g z Conjugate[g], 0, 0, 0,
2 g2}, {-I a Sqrt[b] g w, -g2 - b g z Conjugate[g] -
I (-dD + b d g Conjugate[g]), -I DD, 0, I a Sqrt[b] g w, 0, 0,
0, 0}, {0, -I DD, I dD - g2, 0, 0, I a Sqrt[b] g w, 0, 0,
0}, {I a Sqrt[b] Conjugate[g] Conjugate[w], 0,
0, -g2 - b g z Conjugate[g] -
I (dD - b d g Conjugate[g]), -I a Sqrt[b] Conjugate[
g] Conjugate[w], 0, I DD, 0, 0}, {0,
I a Sqrt[b] Conjugate[g] Conjugate[w],
0, -I a Sqrt[b] g w, -2 g2 - 2 b g z Conjugate[g], -I DD, 0,
I DD, 0}, {0, 0, I a Sqrt[b] Conjugate[g] Conjugate[w],
0, -I DD, -2 g2 + I b d g Conjugate[g] - b g z Conjugate[g], 0,
0, I DD}, {0, 0, 0, I DD, 0,
0, -I dD - g2, -I a Sqrt[b] Conjugate[g] Conjugate[w], 0}, {0, 0,
0, 0, I DD,
0, -I a Sqrt[b] g w, -2 g2 - I b d g Conjugate[g] -
b g z Conjugate[g], -I DD}, {0, 0, 0, 0, 0, I DD,
0, -I DD, -2 g2}});
MatrixForm[L]
NullSpace[L]
As said for the same matrix SymPy is struggling. Is there any reason for this? Is there any other way to solve this problem in python?
Here is my SymPy code:
import numpy as np
import scipy
import sympy as sp
a = sp.symbols("a", real=True, positive=True)
b = sp.symbols("b", real=True, positive=True)
g = sp.symbols("g", real=True, positive=True)
g2 = sp.symbols("g2", real=True, positive=True)
DD = sp.symbols("DD", real=True, positive=True)
dD = sp.symbols("dD", real=True)
w = sp.symbols("w")
z = sp.symbols("z")
d = sp.symbols("d")
L = sp.Matrix([[0, -1j*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w), 0, 1j*a*sp.sqrt(b)*g*w,
2*g2 + 2*b*g*z*sp.conjugate(g), 0, 0, 0,
2*g2], [-1j*a*sp.sqrt(b)*g*w, -g2 - b*g*z*sp.conjugate(g) -
1j*(-dD + b*d*g*sp.conjugate(g)), -1j*DD, 0, 1j*a*sp.sqrt(b)*g*w, 0, 0,
0, 0], [0, -1j*DD, 1j*dD - g2, 0, 0, 1j*a*sp.sqrt(b)*g*w, 0, 0,
0], [1j*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w), 0,
0, -g2 - b*g*z*sp.conjugate(g) -
1j*(dD - b*d*g*sp.conjugate(g)), -1j*a*sp.sqrt(b)*sp.conjugate(
g)*sp.conjugate(w), 0, 1j*DD, 0, 0], [0,
1j*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w),
0, -1j*a*sp.sqrt(b)*g*w, -2*g2 - 2*b*g*z*sp.conjugate(g), -1j*DD, 0,
1j*DD, 0], [0, 0, 1j*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w),
0, -1j*DD, -2*g2 + 1j*b*d*g*sp.conjugate(g) - b*g*z*sp.conjugate(g), 0,
0, 1j*DD], [0, 0, 0, 1j*DD, 0,
0, -1j*dD - g2, -1j*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w), 0], [0, 0,
0, 0, 1j*DD,
0, -1j*a*sp.sqrt(b)*g*w, -2*g2 - 1j*b*d*g*sp.conjugate(g) -
b*g*z*sp.conjugate(g), -1j*DD], [0, 0, 0, 0, 0, 1j*DD,
0, -1j*DD, -2*g2]]);
sp.pprint(L)
sp.pprint(L.nullspace())
According to a comment, the following inforamtion may be relevant too:
Real, positive parameters: a, b, g, g2, DD
Real parameters: dD
Complex parameters: w, z, d

The imaginary unit in sympy is sympy.I (not 1j). Apparently, 1j is acceptable by sympy, however, it is interpreted as a numercal quantity, which should be avoided in symbolic computations.
The following code gives the nullspace fairly quick. Note that I have also provided symbol attributes. These usually help sympy provide faster answers
a = sp.symbols("a", positive = True)
b = sp.symbols("b", positive = True)
g = sp.symbols("g", positive = True)
w = sp.symbols("w")
z = sp.symbols("z")
g2 = sp.symbols("g2", positive = True)
DD = sp.symbols("DD", positive = True)
dD = sp.symbols("dD", real = True)
d = sp.symbols("d")
L = sp.Matrix([[0, -sp.I*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w), 0, sp.I*a*sp.sqrt(b)*g*w,
2*g2 + 2*b*g*z*sp.conjugate(g), 0, 0, 0,
2*g2], [-sp.I*a*sp.sqrt(b)*g*w, -g2 - b*g*z*sp.conjugate(g) -
sp.I*(-dD + b*d*g*sp.conjugate(g)), -sp.I*DD, 0, sp.I*a*sp.sqrt(b)*g*w, 0, 0,
0, 0], [0, -sp.I*DD, sp.I*dD - g2, 0, 0, sp.I*a*sp.sqrt(b)*g*w, 0, 0,
0], [sp.I*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w), 0,
0, -g2 - b*g*z*sp.conjugate(g) -
sp.I*(dD - b*d*g*sp.conjugate(g)), -sp.I*a*sp.sqrt(b)*sp.conjugate(
g)*sp.conjugate(w), 0, sp.I*DD, 0, 0], [0,
sp.I*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w),
0, -sp.I*a*sp.sqrt(b)*g*w, -2*g2 - 2*b*g*z*sp.conjugate(g), -sp.I*DD, 0,
sp.I*DD, 0], [0, 0, sp.I*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w),
0, -sp.I*DD, -2*g2 + sp.I*b*d*g*sp.conjugate(g) - b*g*z*sp.conjugate(g), 0,
0, sp.I*DD], [0, 0, 0, sp.I*DD, 0,
0, -sp.I*dD - g2, -sp.I*a*sp.sqrt(b)*sp.conjugate(g)*sp.conjugate(w), 0], [0, 0,
0, 0, sp.I*DD,
0, -sp.I*a*sp.sqrt(b)*g*w, -2*g2 - sp.I*b*d*g*sp.conjugate(g) -
b*g*z*sp.conjugate(g), -sp.I*DD], [0, 0, 0, 0, 0, sp.I*DD,
0, -sp.I*DD, -2*g2]]);
Ln = L.nullspace()

Related

Python Matrix check for diagonals and horizontals correctly to win a game

I'm building a game like Connect4 the user can connect any number. I am having a problem checking the horizontal and diagonals lines:
def WinningSequenceCheck(board,piece,row_count):
#Horizontal Check
piecePlayer1=0
piecePlayer2=0
win_sequence=board[0]["TamanhoSequĂȘncia"]
width=board[0]["CumpGrelha"]
height=row_count
for c in range(height+1):
for r in range(width):
if board[0]["Tabuleiro"][c][r]==1:
piecePlayer1+=1
if piecePlayer1==win_sequence:
return True
if board[0]["Tabuleiro"][c][r]==2:
pecasPlayer2+=1
if pecasPlayer2==win_sequence:
return True
#For diagonals i did this:
diag1=0
diag2=0
a=0
b=height
d=0
for c in range(width):
for l in range(height+1):
if board[0]["Tabuleiro"][b-l][l+a]==1:
diag1+=1
if diag1==win_sequence:
return True
if board[0]["Tabuleiro"][b-l][l+a]==2:
diag2+=1
if diag2==win_sequence:
return True
if (b-l<height):
b=height
if l<=l-1:
a=a
elif(a+l<width-1):
a+=1
elif(a+l<=width-1):
return
else:
break
The problem with diagonals is that it goes from left to right but it's not checking properly if there is a line of a winning sequence of 1s or 2s
If it finds it should return true because im incrementing each time he finds 1 or 2
Im i doing the horizontal check properly?
Is there a better way to check in diagonals ?
The expected result from the horizontal is that if it finds the number 1 it adds to the variable piecePlayer1 (for the player 1)
If the piecePlayer1 is equal to Victory sequence ( example victory sequence is 5) the game returns true because in one of the lines he found 5 one's .
Winning Sequence=5
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0] ---> Win
The same is for the diagonal check:
Winning Sequence =4
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0] Diagonal WIN
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
#Stunna, here is simple sample code to check the diagonal values, you can try it and modify to suit your main module:
def winner(board, length):
"""Returns the 'mark' of the winning player"""
W = range(len(board)) # width
H = range(len(board[0])) # height
directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
for dx, dy in directions:
edges = []
if dx > 0:
edges += [(0, y) for y in H]
if dy > 0: # scanning down
edges += [(x, 0) for x in W]
if dy < 0: # scanning up
edges += [(x, H[-1]) for x in W]
for ex, ey in edges:
row = 0; mark = None
x, y = ex, ey
while x in W and y in H:
if board[x][y] == mark:
row += 1
else:
mark = board[x][y]
row = 1
if mark is not None and row >= length:
return mark
x, y = x + dx, y + dy
return None
print(winner([
['X', 'O', 'O', 'O'],
['O', 'X', 'O', 'X'],
['O', 'O', 'X', 'O'],
['O', 'X', 'X', 'X'] ], 4)) # X

Python networkx edge and node labeling problem

I'm new to Python and I wanted to draw a incidence graph, but with changed labels. I want them to start labeling nodes from '1', not from '0'. Also I want to label edges like this: if It's between node '1' and '2', label It as '12' or '1:2'. Thanks in advance :)
im = np.array([[1, 1, 0, 0, 0, 0], [1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 1, 0], [0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 1]])
am = (np.dot(im, im.T) > 0).astype(int)
np.fill_diagonal(am, 0)
K = nx.from_numpy_matrix(am)
pos = nx.spring_layout(K)
print(pos)
x=1
nx.relabel_nodes(K, lambda x: x + + 1)
nx.draw(K, pos, with_labels=True)
edge_labels = dict(((u, v), d) for u, v, d in K.edges(data=True))
nx.draw_networkx_edge_labels(K, pos, edge_labels = edge_labels, label_pos=0.5)
plt.show()
Then build the label you want, just as you've done so far. I'll break this down to basic opeartions; you can build it up again as you wish:
edge_labels = dict(((u, v),
str(u+1) +":"+ str(v+1) +" "+ str(d))
for u, v, d in K.edges(data=True))

Python: Boundary points of a non-convex grid

I have the following situation as shown in the Figure below:
I want to find out the grid points that surround the red points. The red points are trajectories of moving agents. So in many situations we have a bunch of points, therefore the solution should be as fast as possible.
The grid is plotted as points.
First step, I managed to reduce the number of grid points as shown below (plotted as x):
This is my code:
step = .5
gridX, gridY = np.meshgrid(np.arange(xmin-step, xmax+step, step), np.arange(ymin-step, ymax+step, step))
mask = False * np.empty_like(gridX, dtype=bool)
threshold = 0.5
for (x,y) in zip(df_traj['X'], df_traj['Y']):
pX = x * np.ones_like(gridX)
pY = y * np.ones_like(gridY)
distX = (pX - gridX)**2
distY = (pY - gridY)**2
dist = np.sqrt(distX + distY)
condition = (dist < threshold)
mask = mask | condition
gX = gridX*mask
gY = gridY*mask
Second step, and this is where I need a little help:
How can I efficiently filter out the inner points of the grid and keep only the "x-points" outside the "red area"?
EDIT
In this special case I have 92450 red points.
I think if you just walk around the edge, since its a evenly spaced grid, it should work. No need for far more complicated non-convex-hull to handle pnts that can be anywhere. This isn't adapted to your code and I cheat with my data structures to make the code easy so youll have to handle that but it think as psuedocode it should work.
pnts = <<lists of points>>
edge_pnts = []
fpnt = pnt_with_min_x_then_min_y
cpnt = fpnt
npnt = None
while npnt != fpnt:
if (cpnt[0] + 1, cpnt[1] ) in pnts: npnt = (cpnt[0] + 1, cpnt[1] )
elif (cpnt[0] + 1, cpnt[1] + 1) in pnts: npnt = (cpnt[0] + 1, cpnt[1] + 1)
elif (cpnt[0], cpnt[1] + 1) in pnts: npnt = (cpnt[0] , cpnt[1] + 1)
elif (cpnt[0] - 1, cpnt[1] + 1) in pnts: npnt = (cpnt[0] - 1, cpnt[1] + 1)
elif (cpnt[0] - 1, cpnt[1] ) in pnts: npnt = (cpnt[0] - 1, cpnt[1] )
elif (cpnt[0] - 1, cpnt[1] - 1) in pnts: npnt = (cpnt[0] - 1, cpnt[1] - 1)
elif (cpnt[0] , cpnt[1] - 1) in pnts: npnt = (cpnt[0] , cpnt[1] - 1)
elif (cpnt[0] + 1, cpnt[1] - 1) in pnts: npnt = (cpnt[0] + 1, cpnt[1] - 1)
else: raise ValueError("Oh no!")
edge_pnts.append(npnt)
cpnt = npnt
For non convex polygons, like your example, convex hull is not a solution. My recommendation is that, given you already have a discrete grid, that you simply attribute the value False to a bool grid cell when a sample occurs inside. Something like this:
import numpy as np
import matplotlib.pyplot as plt
# Generic data production
X, Y = np.random.normal(0, 1, 100000), np.random.normal(0, 1, 100000)
ind = np.where((X > 0) & (Y > 0))
X[ind] = 0
Y[ind] = 0
# Generic grid definition
step = 0.5
xmin, xmax = X.min(), X.max()
ymin, ymax = Y.min(), Y.max()
firstx = xmin-step/2
firsty = ymin-step/2
lastx = xmax+2*step/2
lasty = ymax+2*step/2
gridX, gridY = np.meshgrid(np.arange(firstx, lastx, step), np.arange(firsty, lasty, step))
# This is the actual code that computes inside or outside
bool_grid = np.ones(gridX.shape, dtype="bool")
bool_grid[np.int_(0.5+(Y-firsty)/step), np.int_(0.5+(X-firstx)/step)] = False
# Plot code
plt.scatter(gridX.flatten(), gridY.flatten(), marker="+", color="black", alpha=0.3)
plt.scatter(gridX[bool_grid].flatten(), gridY[bool_grid].flatten(), marker="+", s=90, color="green")
plt.scatter(X, Y, s=10, color="red")
plt.show()
, which results in the following (green crosses are True values):
NOTE: This is very fast but it has some limitations. If your data is not compact you'll have True values inside the shape (so holes are possible). It's possible to process the image to remove the holes however (a flood fill or a moving window based algorithm for example). Another possibility is to play with the resolution of the grid.
You just need to pick a point you know is on the hull (let's take the leftmost point among the topmost points), and assume you "got to it" from above (as we know there is no points above it).
now while the next point is not in your list:
Try going CCW from the direction you came from.
The code looks like that:
matrix = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
# Find the leftmost topmost point
first_point = None
for i in range(len(matrix)):
if first_point:
break
for j in range(len(matrix[0])):
if matrix[i][j]:
first_point = [i, j]
break
next_point = first_point
prev_direction = 'up'
next_direction_dict = {'up': 'left', 'left': 'down', 'down': 'right', 'right': 'up'}
opposite_direction = {'up': 'down', 'left': 'right', 'down': 'up', 'right': 'left'}
hull_points = []
def go_direction(point, direction):
# Find the point to a given direction of a given point
i = point[0]
j = point[1]
if direction == 'right':
j += 1
elif direction == 'up':
i -= 1
elif direction == 'left':
j -= 1
elif direction == 'down':
i += 1
else:
raise ValueError
return [i, j]
def find_next_point(matrix, point, prev_direction):
next_direction = next_direction_dict[prev_direction]
next_point = go_direction(point, next_direction)
prev_direction = next_direction
while not matrix[next_point[0]][next_point[1]]:
next_direction = next_direction_dict[prev_direction]
next_point = go_direction(point, next_direction)
prev_direction = next_direction
from_direction = opposite_direction[prev_direction]
return next_point, from_direction
next_point, prev_direction = find_next_point(matrix, next_point, prev_direction)
while next_point != first_point:
if next_point not in hull_points:
hull_points.append(next_point)
next_point, prev_direction = find_next_point(matrix, next_point, prev_direction)
Edit:
Now also handles single point 'tentacles' by iterating until returning to the first point
Heres another though that came to my mind --
A flood fill of the space:
pnts = <<lists of points>>
seen = set()
edges = []
stack = (0,0)
while stack:
ele = stack.pop()
if ele in pnts:
edges.append(ele)
else:
seen.add(ele)
if (ele[0] + 1, ele[1]) not in seen:
stack.append(ele[0] + 1, ele[1])
if (ele[0] - 1, ele[1]) not in seen:
stack.append(ele[0] - 1, ele[1])
if (ele[0], ele[1] + 1) not in seen:
stack.append(ele[0], ele[1] + 1)
if (ele[0], ele[1] - 1) not in seen:
stack.append(ele[0], ele[1] - 1)
Then you need to sort the points which shouldn't be too hard.

scipy optimize SLSQP only takes last ineq constrant into account

Let's say I have a portfolio with weights, sum = 1.
Then I want to define pockets (0, 1, 2) with some assets included in those pockets, and sum(weights_pocket_assets) < pocket_max_weight
On my UI, I have a 3 columns for each pocket, filled with 1 if asset is in pocket, 0 otherwise (this array is called 'pockets')
mask = list(map(int, pockets[0]))
print(pocket_max[0], mask)
constr0 = {'type': 'ineq', 'fun': lambda x: pocket_max[0] - np.sum(np.ma.array(x, mask=np.logical_not(mask)))}
mask = list(map(int, pockets[1]))
print(pocket_max[1], mask)
constr1 = {'type': 'ineq', 'fun': lambda x: pocket_max[1] - np.sum(np.ma.array(x, mask=np.logical_not(mask)))}
mask = list(map(int, pockets[2]))
print(pocket_max[2], mask)
constr2 = {'type': 'ineq', 'fun': lambda x: pocket_max[2] - np.sum(np.ma.array(x, mask=np.logical_not(mask)))}
constr = [{'type': 'eq', 'fun': lambda x: np.sum(x) - 1}, constr0, constr1, constr2]
print(constr)
gives as output:
0.04 [1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
0.08 [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
0.05 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0]
[{'fun': <function Book.optimize.<locals>.<lambda> at 0x00000060CCD9AD90>, 'type': 'eq'},
{'fun': <function Book.optimize.<locals>.<lambda> at 0x00000060CCD9AD08>, 'type': 'ineq'},
{'fun': <function Book.optimize.<locals>.<lambda> at 0x00000060CCD9ABF8>, 'type': 'ineq'},
{'fun': <function Book.optimize.<locals>.<lambda> at 0x00000060CCD9AAE8>, 'type': 'ineq'}]
which seems correct.
Problem is optimize only with eq and last ineq (ie sum(w) = 1 and sum(w_pocket_2) = 0.05)
Also if I have only 2 pockets, it optimizes with last only.
For short, it only takes last ineq in optimization... don't know what's wrong.
EDIT:
if pockets are equals (ie, same components for each pocket, ie same mask) then all 3 'ineq' constraints are taken into account (ie the most constraining in fact, but no problem if it's the first 'ineq', the second or the third that is the most constraining)
as soon as pockets have not similar components (ex: we add a component for the second 'ineq'), only the last 'ineq' is taken by optimization.
As often, it was a problem with variable scope (odd stuff since variables were still defined, but overwritten. I did not investigate more to fully understand). The following code works as expected (all pockets constraints taken into account):
constr += ({'type': 'ineq',
'fun': lambda x, mask, pocket_max, i: pocket_max[i] - np.sum(np.ma.array(x, mask=np.logical_not(mask))),
'args': (mask, pocket_max, i )}, )

rotating the tires in a car (open gl)

Based on the answer i got for the same question earlier, i changed my code, as per the homework i had to use glmultmatrix. But this is not working. Here is the code, what i am doing is that i translate the center of tire to the center of car, rotate the tire, and then translate back. But it is not placing back the tire where it should be:
if (name == 'Front Driver tire' ) & (self.fFlag == "true"):
self.getCenterTireRim()
bodyFace = self.mini.group(name)
glPushMatrix()
x = self.carCenterX - self.xtFront
y = self.carCenterY - self.ytFront
z = self.carCenterZ - self.ztFront
A = self.matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1)
glMultMatrixd(cast(A, POINTER(c_double)))
#print self.carCenterX, self.carCenterY, self.carCenterZ
#print self.xtFront, self.ytFront, self.ztFront
B = self.matrix(1,0,0,0,0, math.cos(math.radians(self.angle1 + 45)), math.sin(math.radians(self.angle1 + 45)), 0, 0, -math.sin(math.radians(self.angle1 + 45)), math.cos(math.radians(self.angle1 + 45)), 0, 0,0,0, 1)
glMultMatrixd(cast(B, POINTER(c_double)))
for face in bodyFace:
if len(face) == 3:
glBegin(GL_TRIANGLES)
elif len(face) == 4:
glBegin(GL_QUADS)
else:
glBegin(GL_POLYGON)
for i in face:
glNormal3f(*self.mini.normal(i))
glVertex3f(*self.mini.vertex(i))
glEnd()
C = self.matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x - self.carCenterX , y - self.carCenterY, z - self.carCenterZ, 1)
glMultMatrixd(cast(C, POINTER(c_double)))
glPopMatrix()
elif (name == 'Front Driver tire rim') & (self.fFlag == "true"):
bodyFace = self.mini.group(name)
glPushMatrix()
self.getCenterTireRim()
bodyFace = self.mini.group(name)
A1 = self.matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, self.carCenterX - self.xrFront, self.carCenterY - self.yrFront, self.carCenterZ - self.zrFront, 1)
glMultMatrixd(cast(A1, POINTER(c_double)))
#print self.carCenterX, self.carCenterY, self.carCenterZ
#print self.xrFront, self.yrFront, self.zrFront
B1 = self.matrix(1,0,0,0,0, math.cos(math.radians(self.angle1 + 45)), math.sin(math.radians(self.angle1 + 45)), 0, 0, -math.sin(math.radians(self.angle1 + 45)), math.cos(math.radians(self.angle1 + 45)), 0, 0, 0, 0, 1)
glMultMatrixd(cast(B1, POINTER(c_double)))
for face in bodyFace:
if len(face) == 3:
glBegin(GL_TRIANGLES)
elif len(face) == 4:
glBegin(GL_QUADS)
else:
glBegin(GL_POLYGON)
for i in face:
glNormal3f(*self.mini.normal(i))
glVertex3f(*self.mini.vertex(i))
glEnd()
C1 = self.matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, self.xrFront - self.carCenterX , self.yrFront - self.carCenterY, self.zrFront - self.carCenterZ, 1)
glMultMatrixd(cast(C1, POINTER(c_double)))
glPopMatrix()
I'm pretty sure that it is because this line
C = self.matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x - self.carCenterX , y - self.carCenterY, z - self.carCenterZ, 1)
should be
C = self.matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -x , -y, -z, 1)
I'm not sure why you were using x - self.carCenterX and so forth. You translated one way (x,y,z) so just go back the opposite direction, -(x,y,z) = (-x,-y,-z)
I hope that helps.

Categories