Wed 28 Aug 21:38:52 CEST 2024
This commit is contained in:
		
							parent
							
								
									411e953923
								
							
						
					
					
						commit
						36dbeccb6c
					
				
							
								
								
									
										238
									
								
								src/SimNDT/core/packing.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								src/SimNDT/core/packing.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,238 @@ | ||||||
|  | import math | ||||||
|  | from math import pi | ||||||
|  | 
 | ||||||
|  | import numpy as np | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Ellipse: | ||||||
|  | 
 | ||||||
|  |     def __init__(self, x, y, a, b, theta): | ||||||
|  |         self.x = x | ||||||
|  |         self.y = y | ||||||
|  |         self.a = a | ||||||
|  |         self.b = b | ||||||
|  |         self.theta = theta | ||||||
|  |         self.rect = self.getRect() | ||||||
|  | 
 | ||||||
|  |     def area(self): | ||||||
|  |         return pi * self.a * self.b | ||||||
|  | 
 | ||||||
|  |     def getRect(self): | ||||||
|  | 
 | ||||||
|  |         t	= np.linspace(0,2*pi,20, endpoint=True) | ||||||
|  |         x	= self.x  + self.a * np.cos(t) | ||||||
|  |         y	= self.y  + self.b * np.sin(t) | ||||||
|  | 
 | ||||||
|  |         xmin = np.min(x) | ||||||
|  |         xmax = np.max(x) | ||||||
|  |         ymin = np.min(y) | ||||||
|  |         ymax = np.max(y) | ||||||
|  | 
 | ||||||
|  |         w = xmax-xmin | ||||||
|  |         h = ymax-ymin | ||||||
|  | 
 | ||||||
|  |         x0 = (xmax+xmin)/2 | ||||||
|  |         y0 = (ymax+ymin)/2 | ||||||
|  | 
 | ||||||
