How Can we rotate the ENDLESS running background? - cocos2d-android

Below the code have ability to endless background rotation from upward to downward direction OR something else way.
I just want opposite from this rotation. I tried but could solve this problem.
Anybody suggest me , how to do this ?
private void animateBackground() {
_oddBackground = CCSprite.sprite("sky.png");
_evenBackground = CCSprite.sprite("sky.png");
/*from Upward to Downward direction background rotation */
_oddBackground.setPosition(winSize.width / 2, winSize.height / 2);
_evenBackground.setPosition(winSize.width / 2, winSize.height + (winSize.height / 2));
schedule("scroll");
addChild(_oddBackground).addChild(_evenBackground);
}
public void scroll(float dt) {
// move them 100*dt pixels down
_oddBackground.setPosition(_oddBackground.getPosition().x, _oddBackground.getPosition().y - 100 * dt);
_evenBackground.setPosition(_evenBackground.getPosition().x, _evenBackground.getPosition().y - 100 * dt);
// reset position when they are off from view.
if (_oddBackground.getPosition().y < - winSize.height / 2) {
_oddBackground.setPosition(winSize.width / 2, winSize.height / 2);
_evenBackground.setPosition(winSize.width / 2, winSize.height+ (winSize.height / 2));
}
}

Related

Rotating a vector around a point

I've looked around here for some answers on this, I've found a few good ones, but when I implement them in my code, I get some unexpected results.
Here's my problem:
I'm creating a top down geometry shooter, and when an enemy is hit by a bullet, the enemy should explode into smaller clones, shooting out from the center of the enemy in a circular fashion, in even intervals around the enemy. I assumed I could accomplish this by getting an initial vector, coming straight out of the side of the enemy shape, then rotate that vector the appropriate amount of times. Here's my code:
void Game::spawnSmallEnemies(s_ptr<Entity> e)
{
int vertices = e->cShape->shape.getPointCount();
float angle = 360.f / vertices;
double conv = M_PI / 180.f;
double cs = cos(angle * (M_PI / 180));
double sn = sin(angle * (M_PI / 180));
// Radius of enemy shape
Vec2 velocity { e->cTransform->m_pos.m_x + m_enemyCfg.SR , e->cTransform->m_pos.m_y} ;
velocity = velocity.get_normal();
Vec2 origin {e->cTransform->m_pos};
for (int i = 0; i < vertices; i++)
{
auto small = m_entityMgr.addEntity("small");
small->cTransform = std::make_shared<CTransform>(origin, velocity * 3, 0);
small->cShape = std::make_shared<CShape>(m_enemyCfg.SR / 4, vertices,
e->cShape->shape.getFillColor(), e->cShape->shape.getOutlineColor(),
e->cShape->shape.getOutlineThickness(), small->cTransform->m_pos);
small->cCircleCollider = std::make_shared<CCircleCollider>(m_enemyCfg.SR / 4);
small->cLife = std::make_shared<CLifespan>(m_enemyCfg.L);
velocity.m_x = ((velocity.m_x - origin.m_x) * cs) - ((origin.m_y - velocity.m_y) * sn) + origin.m_x;
velocity.m_y = origin.m_y - ((origin.m_y - velocity.m_y) * cs) + ((velocity.m_x - origin.m_x) * sn);
}
}
I got the rotation code at the bottom from this post, however each of the smaller shapes only shoot toward the bottom right, all clumped together. I would assume my error is logic, however I have been unable to find a solution.

How to have text centered inside each slice of a pie chart?

