circular element (cannot interact with squares)

This commit is contained in:
Ian Jauslin 2022-09-27 18:42:11 -04:00
parent 7a044a1619
commit 383cb5c462
3 changed files with 53 additions and 2 deletions

View File

@ -2,7 +2,7 @@
import math
import sys
from point import Point,l_infinity
from point import Point,l_infinity,l_2
from tools import isint_nonzero,sgn,in_interval
# parent class of all elements
@ -39,6 +39,7 @@ class Element():
# override in each subclass
# move along edge of element
# delta is the impossible move that was asked for
def move_along(self,delta,element):
return element
@ -47,6 +48,7 @@ class Element():
class Element_square(Element):
# check whether an element interacts with square
# TODO: this only works if element is a square!
def check_interaction(self,element):
# allow for error
return l_infinity(element.pos-self.pos)<(self.size+element.size)/2-1e-11
@ -56,6 +58,7 @@ class Element_square(Element):
return l_infinity(self.pos-x)<=1/2
# check whether an element is touching self
# TODO: this only works if element is a square!
def check_touch(self,element):
# allow for error
if in_interval(l_infinity(element.pos-self.pos),(self.size+element.size)/2-1e-11,(self.size+element.size)/2+1e-11):
@ -63,6 +66,7 @@ class Element_square(Element):
return False
# find position along a line that comes in contact with the line going through element.pos in direction v
# TODO: this only works if element is a square!
def move_on_line_to_stick(self,element,v):
# compute intersections with four lines making up square
if v.x!=0:
@ -106,6 +110,7 @@ class Element_square(Element):
return closest-element.pos
# move along edge of square
# TODO: this only works if element is a square!
def move_along(self,delta,element):
rel=element.pos-self.pos
# check if the particle is stuck in the x direction
@ -162,3 +167,45 @@ class Element_square(Element):
candidate.x=math.floor(rel/((self.size+element.size)/2))*((self.size+element.size)/2)+self.pos.x-element.pos.x
return candidate
# circular elements
# (size is the diameter)
class Element_circle(Element):
# check whether an element interacts with square
# TODO: this only works if element is a circle!
def check_interaction(self,element):
# allow for error
return l_2(element.pos-self.pos)<(self.size+element.size)/2-1e-11
# whether x is in the support of the element
def in_support(self,x):
return l_2(self.pos-x)<=1/2
# check whether an element is touching self
# TODO: this only works if element is a circle!
def check_touch(self,element):
# allow for error
if in_interval(l_2(element.pos-self.pos),(self.size+element.size)/2-1e-11,(self.size+element.size)/2+1e-11):
return True
return False
# find position along a line that comes in contact with the line going through element.pos in direction v
# TODO: this only works if element is a circle!
def move_on_line_to_stick(self,element,v):
# relative position
x=element.pos-self.pos
# radius of collision circle
R=(element.size+self.size)/2
# smallest root of t^2 v^2+2x.v t+x^2-R^2
t=(-v.dot(x)+sqrt(v.dot(x)*v.dot(v)-v.dot(v)*(x.dot(x)-R*R)))/v.dot(v)
# return difference to pos
return t*v
# move along edge of circle
# TODO: this only works if element is a circle!
def move_along(self,delta,element):
x=element.pos-self.pos+delta
return x/l_2(x)*(element.size+self.size)/2+self.pos-element.pos

View File

@ -213,7 +213,7 @@ class Painter(Widget):
touchx=self.coord_topos_x(touch.x)
touchy=self.coord_topos_y(touch.y)
# create new cross
# create new particle
if touch.button=="right":
new=Cross(touchx,touchy)
# snap to lattice

View File

@ -49,3 +49,7 @@ class Point:
# L infinity norm
def l_infinity(x):
return max(abs(x.x),abs(x.y))
# L 2 norm
def l_2(x):
return sqrt(x.x*x.x+x.y*x.y)