|  |         return Rect(x0,y0,w,h) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def intersect2(self, b): | ||||||
|  |         return ( (np.abs(self.rect.x - b.rect.x) * 2.0 < (self.rect.w + b.rect.w) ) and | ||||||
|  |                (np.abs(self.rect.y - b.rect.y) * 2.0 < (self.rect.h + b.rect.h)) ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def intersect(self, ellipse): | ||||||
|  | 
 | ||||||
|  |         c =	 np.sqrt(self.a**2 - self.b**2) | ||||||
|  |         cost  =	 c * np.cos(self.theta) | ||||||
|  |         sint  =	 c * np.sin(self.theta) | ||||||
|  |         d1	= (ellipse.x - self.x - cost)**2 + (ellipse.y - self.y - sint)**2 | ||||||
|  |         d1	= np.sqrt(d1) | ||||||
|  |         d2	= (ellipse.x - self.x + cost)**2 + (ellipse.y - self.y + sint)**2 | ||||||
|  |         d2	= np.sqrt(d2) | ||||||
|  |         d	= np.sqrt( (self.x-ellipse.x)**2 + (self.y-ellipse.y)**2 ) | ||||||
|  | 
 | ||||||
|  |         if self.a >= 8*ellipse.a: | ||||||
|  |             Mb	= 0.15*self.a + ellipse.a | ||||||
|  | 
 | ||||||
|  |         elif ellipse.a >= 8*self.a: | ||||||
|  |             Mb	= self.a + 0.15*ellipse.a | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         else: | ||||||
|  |             Mb	= self.a + ellipse.a | ||||||
|  | 
 | ||||||
|  |         if	(d1+d2 <= Mb) or (d <= Mb): | ||||||
|  |             return True | ||||||
|  | 
 | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Circle: | ||||||
|  | 
 | ||||||
|  |     def __init__(self, x, y, r): | ||||||
|  |         self.x = x | ||||||
|  |         self.y = y | ||||||
|  |         self.r = r | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return '<{0},{1}:{2}>'.format(self.x, self.y, self.r) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def area(self): | ||||||
|  |         return pi * self.r**2 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def distance(self, x, y): | ||||||
|  |         return math.sqrt((self.x - x)**2 + (self.y - y)**2) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def collide(self, x, y): | ||||||
|  |         return (self.distance(x, y) <= self.r) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def intersect(self, circ): | ||||||
|  |         if (self.distance(circ.x, circ.y) <= self.r + circ.r): | ||||||
|  |             return True | ||||||
|  |         else: | ||||||
|  |             return False | ||||||
|  | 
 | ||||||
|  |     def getRect(self): | ||||||
|  | 
 | ||||||
|  |         return Rect(self.x - self.r, self.y - self.r, 2 * self.r, 2 * self.r) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Rect: | ||||||
|  | 
 | ||||||
|  |     def __init__(self, x, y, w, h): | ||||||
|  |         self.x = x | ||||||
|  |         self.y = y | ||||||
|  |         self.w = w | ||||||
|  |         self.h = h | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def collide(self, x, y): | ||||||
|  |         return ((self.x <= x <= self.x + self.w) and | ||||||
|  |                  (self.y <= y <= self.y + self.h)) | ||||||
|  | 
 | ||||||
|  |     def intersect(self, rect): | ||||||
|  |         return ((self.x < rect.x + rect.w) and (rect.x < self.x + self.w) and | ||||||
|  |                 (self.y < rect.y + rect.h) and (rect.y < self.y + self.h)) | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return '<{0},{1};{2},{3}>'.format(self.x, self.y, self.w, self.h) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Quadtree: | ||||||
|  | 
 | ||||||
|  |     def __init__(self, depth, rect): | ||||||
|  |         self.rect  = rect | ||||||
|  |         self.depth = depth | ||||||
|  |         self.ne = None | ||||||
|  |         self.se = None | ||||||
|  |         self.sw = None | ||||||
|  |         self.nw = None | ||||||
|  |         self.objs = list() | ||||||
|  |         if (depth > 1): | ||||||
|  |             w = self.rect.w / 2 | ||||||
|  |             h = self.rect.h / 2 | ||||||
|  |             x = self.rect.x + w | ||||||
|  |             y = self.rect.y | ||||||
|  |             self.ne = Quadtree(depth-1, Rect(x, y, w, h)) | ||||||
|  |             w = self.rect.w / 2 | ||||||
|  |             h = self.rect.h / 2 | ||||||
|  |             x = self.rect.x + w | ||||||
|  |             y = self.rect.y + h | ||||||
|  |             self.se = Quadtree(depth-1, Rect(x, y, w, h)) | ||||||
|  |             w = self.rect.w / 2 | ||||||
|  |             h = self.rect.h / 2 | ||||||
|  |             x = self.rect.x | ||||||
|  |             y = self.rect.y + h | ||||||
|  |             self.sw = Quadtree(depth-1, Rect(x, y, w, h)) | ||||||
|  |             w = self.rect.w / 2 | ||||||
|  |             h = self.rect.h / 2 | ||||||
|  |             x = self.rect.x | ||||||
|  |             y = self.rect.y | ||||||
|  |             self.nw = Quadtree(depth-1, Rect(x, y, w, h)) | ||||||
|  | 
 | ||||||
|  |     def insert(self, obj): | ||||||
|  |         if (not self.rect.intersect(obj.getRect())): | ||||||
|  |             return | ||||||
|  |         if (self.depth == 1): | ||||||
|  |             self.objs.append(obj) | ||||||
|  |         else: | ||||||
|  |             self.ne.insert(obj) | ||||||
|  |             self.se.insert(obj) | ||||||
|  |             self.sw.insert(obj) | ||||||
|  |             self.nw.insert(obj) | ||||||
|  | 
 | ||||||
|  |     def query(self, obj): | ||||||
|  |         inRange = list() | ||||||
|  |         if (not self.rect.intersect(obj.getRect())): | ||||||
|  |             return inRange | ||||||
|  |         if (self.depth == 1): | ||||||
|  |             for o in self.objs: | ||||||
|  |                 if (obj.intersect(o)): | ||||||
|  |                     inRange.append(o) | ||||||
|  |         else: | ||||||
|  |             inRange.extend(self.ne.query(obj)) | ||||||
|  |             inRange.extend(self.se.query(obj)) | ||||||
|  |             inRange.extend(self.sw.query(obj)) | ||||||
|  |             inRange.extend(self.nw.query(obj)) | ||||||
|  |         return inRange | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def ellipseMatrix(x0, y0, a, b, theta, Image, Color, XX, YY): | ||||||
|  | 
 | ||||||
|  |     a2 = a**2 | ||||||
|  |     b2 = b**2 | ||||||
|  |     cost = np.cos(theta) | ||||||
|  |     sint = np.sin(theta) | ||||||
|  | 
 | ||||||
|  |     Ellipse = ( ( ( (XX-x0)*cost+(YY-y0)*sint )**2 )/(a2) + | ||||||
|  |                 ( ( (XX-x0)*sint-(YY-y0)*cost )**2 )/(b2) ) | ||||||
|  | 
 | ||||||
|  |     #Img	 = (Ellipse < 1.0) | ||||||
|  |     #indx,indy = np.nonzero(Img == 1) | ||||||
|  |     #Image[indx,indy] = Color | ||||||
|  | 
 | ||||||
|  |     Image[Ellipse < 1.0] = Color | ||||||
|  |     return Image | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def circleMatrix(x0, y0, a, Image, Color, XX, YY): | ||||||
|  | 
 | ||||||
|  |     a2 = a**2 | ||||||
|  |     Ellipse = (XX-x0)**2  + (YY-y0)**2 | ||||||
|  |     Image[Ellipse < a2] = Color | ||||||
|  |     return Image | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def ellipseDiscard(x0, y0, a, b, theta, XX, YY, coords, mask, value): | ||||||
|  | 
 | ||||||
|  |     XXX = XX[::1,::1] | ||||||
|  |     YYY = YY[::1,::1] | ||||||
|  |     Ellipse = ( ( ( (XXX-x0)*np.cos(theta)+(YYY-y0)*np.sin(theta) )**2 )/(a**2) + | ||||||
|  | 												( ( (XXX-x0)*np.sin(theta)-(YYY-y0)*np.cos(theta) )**2 )/(b**2) ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     Img = np.argwhere(Ellipse <= 1.0) | ||||||
|  | 
 | ||||||
|  |     for ind in Img: | ||||||
|  |         coords.discard((ind[0],ind[1])) | ||||||
|  |         mask[ind[0],ind[1]] = value | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user