0
votes

I've got what I thought was a simple question, yet the solution eludes me. The premise of the problem is simple: I have a view (call it a point) with center vx, vy that I want to rotate around a bigger circle cx, cy. I've looked into using sin, cos, radians, atan2, all that jazz, yet for some reason when I rotate my views, it looks as if it's rotating in an oval and not a circle. The math for this eludes me.

What I have so far:

public void update(double matrixAngle) 
        double angleInDegs = Math.toDegrees(mAngle);
        double newAngle = (matrixAngle > 0) ? angleInDegs + matrixAngle : angleInDegs - matrixAngle;
        double angleInRads = Math.toRadians(newAngle);

        float dx = itemCircle.getCenterX() - getCenterX();
        float dy = itemCircle.getCenterY() - getCenterY();
        double radius = Math.sqrt(dx * dx + dy * dy);

        float x = (float) (getCenterX() + radius * Math.cos(angleInRads));
        float y = (float) (getCenterY() - radius * Math.sin(angleInRads));

        itemCircle.setCenterX(x);
        itemCircle.setCenterY(y);

For some clarification:

matrixAngle parameter of the method is the matrix angle used to rotate the entire view. It ranges from 0-180, then from -180 to 0, where 0 is opening from the right-side of the circle.

mAngle is the original angle that the view was drawn at. It ranges from 0 to 360.

itemCircle is the circle representing the view's bounds. It is a circle (an extended FloatingActionButton, to be exact).

getCenterX(), getCenterY() are the coords of the bigger circle that I want to rotate around.

I'd really appreciate some help here. This problem has been bugging me for a day now.

2
May be you can try object animator.Deepak Goyal
That's the issue. I would, but I need to update the touch coordinates of each view (which I will using its itemCircle) because I need to have them respond to click events and fire my click listener.Miles Peele

2 Answers

0
votes

Your object is moving in an ellipse shape because the pixels aren't square. Notice that in class DisplayMetrics, there are actually different values for xdpi and ydpi. You'll need to adjust your computation to account for this.

0
votes

Got it. Involved looking more closely at cos, sin angles to achieve what I wanted. Working code:

public void update(double matrixAngle) {
        double angleInRads = Math.toRadians(matrixAngle);

        double cosAngle = Math.cos(angleInRads);
        double sinAngle = Math.sin(angleInRads);

        float dx = mItemCircle.getCenterX() - getCenterX();
        float dy = mItemCircle.getCenterY() - getCenterY();

        float rx = (float) (dx * cosAngle - dy * sinAngle);
        float ry = (float) (dx * sinAngle + dy * cosAngle);

        rx += getCenterX();
        ry += getCenterY();

        mItemCircle.setCenterX(rx);
        mItemCircle.setCenterY(ry);
}