1 | initial version |
Some things jump out for me:
1) Vertex.distance
calls itself. Presumably it should call Vertex._distance
.
2) Vertex._distance
has issues: it needs negative signs inside the squares and the vector indices are currently identical.
3) Most critically, you're trying to plot a function of three independent variables, which would need four-dimensional plotting capabilities. The best you can do in three dimensions is an implicit_plot3d
for when the four-dimensional surface equals some value. In the following code, that's when distance(repulsion, attraction, epsilon)
is one:
class Vertex: def __init__(self): self.acceleration = vector((0, 0, 0)) self.velocity = vector((0, 0, 0)) self.position = self._random_vector() def _rand(self): return RR.random_element(-1, 1) def _random_vector(self): return vector((self._rand(), self._rand(), self._rand())) def _repulsion(self, x1, x2, c_repulsion=0, c_epsilon=0.1): return (c_repulsion / c_epsilon + abs(x1-x2)^2)*((x1-x2)/abs(x1-x2)) def _attraction(self, x1, x2, c_attraction): return (x1-x2)*-1*c_attraction def iterate(self, vertices, c_repulsion=0, c_attraction=0, c_epsilon=0, c_friction=0.60): for v in vertices: if v is not self: self.acceleration += self._attraction(self.position, v.position, c_attraction) self.acceleration -= self._repulsion(self.position, v.position, c_repulsion, c_epsilon) self.acceleration -= (self.acceleration * c_friction) self.velocity += self.acceleration self.position += self.velocity def _distance(self, p1, p2): return sqrt((p1[0] - p2[0])^2 + (p1[1] - p2[1])^2 + (p1[2] - p2[2])^2) def distance(self, v): return self._distance(self.position, v.position) def reset(self): self.acceleration = vector((0, 0, 0)) self.velocity = vector((0, 0, 0)) self.position = random_vector() v1 = Vertex() v2 = Vertex() repulsion, attraction, epsilon = var('repulsion, attraction, epsilon') def distance(repulsion, attraction, epsilon): #for i in range(100): v1.iterate( [v1, v2], c_repulsion=repulsion, c_attraction=attraction, c_epsilon=epsilon ) return v1.distance(v2) implicit_plot3d(distance(repulsion, attraction, epsilon)==1, (repulsion, -1, 1), (attraction, -1, 1), (epsilon, -1, 1) )
Here's a live link for the code. You can change the value on the right-hand side of ==
to see other three-dimensional slices of the four-surface.
2 | No.2 Revision |
Some things jump out for me:
1) Vertex.distance
calls itself. Presumably it should call Vertex._distance
.
2) Vertex._distance
has issues: it needs negative signs inside the squares and the vector indices are currently identical.
3) Most critically, you're trying to plot plotting a function of three independent variables, which would need variables needs four-dimensional plotting capabilities. The best One thing you can do in three dimensions is an implicit_plot3d
for when the four-dimensional surface equals some value. In the following code, that's when distance(repulsion, attraction, epsilon)
is one:
class Vertex: def __init__(self): self.acceleration = vector((0, 0, 0)) self.velocity = vector((0, 0, 0)) self.position = self._random_vector() def _rand(self): return RR.random_element(-1, 1) def _random_vector(self): return vector((self._rand(), self._rand(), self._rand())) def _repulsion(self, x1, x2, c_repulsion=0, c_epsilon=0.1): return (c_repulsion / c_epsilon + abs(x1-x2)^2)*((x1-x2)/abs(x1-x2)) def _attraction(self, x1, x2, c_attraction): return (x1-x2)*-1*c_attraction def iterate(self, vertices, c_repulsion=0, c_attraction=0, c_epsilon=0, c_friction=0.60): for v in vertices: if v is not self: self.acceleration += self._attraction(self.position, v.position, c_attraction) self.acceleration -= self._repulsion(self.position, v.position, c_repulsion, c_epsilon) self.acceleration -= (self.acceleration * c_friction) self.velocity += self.acceleration self.position += self.velocity def _distance(self, p1, p2): return sqrt((p1[0] - p2[0])^2 + (p1[1] - p2[1])^2 + (p1[2] - p2[2])^2) def distance(self, v): return self._distance(self.position, v.position) def reset(self): self.acceleration = vector((0, 0, 0)) self.velocity = vector((0, 0, 0)) self.position = random_vector() v1 = Vertex() v2 = Vertex() repulsion, attraction, epsilon = var('repulsion, attraction, epsilon') def distance(repulsion, attraction, epsilon): #for i in range(100): v1.iterate( [v1, v2], c_repulsion=repulsion, c_attraction=attraction, c_epsilon=epsilon ) return v1.distance(v2) implicit_plot3d(distance(repulsion, attraction, epsilon)==1, (repulsion, -1, 1), (attraction, -1, 1), (epsilon, -1, 1) )
Here's a live link for the code. You can change the value on the right-hand side of ==
to see other three-dimensional slices of the four-surface.