Find if two game object overlapping - Python - python

I am trying to achieve if two objects (let's say two cubes) with their locations and dimensions.
for example we have a function:
def isOverlapped(locationCube1, dimensionCube1, locationCube2, dimensionCube2)
It should return true if they overlapped and false otherwise. The parameters should be a tuple of x, y, z coordination.
For example: we have two cubes:
Cube 1: location = (2, 2, 2) , dimension = (1.0, 5.0, 1.0)
Cube 2: location = (1.0, -1.0, 1.0) , dimension = (2.0, 2.0, 2.0)
So, after I put this in simulation I found out that they overlapped each others.
Now, I am wondering how to program such a thing. Thank you!

The idea is that you check each axis separately. If ANY axis does not overlap, then the objects do not intersect. Assuming the lines are sorted, if the end of line 1 > start of line 2 and start of line 1 < end of line 2, then they overlap.
https://gamedevelopment.tutsplus.com/tutorials/collision-detection-using-the-separating-axis-theorem--gamedev-169

Related

How can I use numpy to create a function that returns two-dimensional values from arrays of data?

This question is about deriving a mathematical function that returns pairs of values based on arrays of data - two-dimensional values from two-dimensional values.
I have created a Python library that drives a pen-plotter using cheap servo motors.
From the x/y position of the pen, I obtain the required angles of the motors, and from that the pulse-widths that need to be fed to them.
These cheap motors are of course rather non-linear and the mechanical system as a whole exhibits hysteresis and distorting behaviours.
The library can calculate the required pulse-width values in different ways. One way is to determine some actual pulse-width/angle measurements for each servo, like so:
servo_angle_pws = [
# angle, pulse-width
[ 45, 1000],
[ 60, 1200],
[ 90, 1500],
[120, 1800],
[135, 2000],
]
and then use numpy to create a function that fits the curve described by those values:
servo_2_array = numpy.array(servo_2_angle_pws)
self.angles_to_pw = numpy.poly1d(numpy.polyfit(servo_2_array[:, 0], servo_2_array[:, 1], 3))
Which would look like this:
Now I'd like to take another step, and find a function in a similar way that gives me me the relationship between x/y positions and pulse-widths rather than angles (this will provide greater accuracy, as it will take into account more real-world imperfections in the system). In this case though, I will have two pairs of values, like this:
# x/y positions, servo pulse-widths
((-8.0, 8.0), (1900, 1413)),
((-8.0, 4.0), (2208, 1605)),
(( 8.0, 4.0), ( 977, 1622)),
((-0.0, 4.0), (1759, 1999)),
(( 6.0, 13.0), (1065, 1121)),
My question is: what do I need to do to get a function (I'll need two of them of course) that returns pulse-width values for a desired pair of x/y positions? For example:
pw1 = xy_to_pulsewidths1(x=-4, y=6.3)
pw2 = xy_to_pulsewidths2(x=-4, y=6.3)
I believe that I need to do a "multivariate regression" - but I am no mathematician so I don't know if that's right, and even if it is, I have not yet found anything in my researches in numpy and scipy that indicates what I would actually need to do in my code.
If I understand you correctly, you want to perform a multivariate regression, which is equivalent to solving a multivariate least-squares problem. Assuming your function is a 2D polynomial, you can use a combination of polyval2d and scipy.optimize.least_squares:
import numpy as np
from numpy.polynomial.polynomial import polyval2d
from scipy.optimize import least_squares
x = np.array((-8.0,-8.0, 8.0, -0.0, 6.0))
y = np.array((8.0, 4.0, 4.0, 4.0, 13.0))
pulse_widths = np.array(((1900, 1413),(2208, 1605),(977, 1622),(1759, 1999),(1065, 1121)))
# we want to minimize the sum of the squares of the residuals
def residuals(coeffs, x, y, widths, poly_degree):
return polyval2d(x, y, coeffs.reshape(-1, poly_degree+1)) - widths
# polynomial degree
degree = 3
# initial guess for the polynomial coefficients
x0 = np.ones((degree+1)**2)
# res1.x and res2.x contain your coefficients
res1 = least_squares(lambda coeffs: residuals(coeffs, x, y, pulse_widths[:, 0], degree), x0=x0)
res2 = least_squares(lambda coeffs: residuals(coeffs, x, y, pulse_widths[:, 1], degree), x0=x0)
# Evaluate the 2d Polynomial at (x,y)
def xy_to_pulswidth(x, y, coeffs):
num_coeffs = int(np.sqrt(coeffs.size))
return polyval2d(x, y, coeffs.reshape(-1, num_coeffs))
# Evaluate the function
pw1 = xy_to_pulswidth(-4, 6.3, res1.x)
pw2 = xy_to_pulswidth(-4, 6.3, res2.x)

How to get area of a mesh?

How to get area of a mesh if subdivided into triangle?
I found the cross product for each triangle and computed the area.The area is coming wrong according to blender.I have looked up stack flow other posts but they are not of any help.Could you help me to figure out why I am get a low area of 16.3 something for my mesh.
for i in f:
# print("i",i)
for k in i:
# print("k",k)
for j in z:
# print("z",z)
if (k==z.index(j)):
f_v.append(j)
# print(f_v)
v0=np.array(f_v[0])
v1=np.array(f_v[1])
v2=np.array(f_v[2])
ax=np.subtract(f_v[1],f_v[0])
ax=np.subtract(f_v[2],f_v[1])
ay=np.subtract(f_v[3],f_v[1])
..
cxx=np.power(cx,2)
# cyy=np.power(ay,2)
#czz=np.power(cz,2)
I've created meshplex to help you with this kind of tasks, and do it quickly. Simply load the mesh and sum up the cell volumes:
import meshplex
points = numpy.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
cells = numpy.array([[0, 1, 2]])
mesh = meshplex.MeshTri(points, cells)
# or read it from a file
# mesh = meshplex.read("circle.vtk")
print(numpy.sum(mesh.cell_volumes))

How to create Coulomb Matrix with Python?

I need some coulomb matrices of molecules for a machine learning task.
Coulomb Matrix? Here's a paper describing it
I found the python package molml which has a method for it. However i can't figure out how to use the api for a single molecule only. In all examples they provide the method is called with two molecules, why?
How the example provides the method:
H2 = (['H', 'H'],
[[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0]])
HCN = (['H', 'C', 'N'],
[[-1.0, 0.0, 0.0],
[ 0.0, 0.0, 0.0],
[ 1.0, 0.0, 0.0]])
feat.transform([H2, HCN])
I need something like this:
atomnames = [list of atomsymbols]
atomcoords = [list of [x,y,z] for the atoms]
coulombMatrice = CoulombMatrix((atomnames,atomcoords)
I also found another lib (QML) wich promises the possibility to generate coulomb matrices, but, i'm not able to install it on windows because it depends on linux gcc-fortran compilers, i already installed cygwin and gcc-fortran for this purpose.
Thank you, guys
I've implemented my own solution for the problem. There's much room for improvements. E.g. randomly sorted coulomb matrix and bag of bonds are still not implemented.
import numpy as np
def get_coulombmatrix(molecule, largest_mol_size=None):
"""
This function generates a coulomb matrix for the given molecule
if largest_mol size is provided matrix will have dimension lm x lm.
Padding is provided for the bottom and right _|
"""
numberAtoms = len(molecule.atoms)
if largest_mol_size == None or largest_mol_size == 0: largest_mol_size = numberAtoms
cij = np.zeros((largest_mol_size, largest_mol_size))
xyzmatrix = [[atom.position.x, atom.position.y, atom.position.z] for atom in molecule.atoms]
chargearray = [atom.atomic_number for atom in molecule.atoms]
for i in range(numberAtoms):
for j in range(numberAtoms):
if i == j:
cij[i][j] = 0.5 * chargearray[i] ** 2.4 # Diagonal term described by Potential energy of isolated atom
else:
dist = np.linalg.norm(np.array(xyzmatrix[i]) - np.array(xyzmatrix[j]))
cij[i][j] = chargearray[i] * chargearray[j] / dist # Pair-wise repulsion
return cij

Python optimization of 3D grid search with nested loops

Imagine we have a 3D grid with discrete points. The ranges for the 3 dimensions (interval endpoints included) are:
in x: [4000, 7000], stepsize 1000 in y: [0.0, 2.0], stepsize 1.0 in z: [-0.75, 0.75], stepsize 0.25
The task below should now be done for all points in the range [4000, 7000, 100], [0.0, 2.0, 0.1], [-0.75, 0.75, 0.05] (roughly 20000 = 31 * 21 * 31 points):
Find the smallest cuboid that contains the point. However there are holes in the grid (each point should have a "physical" counterpart as a file, but some do not). I tried the following really simple code (where I called cuboid 'cube'):
def findcubesnew(startvalues, endvalues, resols, \
loopvalues, refvalues, modelpath):
cubearray = []
startvalue1 = startvalues[0]
endvalue1 = endvalues[0]
resol1 = resols[0]
refvalue1 = refvalues[0]
loopstop1 = loopvalues[0][0]
loopstart1 = loopvalues[1][0]
startvalue2 = startvalues[1]
endvalue2 = endvalues[1]
resol2 = resols[1]
refvalue2 = refvalues[1]
loopstop2 = loopvalues[0][1]
loopstart2 = loopvalues[1][1]
startvalue3 = startvalues[2]
endvalue3 = endvalues[2]
resol3 = resols[2]
refvalue3 = refvalues[2]
loopstop3 = loopvalues[0][2]
loopstart3 = loopvalues[1][2]
refmass = refvalues[3]
refveloc = refvalues[4]
for start1 in numpy.arange(startvalue1, loopstop1 + resol1, resol1):
for end1 in numpy.arange(loopstart1, endvalue1 + resol1, resol1):
for start2 in numpy.arange(startvalue2, loopstop2 + resol2, resol2):
for end2 in numpy.arange(loopstart2, endvalue2 + resol2, resol2):
for start3 in numpy.arange(startvalue3, loopstop3 + resol3, resol3):
for end3 in numpy.arange(loopstart3, endvalue3 + resol3, resol3):
if glob.glob(*start1*start2*start3) and \
if glob.glob(modelpath/*start1*start2*end3) and \
if glob.glob(modelpath/*start1*end2*start3) and \
if glob.glob(modelpath/*start1*end2*end3) and \
if glob.glob(modelpath/*end1*start2*start3) and \
if glob.glob(modelpath/*end1*start2*end3) and \
if glob.glob(modelpath/*end1*end2*start3) and \
if glob.glob(modelpath/*end1*end2*end3):
cubearray.append((start1, end1, start2, end2, start3, end3))
else:
pass
return cubearray
foundcubearray = findcubesnew([metalstart, tempstart, loggstart], \
[metalend, tempend, loggend], [metalresol, tempresol, loggresol], \
looplimitarray, [refmetal, reftemp, reflogg, refmass, refveloc], \
modelpath)
if foundcubearray:
bestcube = findsmallestcubenew(foundcubearray, \
[metalresol, tempresol, loggresol])
....
Hence I go in a loop in x direction from the lower grid border to the biggest value below the desired point where we want to get the cuboid, and in another loop from the smallest value after the point to the higher grid border. Similarly for the y- and the z-direction and the loops are nested one in each other. The if part is pseudocode without the format strings etc. and checks that all file with these values (and other quantities may be as well in the filename) does exist (that all corners of the cuboid are present).
This code also finds points or lines or rectangles if one or multiple coordinates of the point coincide with values in our grid, but it's not a problem (and actually desired).
The bottleneck here is that the search for the cuboids takes quite some time (the smallest cuboid can be found easily and quickly then, if there are multiple with the same (smallest) size I do not care which one to choose). Also I need to read in the start and end values of the grid, the stepsizes, the reference values (coordinates) of my point and some other variables. Any way to optimize the code? It takes roughly 1.4 sec per point so ~ 8 hours for the ~ 20000 points and this is too long.
I know that if I found the smallest cuboid e.g. for the point 4500, 0.5, 0.1, I can immediately tell that all other points inside the cube with limits [4000, 5000; 0.0, 1.0; 0, 0.25] have the same smallest cuboid. Still I'm interested in a solution that optimizes the computation time for all 20000 runs. The application of this is an interpolation routine for stellar models where 8 grid points with a cuboid shape around the interpolation point are required.
P.S.: I hope that the continuation line breaks and indents are correct. In my code they do not exist, although it's not a good style to go beyond 80 chars per line :).
My suggestion is not to use glob. If I'm reading the numbers right, the modelpath directory could contain up to 20,000 files, and there might be 8 globs on these in the inner loop body. I'm surprised it only takes 1.4 seconds per point!
The file names are just being used as booleans, right? All that matters is whether the file exists or not.
I would create a 3D array of booleans with the same dimensions as your 3D grid, initialised to False. Then read through the contents of the directory, converting each filename into a 3D index and set that to True.
Then do your search over the points using the array of booleans, not the file system.
Hope this helps.

Duplicate Tick Labels in Matplotlib

I'm searching for a way to extract all text elements from a matplotlibfigure including their position, style, alignment etc. Calling the findobj(matplotlib.text.Text) method of a figure does that job exactly. However, I get some weird duplicates for all the tick labels and I don't know how to handle them.
For example, use findobj for printing all Text elements of an axis:
import matplotlib
import pylab as p
p.plot([1,2,3])
p.xticks([1],["tick"])
ax = p.gca()
fig = p.gcf()
p.draw()
def print_texts(artist):
for t in artist.findobj(matplotlib.text.Text):
if t.get_visible() and t.get_text():
print " %r # %s" % (t.get_text(), t.get_position())
print "X-Axis Text Elements:"
print_texts(ax.xaxis)
print "Y-Axis Text Elements:"
print_texts(ax.yaxis)
Result:
X-Axis Text Elements:
'tick' # (1.0, 0.0)
'tick' # (0.0, 1.0)
Y-Axis Text Elements:
u'1.0' # (0.0, 1.0)
u'1.0' # (1.0, 0.0)
u'1.5' # (0.0, 1.5)
u'1.5' # (1.0, 0.0)
u'2.0' # (0.0, 2.0)
u'2.0' # (1.0, 0.0)
u'2.5' # (0.0, 2.5)
u'2.5' # (1.0, 0.0)
u'3.0' # (0.0, 3.0)
u'3.0' # (1.0, 0.0)
Note that all tick labels have duplicates positioned at the end of the axis. Why? How to filter them out from a list of Text elements? Their get_visible() attribute is True.
Another thing is that I first have to do call draw() in order to update/generate the ticks. How do I force an update of the tick labels? matplotlib.colorbar.Colorbar seems to have a update_ticks() method, but I can't find something similar for ticks on the axes.
I also tried writing a custum backend and fetch all the texts from the draw_text()
method of the renderer. In contrast to the documentation draw_text() does
not receive a matplotlib.text.Text instance with all the necessary
information but only a simple string and a pre-layouted position.
The answer to this problem was given in the matplotlib mailing list. The Tick object always creates two text labels, one for the left/bottom and one for the right/top. When a Tick artist is drawn its label1On and label2On attributes define which of the two child text labels receive the draw() call. Both of them remain in the visible state however.
So before iterating through all the text elements of a figure, I hide those labels that are not supposed to be seen:
for tick in fig.findobj(matplotlib.axis.Tick):
tick.label1.set_visible(tick.label1On)
tick.label2.set_visible(tick.label2On)
for text in fig.findobj(match=Text, include_self=False):
s = text.get_text()
if not s or not text.get_visible(): continue
# do something with the texts

Categories

Resources