Why the angle moves lagging behind the dot - manim

There is a grouped angle (two lines and a arc) moving and rotating at the same time, depending on the location of another Dot, from the video, the grouped angle is lagged behind the Dot, don't know why? below is the code:
class MovRot(Scene):
def construct(self):
ln = Line(LEFT*2, LEFT*1+UP*1.5)
self.add(ln)
ln_ab = Line(LEFT*2, interpolate(LEFT*2, LEFT*1+UP*1.5, 0.7), color=RED_D)
ln_bc = Line(LEFT*2, ORIGIN, color=RED_D)
arc_b = Arc(0, ln_ab.get_angle(), radius=0.6, color=RED_D).move_arc_center_to(LEFT*2)
grp_b = VGroup(ln_ab, ln_bc, arc_b)
self.add(grp_b)
dt = Dot(color=YELLOW_D).move_to(LEFT*2)
grp_1 = grp_b.copy()
def update_grp1(mob, alpha):
mob.become(grp_1)
mob.move_to(dt.get_center(), aligned_edge=arc_b.get_arc_center())
mob.rotate(alpha*PI, about_point=arc_b.get_arc_center())
self.add(grp_1, dt)
self.play(UpdateFromAlphaFunc(grp_b, update_grp1, rate_func=smooth), dt.move_to, LEFT*1+UP*1.5,
rate_func=smooth,
run_time=2)
Thanks for any help.

You always have to write the "master" animation at the beginning of the play method, in your case, the animation that "takes the baton" is move_to, so it must be the first to be written:
self.play(
dt.move_to, LEFT*1+UP*1.5,
UpdateFromAlphaFunc(grp_b, update_grp1, rate_func=smooth),
rate_func=smooth,
run_time=2
)

Related

How to have multiple dots move at constant speed around a circle in manim?

I want to reproduce the animation here in manim.
I found how to have multiple dots move along a circle, but they only do one turn and don't have constant speed.
How to have them move at constant speed and do multiple turns ?
Here is my attempt up to now :
def construct(self):
circle = Circle()
points = Group(*[Dot((1, 0, 0)) for _ in range(2)])
self.add(circle)
self.add(points)
self.play(
MoveAlongPath(points[0], circle, run_time=1),
MoveAlongPath(points[1], circle, run_time=2)
)
Just found an answer, easier than I thought :
self.play(Rotating(points[0],
radians=2 * TAU,
about_point=ORIGIN),
Rotating(points[1],
radians=TAU,
about_point=ORIGIN),
)

Zoom into scene using transition - Corona

Hey so I am looking for something similar to in tennis when players challenge a point and the video shows whether the ball was in or out by zooming in really really close to the moment when the ball lands to see whether a fraction was on the line.
I have experimented with using transitions with xScale and yScale but the results I get is strange, almost as if the objects have moved during zooming in. If there was a way to lock in position and then zoom, that would work. The second method I tried is putting the graphics into a display group and then scaling the group. This also results in weird behaviour where the whole group begins moving diagonally across the screen.
Please help as this is confusing me
cheers.
Objects which will scale:
cloud = display.newImageRect("cloud.png", 419,273)
cloud.anchorY = 0
cloud.anchorX = 0.5
cloud.alpha = 1
cloud.x = display.contentCenterX
cloud.y = display.contentCenterY + 250
physics.addBody(cloud, {isSensor=true})
star = display.newImageRect("Star.png", 78,72)
star.anchorY = 0
star.anchorX = 0.5
star.alpha = 1
star.name = "Star"
physics.addBody(star, {isSensor=true})
star.x = display.contentCenterX
star.y = display.actualContentHeight - display.actualContentHeight - 100
Scale Function
function scale( event )
transition.to(star, {time=2000, xScale=1.5, yScale = 1.5})
transition.to(cloud, {time=2000, xScale=1.5, yScale=1.5})
end
When you scale an object, it may "move" due to its anchor position, which is the position of the object that is used to position it and also works as its 'anchor' during rotation or scale.
So, you have 2 options:
1) Set the anchor position (obj.anchorX = value , obj.anchorY = value ) to the one that will make your object stays in the position that you want;
2) During the transition, also change its x and y to compensate the moving.

Box2D: How to use b2ChainShape for a tile based map with squares

