{"record":{"id":"c0def2ea1056a984","repo":"TheAlgorithms/Java","slug":"velocity-height-and-gravity-must-be-non-negative","errorCode":null,"errorMessage":"Velocity, height, and gravity must be non-negative, and gravity must be positive.","messagePattern":"Velocity, height, and gravity must be non-negative, and gravity must be positive\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/physics/ProjectileMotion.java","lineNumber":72,"sourceCode":"     * @param initialHeight Starting height of the projectile (m).\n     * @return A {@link Result} object with the trajectory data.\n     */\n    public static Result calculateTrajectory(double initialVelocity, double launchAngleDegrees, double initialHeight) {\n        return calculateTrajectory(initialVelocity, launchAngleDegrees, initialHeight, GRAVITY);\n    }\n\n    /**\n     * Calculates projectile trajectory with a custom gravity value.\n     *\n     * @param initialVelocity Initial speed (m/s). Must be non-negative.\n     * @param launchAngleDegrees Launch angle (degrees).\n     * @param initialHeight Starting height (m). Must be non-negative.\n     * @param gravity Acceleration due to gravity (m/s^2). Must be positive.\n     * @return A {@link Result} object with the trajectory data.\n     */\n    public static Result calculateTrajectory(double initialVelocity, double launchAngleDegrees, double initialHeight, double gravity) {\n        if (initialVelocity < 0 || initialHeight < 0 || gravity <= 0) {\n            throw new IllegalArgumentException(\"Velocity, height, and gravity must be non-negative, and gravity must be positive.\");\n        }\n\n        double launchAngleRadians = Math.toRadians(launchAngleDegrees);\n        double initialVerticalVelocity = initialVelocity * Math.sin(launchAngleRadians); // Initial vertical velocity\n        double initialHorizontalVelocity = initialVelocity * Math.cos(launchAngleRadians); // Initial horizontal velocity\n\n        // Correctly calculate total time of flight using the quadratic formula for vertical motion.\n        // y(t) = y0 + initialVerticalVelocity*t - 0.5*g*t^2. We solve for t when y(t) = 0.\n        double totalTimeOfFlight = (initialVerticalVelocity + Math.sqrt(initialVerticalVelocity * initialVerticalVelocity + 2 * gravity * initialHeight)) / gravity;\n\n        // Calculate max height. If launched downwards, max height is the initial height.\n        double maxHeight;\n        if (initialVerticalVelocity > 0) {\n            double heightGained = initialVerticalVelocity * initialVerticalVelocity / (2 * gravity);\n            maxHeight = initialHeight + heightGained;\n        } else {\n            maxHeight = initialHeight;\n        }","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/physics/ProjectileMotion.java#L54-L90","documentation":"Thrown by ProjectileMotion.calculateTrajectory when initialVelocity < 0, initialHeight < 0, or gravity <= 0. The trajectory solver uses the quadratic formula and divides by gravity; a negative velocity/height is unphysical for a launch, and non-positive gravity breaks the time-of-flight and max-height calculations. All three conditions share one combined guard, so any one of them triggers this single message.","triggerScenarios":"Calling calculateTrajectory with a negative initialVelocity, a negative initialHeight, or gravity of 0 or negative. A velocity or height of exactly 0 is allowed (only gravity must be strictly positive).","commonSituations":"Config defaulting gravity to 0 in a test, a sign error on height when the object starts below ground level modelled as negative, or a UI form that allowed a negative speed value through.","solutions":["Pass non-negative initialVelocity (m/s) and initialHeight (m), and strictly positive gravity (m/s^2, ~9.81 on Earth).","Validate the three inputs separately in your UI/parse layer so you can report which one was wrong rather than one combined message.","If modelling a launch from below origin, shift the coordinate frame so initialHeight stays non-negative."],"exampleFix":"// before\nResult r = ProjectileMotion.calculateTrajectory(-10, 45, 0, 9.81);\n// after\nResult r = ProjectileMotion.calculateTrajectory(10, 45, 0, 9.81);","handlingStrategy":"validation","validationCode":"if (initialVelocity < 0 || initialHeight < 0 || !(gravity > 0)) {\n    // report which field failed to the user\n    throw new IllegalArgumentException(\"invalid launch parameters\");\n}\nResult r = ProjectileMotion.calculateTrajectory(initialVelocity, launchAngleDegrees, initialHeight, gravity);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the three inputs separately in the UI so you can name the offending field.","Default gravity to 9.81 rather than 0 in config templates.","Reject negative speeds at the form layer before reaching the physics call."],"tags":["java","physics","parameter-validation","projectile-motion","illegal-argument"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}