The code shared here shows a system of cycles that, while rotating, create trails. I have issues when the points bringing the rigid orange arms intersect while rotating,ruining the trail and inverting themselves. The problem is clearly because their distance = 0 during intersection but I don’t know in which way this ruins the work and how to solve it.
Language: Julia, Computer: HP PAVILION
using Javis, Luxor, Animations, Colors, Plots, Random
videoone = Video(800,800)
function ground(args...)
Javis.background("white")
sethue("black")
end
framez =2000
Background(1:framez, ground)
dist_cerchi = 120
raggio1 = 60
raggio2 = 60
raggio1_piccolo = 60
raggio2_piccolo = 60
v_1 = -8
v_2 = 8
v_1_picc = -16
v_2_picc = 8
braccio1 = 220
braccio2 = 220
offsett = pi
offset2 = pi
setdash("dot")
function circ(p, r, color = "black", action = :stroke)
sethue(color)
circle(p, r, action)
return p
end
function connector(p1, p2, color)
sethue(color)
line(p1,p2, :stroke)
end
c1 = Object(1:framez, (args...)-> circ(O, raggio1, "grey80", :stroke), Point(dist_cerchi/2,0))
c2 = Object(1:framez, (args...)-> circ(O, raggio2, "grey80", :stroke), Point(-dist_cerchi/2,0))
gg1 = dist_cerchi/2+raggio1
gg2 = -dist_cerchi/2
punto_c1 = Object(1:framez, (args...)-> circ(O, 2, "black", :fill), Point(gg1, 0))
punto_c2 = Object(1:framez, (args...)-> circ(O, 2, "black", :fill), Point(gg2+raggio2*cos(offsett), 0+raggio2*sin(offsett)))
c1_piccolo = Object(1:framez, (args...)-> circ(pos(punto_c1), raggio1_piccolo, "grey80", :stroke))
c2_piccolo = Object(1:framez, (args...)-> circ(pos(punto_c2), raggio2_piccolo, "grey80", :stroke))
punto_c1_piccolo = Object(1:framez, (args...)-> circ(O, 2, "black", :fill), Point(gg1+raggio1_piccolo, 0))
punto_c2_piccolo = Object(1:framez, (args...)-> circ(O, 2, "black", :fill),
Point(gg2+raggio2*cos(offsett)+raggio2_piccolo*cos(offset2), 0+raggio2*sin(offsett)+ raggio2_piccolo*sin(offset2)))
act!([c1, c1_piccolo, c2, c2_piccolo, punto_c1, punto_c2, punto_c1_piccolo, punto_c2_piccolo], Action(1:20, appear(:fade)))
act!(punto_c1, Action(RFrames(1:(framez-20)), anim_rotate_around(v_1*2*pi, c1)))
act!(punto_c2, Action(RFrames(1:(framez-20)), anim_rotate_around(v_2*2*pi, c2)))
act!(punto_c1_piccolo, Action(RFrames(1:(framez-20)), anim_rotate_around(v_1_picc*2*pi, c1_piccolo)))
act!(punto_c2_piccolo, Action(RFrames(1:(framez-20)), anim_rotate_around(v_2_picc*2*pi, c2_piccolo)))
Luxor.setline(10)
#linea_base = Object(1:200, (args...) -> connector(pos(punto_c1), pos(punto_c2), "grey50"))
#act!(linea_base, Action(1:20, appear(:fade)))
function calculate_distance(a,b)
p1 = pos(a)
p2 = pos(b)
dist_punti_num = distance(p1, p2)
return dist_punti_num
end
function calculate_angles(a, b)
dist = calculate_distance(a, b)
begin
if abs((braccio1^2 + dist^2 - braccio2^2) / (2 * braccio1 * dist)) >= 1
u1 = 0
elseif dist == 0
u1 = pi/2
else
u1 = acos((braccio1^2 + dist^2 - braccio2^2) / (2 * braccio1 * dist))
end
end
return u1
end
function altezza_punto(args...)
u1 = Object(1:200, calculate_angles(punto_c1_piccolo, punto_c2_piccolo))
altez_1 = Object(1:200, braccio1*sqrt(1-cos(u1)^2))
return altez_1
end
function Pooint(a, b)
pendenza = begin
if a == b
Inf
else
(a.y-b.y)/(a.x-b.x)
end
end
u1 = calculate_angles(a, b)
denom= sqrt(1+pendenza^2)
S = begin
if a.x > b.x
Point(braccio1*cos(u1)/denom +pos(punto_c2_piccolo).x , braccio1*cos(u1)*pendenza/denom +pos(punto_c2_piccolo).y)
else
Point(-braccio1*cos(u1)/denom +pos(punto_c2_piccolo).x , -braccio1*cos(u1)*pendenza/denom +pos(punto_c2_piccolo).y)
end
end
return S
end
function p_union_bracci(a,b,c)
pendenza = (a.y-b.y)/(a.x-b.x)
u1 = calculate_angles(a, b)
denom= sqrt(1+pendenza^2)
S = begin
if a.x-b.x != 0
Point((-1)^c*pendenza*braccio1*sin(u1)/denom+Pooint(a,b).x, (-1)^(c-1)*braccio1*sin(u1)/denom+Pooint(a,b).y)
else
Point((-1)^(c+1)*braccio1*sin(u1)+Pooint(a,b).x, Pooint(a,b).y)
end
end
return S
end
function pathhh!(points, pos, distanzie)
push!(points, pos) # points = path_p_union
if length(points) > 1
dist = distance(points[end-1], points[end])
push!(distanzie, dist)
min_dist = minimum(distanzie)
max_dist = maximum(distanzie)
norm_dists = [(d - min_dist) / (max_dist - min_dist) for d in distanzie]
color_scalee = Plots.cgrad(:thermal)
for i in 2:length(points)
sethue(color_scalee[norm_dists[i-1]])
line(points[i-1], points[i], :stroke)
end
end
end
path_p_union = Point[]
path_p_union2 = Point[]
distanzie = []
distanzie2 = []
p_unione_piccolo = Object(1:framez, (args...)->begin
x1 = pos(punto_c1_piccolo)
x2 = pos(punto_c2_piccolo)
if x1.x < x2.x
circ(p_union_bracci(pos(x1),pos(x2),1), 3, "pink", :fill)
elseif x1.x > x2.x
circ(p_union_bracci(pos(x1),pos(x2),2), 3, "pink", :fill)
end
end)
p_unione2_piccolo = Object(1:framez, (args...)->begin
x1 = pos(punto_c1_piccolo)
x2 = pos(punto_c2_piccolo)
if x1.x != x2.x && x1.x < x2.x
circ(p_union_bracci(pos(x1),pos(x2),2), 3, "pink", :fill)
elseif x1.x != x2.x && x1.x > x2.x
circ(p_union_bracci(pos(x1),pos(x2),1), 3, "pink", :fill)
end
end)
b1_1 = Object(1:framez, (args...)->connector(pos(punto_c1_piccolo),pos(p_unione_piccolo),"orange"))
b2_1 = Object(1:framez, (args...)->connector(pos(punto_c2_piccolo),pos(p_unione_piccolo),"orange"))
b1_2 = Object(1:framez, (args...)->connector(pos(punto_c1_piccolo),pos(p_unione2_piccolo),"orange"))
b2_2 = Object(1:framez, (args...)->connector(pos(punto_c2_piccolo),pos(p_unione2_piccolo),"orange"))
act!([p_unione_piccolo,b1_1,b2_1], Action(1:20, appear(:fade)))
act!([p_unione2_piccolo,b1_2,b2_2], Action(1:20, appear(:fade)))
Object(1:framez, (args...) -> pathhh!(path_p_union, pos(p_unione_piccolo), distanzie))
Object(1:framez, (args...) -> pathhh!(path_p_union2, pos(p_unione2_piccolo), distanzie2))
render(videoone, pathname = "videone2.gif")
I implemented few lines to descrivbe how u1 has to become when acos() function > 1 and when distance of rotating points becomes 0. (u1 = Inf and other couple of things recalculated using asymptotes)
But more than that, I didn’t find others places I can easily fix.