I would like to get the text labels (percentages) centered within each pie slice. It currently works a bit for two of the quadrants:
What am I doing wrong?
void PieChartWidget::paintEvent(QPaintEvent *) {
QPainter painter(this);
QRectF size;
painter.setPen(QPen(Qt::black, 2));
if (this->height() > this->width()) {
size = QRectF(5, 5, this->width() - 10, this->width() - 10);
} else {
size = QRectF(5, 5, this->height() - 5, this->height() - 10);
}
double sum = 0.0, startAng = 0.0;
double angle, endAng;
double percent;
for (int i = 0; i < qvValues.size(); i++) {
sum += qvValues[i];
}
for (int i = 0; i < qvValues.size(); i++) {
percent = qvValues[i] / sum;
angle = percent * 360.0;
endAng = startAng + angle;
painter.setBrush(qvColors[i]);
painter.drawPie(size, static_cast<int>(startAng * 16),
static_cast<int>(angle * 16));
startAng = endAng;
if (percent != 0) {
double draw_x = width() / 2 +
cos(PI * (endAng / 180.0 - angle / 360.0)) * this->width() / 4.0;
double draw_y = height() / 2 +
sin(PI * (endAng / 180.0 - angle / 360.0)) * this->width() / 4.0;
painter.drawText(draw_x, draw_y, QString::number(percent * 100) + "%");
}
}
}
On this line:
painter.drawText(this->width()/4,this->height(), QString::number(percent*100)+"%");
You seem to draw the percentage in the same place every time. You do successfully draw the percentage for each section, they're just being drawn in the same place every time. Try changing it to this:
painter.drawText(double(i + 1) * this->width()/4,this->height(), QString::number(percent*100)+"%");
And you'll see what I mean. By multiplying the x value by some changing value, the x position of each drawn text will change, and thus you will be able to see the different percentages being drawn.
If you want it to draw in each quadrant, then your code might look something like this:
# define PI 3.14159265358979323846
...
double draw_x = this->width / 2.0 + cos(PI * (end_angle / 180.0 - angle / 360.0)) * this->width / 4.0;
double draw_y = this->height / 2.0 - sin(PI * (end_angle / 180.0 - angle / 360.0)) * this->width / 4.0;
painter.drawText(draw_x, draw_y, QString::number(percent*100)+"%");
Basically, what's happening in the above code is I'm calculating the x and y coords of the middle of each slice. Then, I'm drawing the percentages in those positions.

Triangle rotation causes deformation

I would like to rotate my triangle but there are some problems.
Its default form:
I am rotating it with my arrow keys but as you see it has some deformations on shape of triangle:
Here is my code:
typedef struct {
point_t pos; // position of the triangle
float angle; // view angle
float r;
} weapon_t;
void drawPlayer(weapon_t tw) {
glBegin(GL_TRIANGLES);
glColor3f(0.1, 0.2, 0.3);
glVertex2f(tw.pos.x, tw.pos.y);
glVertex2f(tw.pos.x + 150 * cos(tw.angle * D2R), tw.pos.y + 100 * sin(tw.angle * D2R) + 8);
glVertex2f(tw.pos.x + 150 * cos(tw.angle * D2R), tw.pos.y + 100 * sin(tw.angle * D2R) - 8);
glEnd();
}
void onTimer(int v) {
glutTimerFunc(TIMER_PERIOD, onTimer, 0);
if (right) {
if (weapon.angle != -45)
turnWeapon(&weapon, -3);
}
if (left) {
if (weapon.angle != 45)
turnWeapon(&weapon, 3);
}
Any idea guys?
I don't know where you got your formulas from but they are wrong. To rotate a 2D vector anti-clockwise around angle x you can use the rotation matrix [cos(x), -sin(x) ; sin(x), cos(x)] (you can prove this easily with exp(i*x) = cos(x) + i*sin(x)). You want to rotate the vectors [150, 108] and [150, 92] if you multiply those by the rotation matrix you get [150*cos(x) - 108*sin(x), 150*sin(x) + 108*cos(x)] and [150*cos(x) - 92*sin(x), 150*sin(x) + 92*cos(x)].
Translated into code this looks like this:
float c = cos(tw.angle * D2R);
float s = sin(tw.angle * D2R);
glVertex2f(tw.pos.x + 150*c - 108*s, tw.pos.y + 150*s + 108*c);
glVertex2f(tw.pos.x + 150*c - 92*s, tw.pos.y + 150*s + 92*c);

Getting sprite to follow mouse, weird glitch when using views

I was wondering if anyone could help me. My sprite was following my mouse fine until i started using views i am just starting using SFML, to make the sprite follow my player i used this.
void player::rotateToMouse(sf::Sprite &sprite, sf::RenderWindow &window)
{
this->mouse = sf::Mouse::getPosition(window);
const float PI = 3.14159265;
float a = playerPosition.x - mouse.x;
float b = playerPosition.y - mouse.y;
mouseAngle = (atan2(b, a)) * 180 / PI;
playerSprite.setRotation(mouseAngle + 180);
}
I am adding this code in my update method, like so,
void player::update(sf::RenderWindow &window){
this->rotateToMouse(playerSprite, window);
this->followPlayer();
I am setting my views like this,
void player::followPlayer(){
view.reset(sf::FloatRect(0, 0, 32 + 10, 32 + 10));
view.zoom(15);
view.setCenter(playerSprite.getPosition());
}
and my movement code is this,
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)){
playerSprite.move(std::cos(3.14159265 * mouseAngle / 180.f) * speed *-1, std::sin(3.14159265 * mouseAngle / 180.f) * speed *-1);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)){ //Speed
playerSprite.move(std::cos(3.14159265 * mouseAngle / 180.f) * speed , std::sin(3.14159265 * mouseAngle / 180.f) * speed );
}
this->playerPosition = playerSprite.getPosition();
I can see the sprite is facing slightly off and after a while he starts to spin round randomly, i am quite a noob at c++ and if anyone could help me it would be appreciated.
You need to use sf::RenderTarget::mapPixelToCoords. Basically you need to change how you compute the mouse position from:
this->mouse = sf::Mouse::getPosition(window);
to
this->mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));

