Search code examples
javaandroidcanvasdrawingpixel

Calculate target Pixels from given Angle


What i want :

enter image description here I am using Orientation Sensor to get Azmuth value (Angle). i am also taking starting point from user and draw a circle. Now i want to draw next pixel on the point where the user is heading considering that one step is equal to 30 pixels.

As user starts walking i want to draw circles of user current position on the image of floor plan inserted on screen. I can't use GPS for this solution due to certain reasons.

Here are steps i am performing :

  1. Get current user direction in angles from Orientation sensor.
  2. User will touch on screen to draw starting point on image.
  3. As user starts walking it will draw points on the image relative to user's real world direction like i showed in above image. How can i certainly achieve this given only starting point(pixelX,pixelY) and start angle of user and current angle where he just faced.

What we have achieved so far : We can draw straight lines on 4 angles i.e 0 , 90,180 and 270 by just adding and subtracting pixels to current pixels.

newAzimuth is current angle of user direction

           if (newAzimuth >= 45 && newAzimuth <= 135) {
                startX = startX + oneStepPixelsWidth;
            mScreenRotationTextView.setText("You turned (Right)");
            } else if (newAzimuth > 135 && newAzimuth <= 225) {
            mScreenRotationTextVniew.setText("You turned (Back)");
                startY = startY + oneStepPixelsHeight;
            } else if (newAzimuth > 225 && newAzimuth <= 315) {
            mScreenRotationTextView.setText("You turned (Left)");
                startX = startX - oneStepPixelsWidth;
            } else if (newAzimuth > 315 || newAzimuth < 45) {
            mScreenRotationTextView.setText("You turned (Front)");
                startY = startY - oneStepPixelsHeight;
            }

Solution

  • Given that calculated angles are:

    enter image description here

    Here's the equations for that.

    X=distance*cos(angle)
    Y=distance*sin(angle)
    

    In your case distance will always be 30 pixel

    so (30Cos(Angle),30Sin(Angle)) will give you your location.

    To adjust your calculated angle to work you can rotate them with those formulas;

    adjustedX = x cos(angle) − y sin(angle)
    adjustedY = y cos(angle) + x sin(angle)
    

    By exemple if the angle calculated are like this:

    enter image description here

    Then you will need to;

    1. Rotate 90 degree right or 270 degree left.
    2. Translate.
    3. Rotate 270 degree right or 90 degree left.
     private Pair<Double, Double> getPositionOf(Pair<Double, Double> lastPosition, double angle, int distance, int angleAdjustment)
        {
            final Pair<Double, Double> rotatedLeftPosition = rotateLeft(lastPosition, 360 - angleAdjustment);
            final Pair<Double, Double> translatedLocation = applyTranslationTo(rotatedLeftPosition, angle, distance);
            return rotateLeft(translatedLocation, angleAdjustment);
        }
    
        private Pair<Double, Double> rotateLeft(Pair<Double, Double> position, double degreeAngle)
        {
            double x = position.first;
            double y = position.second;
    
            double adjustedX = (x * Math.cos(degreeAngle)) - (y * Math.sin(degreeAngle));
            double adjustedY = (y * Math.cos(degreeAngle)) + (x * Math.sin(degreeAngle));
            return new Pair<>(adjustedX, adjustedY);
        }
    
        @NotNull
        private Pair<Double, Double> applyTranslationTo(final Pair<Double, Double> position, final double angle, final int distance)
        {
            double x = distance * Math.cos(angle);
            double y = distance * Math.sin(angle);
            return new Pair<>(position.first + x, position.second + y);
        }
    
    

    Where angleAdjustment will be 90