Im fighting here with the so called ghost collisions on a simple tile based map with a circle as player character.
When applying an impulse to the circle it first starts bouncing correctly, then sooner or later it bounces wrong (wrong angle).
Looking up on the internet i read about an issue in Box2D (i use iOS Swift with Box2d port for Swift).
Using b2ChainShape does not help, but it looks i misunderstood it. I also need to use the "prevVertex" and "nextVertex" properties to set up the ghost vertices.
But im confused. I have a simple map made up of boxes (simple square), all placed next to each other forming a closed room. Inside of it my circle i apply an impulse seeing the issue.
Now WHERE to place those ghost vertices for each square/box i placed on the view in order to solve this issue? Do i need to place ANY vertex close to the last and first vertice of chainShape or does it need to be one of the vertices of the next box to the current one? I dont understand. Box2D's manual does not explain where these ghost vertices coordinates are coming from.
Below you can see an image describing the problem.
Some code showing the physics parts for the walls and the circle:
First the wall part:
let bodyDef = b2BodyDef()
bodyDef.position = self.ptm_vec(node.position+self.offset)
let w = self.ptm(Constants.Config.wallsize)
let square = b2ChainShape()
var chains = [b2Vec2]()
chains.append(b2Vec2(-w/2,-w/2))
chains.append(b2Vec2(-w/2,w/2))
chains.append(b2Vec2(w/2,w/2))
chains.append(b2Vec2(w/2,-w/2))
square.createLoop(vertices: chains)
let fixtureDef = b2FixtureDef()
fixtureDef.shape = square
fixtureDef.filter.categoryBits = Constants.Config.PhysicsCategory.Wall
fixtureDef.filter.maskBits = Constants.Config.PhysicsCategory.Player
let wallBody = self.world.createBody(bodyDef)
wallBody.createFixture(fixtureDef)
The circle part:
let bodyDef = b2BodyDef()
bodyDef.type = b2BodyType.dynamicBody
bodyDef.position = self.ptm_vec(node.position+self.offset)
let circle = b2CircleShape()
circle.radius = self.ptm(Constants.Config.playersize)
let fixtureDef = b2FixtureDef()
fixtureDef.shape = circle
fixtureDef.density = 0.3
fixtureDef.friction = 0
fixtureDef.restitution = 1.0
fixtureDef.filter.categoryBits = Constants.Config.PhysicsCategory.Player
fixtureDef.filter.maskBits = Constants.Config.PhysicsCategory.Wall
let ballBody = self.world.createBody(bodyDef)
ballBody.linearDamping = 0
ballBody.angularDamping = 0
ballBody.createFixture(fixtureDef)
Not sure that I know of a simple solution in the case that each tile can potentially have different physics.
If your walls are all horizontal and/or vertical, you could write a class to take a row of boxes, create a single edge or rectangle body, and then on collision calculate which box (a simple a < x < b test) should interact with the colliding object, and apply the physics appropriately, manually calling the OnCollision method that you would otherwise specify as the callback for each individual box.
Alternatively, to avoid the trouble of manually testing intersection with different boxes, you could still merge all common straight edge boxes into one edge body for accurate reflections. However, you would still retain the bodies for the individual boxes. Extend the boxes so that they overlap the edge.
Now here's the trick: all box collision handlers return false, but they toggle flags on the colliding object (turning flags on OnCollision, and off OnSeparation). The OnCollision method for the edge body then processes the collision based on which flags are set.
Just make sure that the colliding body always passes through a box before it can touch an edge. That should be straightforward.

Keeping Direction of a Vector Constant while Rotating Sprite

I'm trying to make a game where the sprite will always move to the right when hit by an object. However since the Sprite rotates constantly and the zero radians rotates with the Sprite causes my calculated magnitude to go the opposite direction if the sprite is facing left and hits the object. Is there a way to keep the direction of the magnitude always pointing to the right even if the zero is facing left?
// referencePoint = upper right corner of the frame
let rightTriangleFinalPoint:CGPoint = CGPoint(x: referencePoint.x, y: theSprite.position.y)
let theSpriteToReferenceDistance = distanceBetweenCGPoints(theSprite.position, b: referencePoint)
let theSpriteToFinalPointDistance = distanceBetweenCGPoints(theSprite.position, b: rightTriangleFinalPoint)
let arcCosineValue = theSpriteToFinalPointDistance / theSpriteToReferenceDistance
let angle = Double(acos(arcCosineValue))
let xMagnitude = magnitude * cos(angle)
let yMagnitude = (magnitude * sin(angle)) / 1.5
Not sure if this works for you:
I would use an orientation constraint to rotate the sprite. The movement can be done independent from the orientation in that case.
I made an tutorial some time ago: http://stefansdevplayground.blogspot.de/2014/09/howto-implement-targeting-or-follow.html
So I figured out what was going on.
It seems like the angle doesn't rotate with the Sprite like I originally thought and the vector that I am making is working with the code above. THE problem that I had was that I also set the collision bit for the objects which is wrong. If I only set the contact bit for the objects against the sprite the my desired outcome comes true.

CGPointEqualToPoint not working

I am making an app in which I want to have some thing happen If an image moves over another point. such as
first I have an image moving horizontally across the screen,'
self.ball.center = CGPointMake(self.ball.center.x + self.gravity.x / 8.0 * 200.0, 9);
then when it gets to a certain place another image moves down from that spot.
CGPoint a = CGPointMake(9, 9);
if (CGPointEqualToPoint(ball.center,a)) {
balla.hidden = NO;
self.balla.center = CGPointMake(self.balla.center.x , (self.balla.center.y)- (self.gravity.y / 8.0 * 200.0));
}
the first time it works ok but when I put in the next statement to move another image down from another spot nothing happens.
CGPoint b = CGPointMake(86, 9);
if (CGPointEqualToPoint(ball.center,b)) {
ball2a.hidden = NO;
self.ball2a.center = CGPointMake(self.ball2a.center.x , (self.ball2a.center.y)- (self.gravity.y / 8.0 * 200.0));}
Any ideas as to why this isn't working
If you're moving the ball by adding some floating-point value offset, you might be "skipping over" the point b - you may never hit b, but rather appear slightly before it and then slightly after it.
Rather than testing if you're "equal" to the point, you could be better off comparing the distance between the ball and the point and seeing if it is inside some small radius. A simple euclidean distance could work.
CGFloat euclid_dist(CGPoint a, CGPoint b)
{
return sqrt((b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y-a.y));
}
You could then use this to see if you've "hit" the point:
if (euclid_dist(ball.center, b) < 0.1)
{
// React appropriately
}
In general it's problematic to test for equality between floating point numbers.

Resources