OpenCV How to Plot velocity vectors as arrows in using single static image

I am trying to plot velocity vectors like in matlab we use "quiver" function http://www.mathworks.com/help/techdoc/ref/quiver.html
I need to port same methodology in C++ using OpenCV library.
I have heard There are a few optical flow methods, i.e. Lucas and Kanade (cvCalOpticalFlowLK) or Horn and Schunck (cvCalOpticalFlowHS) or Block Matching method (cvCalOpticalFlowBM)
but all of these functions take two images , while i need to use one image because i am working on fingerprints.
Kindly help me ...
[Edit]
Solution found
void cvQuiver(IplImage*Image,int x,int y,int u,int v,CvScalar Color,
int Size,int Thickness){
cv::Point pt1,pt2;
double Theta;
double PI = 3.1416;
if(u==0)
Theta=PI/2;
else
Theta=atan2(double(v),(double)(u));
pt1.x=x;
pt1.y=y;
pt2.x=x+u;
pt2.y=y+v;
cv::line(Image,pt1,pt2,Color,Thickness,8); //Draw Line
Size=(int)(Size*0.707);
if(Theta==PI/2 && pt1.y > pt2.y)
{
pt1.x=(int)(Size*cos(Theta)-Size*sin(Theta)+pt2.x);
pt1.y=(int)(Size*sin(Theta)+Size*cos(Theta)+pt2.y);
cv::line(Image,pt1,pt2,Color,Thickness,8); //Draw Line
pt1.x=(int)(Size*cos(Theta)+Size*sin(Theta)+pt2.x);
pt1.y=(int)(Size*sin(Theta)-Size*cos(Theta)+pt2.y);
cv::line(Image,pt1,pt2,Color,Thickness,8); //Draw Line
}
else{
pt1.x=(int)(-Size*cos(Theta)-Size*sin(Theta)+pt2.x);
pt1.y=(int)(-Size*sin(Theta)+Size*cos(Theta)+pt2.y);
cv::line(Image,pt1,pt2,Color,Thickness,8); //Draw Line
pt1.x=(int)(-Size*cos(Theta)+Size*sin(Theta)+pt2.x);
pt1.y=(int)(-Size*sin(Theta)-Size*cos(Theta)+pt2.y);
cv::line(Image,pt1,pt2,Color,Thickness,8); //Draw Line
}
}
I am kind of completing the current answer here, which fails in giving the right size of each of the arrows' tip. MATLAB does it in a way that when an arrow is nearly a dot, it doesn't have any tip, while for long arrows it shows a big tip, as the following image shows.
To get this effect, we need to normalise the "tip size" of each of the arrow over the range of arrows' length. The following code does the trick
double l_max = -10;
for (int y = 0; y < img_sz.height; y+=10) // First iteration, to compute the maximum l (longest flow)
{
for (int x = 0; x < img_sz.width; x+=10)
{
double dx = cvGetReal2D(velx, y, x); // Gets X component of the flow
double dy = cvGetReal2D(vely, y, x); // Gets Y component of the flow
CvPoint p = cvPoint(x, y);
double l = sqrt(dx*dx + dy*dy); // This function sets a basic threshold for drawing on the image
if(l>l_max) l_max = l;
}
}
for (int y = 0; y < img_sz.height; y+=10)
{
for (int x = 0; x < img_sz.width; x+=10)
{
double dx = cvGetReal2D(velx, y, x); // Gets X component of the flow
double dy = cvGetReal2D(vely, y, x); // Gets Y component of the flow
CvPoint p = cvPoint(x, y);
double l = sqrt(dx*dx + dy*dy); // This function sets a basic threshold for drawing on the image
if (l > 0)
{
double spinSize = 5.0 * l/l_max; // Factor to normalise the size of the spin depeding on the length of the arrow
CvPoint p2 = cvPoint(p.x + (int)(dx), p.y + (int)(dy));
cvLine(resultDenseOpticalFlow, p, p2, CV_RGB(0,255,0), 1, CV_AA);
double angle; // Draws the spin of the arrow
angle = atan2( (double) p.y - p2.y, (double) p.x - p2.x );
p.x = (int) (p2.x + spinSize * cos(angle + 3.1416 / 4));
p.y = (int) (p2.y + spinSize * sin(angle + 3.1416 / 4));
cvLine( resultDenseOpticalFlow, p, p2, CV_RGB(0,255,0), 1, CV_AA, 0 );
p.x = (int) (p2.x + spinSize * cos(angle - 3.1416 / 4));
p.y = (int) (p2.y + spinSize * sin(angle - 3.1416 / 4));
cvLine( resultDenseOpticalFlow, p, p2, CV_RGB(0,255,0), 1, CV_AA, 0 );
}
}
}
And this is an example of how this OpenCV code would look like
I hope this help other people Googling for the same issue.
Based on the code from Dan and the suggestion of mkuse, here is a function with the same syntax as cv::line():
static void arrowedLine(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness=1, int line_type=8, int shift=0, double tipLength=0.1)
{
const double tipSize = norm(pt1-pt2)*tipLength; // Factor to normalize the size of the tip depending on the length of the arrow
line(img, pt1, pt2, color, thickness, line_type, shift);
const double angle = atan2( (double) pt1.y - pt2.y, (double) pt1.x - pt2.x );
Point p(cvRound(pt2.x + tipSize * cos(angle + CV_PI / 4)),
cvRound(pt2.y + tipSize * sin(angle + CV_PI / 4)));
line(img, p, pt2, color, thickness, line_type, shift);
p.x = cvRound(pt2.x + tipSize * cos(angle - CV_PI / 4));
p.y = cvRound(pt2.y + tipSize * sin(angle - CV_PI / 4));
line(img, p, pt2, color, thickness, line_type, shift);
}
We will see if those maintaining the OpenCV repository will like it :-)
The cvCalOpticalFlowLK does not plot velocity vectors, it computes these velocity vectors. If you do not have these vectors, you must call this function with two images. I guess you already have these vectors, and you just want to plot them.
In this case, you can use the cv::line function, for example:
cv::line(yourImage, cv::Point(baseX, baseY), cv::Point(endX, endY));
I hope this will help you!