Hone logo
Hone
Problems

Managing Geometric Shapes with Struct Methods in Rust

This challenge will test your understanding of how to define and implement methods for structs in Rust. You'll create a Rectangle struct and then add methods to calculate its area and perimeter, as well as a method to check if it contains another point. This is a fundamental skill for organizing data and behavior in Rust.

Problem Description

You are tasked with creating a Rectangle struct that represents a geometric rectangle. This struct should store the coordinates of its bottom-left and top-right corners. You will then implement several methods for this struct:

  1. area(): A method that calculates and returns the area of the rectangle.
  2. perimeter(): A method that calculates and returns the perimeter of the rectangle.
  3. contains(point): A method that takes another Point struct as an argument and returns true if the given point lies within or on the boundary of the rectangle, and false otherwise.

You will also need to define a Point struct to represent coordinates.

Key Requirements

  • Define a Point struct with x and y fields (floating-point numbers).
  • Define a Rectangle struct with bottom_left and top_right fields, both of type Point.
  • Implement the area() method for Rectangle.
  • Implement the perimeter() method for Rectangle.
  • Implement the contains(point) method for Rectangle.
  • All methods should take &self as their first parameter where appropriate.

Expected Behavior

  • area() should return a floating-point number representing the area.
  • perimeter() should return a floating-point number representing the perimeter.
  • contains(point) should correctly identify points inside, outside, and on the boundaries of the rectangle.

Important Edge Cases

  • Rectangles with zero width or height.
  • Points exactly on the edges or corners of the rectangle.
  • Rectangles where bottom_left.x > top_right.x or bottom_left.y > top_right.y (these should be handled gracefully, perhaps by assuming the user intended to swap them or by returning an error/specific value, though for this challenge, we'll assume valid inputs where bottom_left is indeed the bottom-left and top_right is the top-right).

Examples

Example 1:

let p1 = Point { x: 0.0, y: 0.0 };
let p2 = Point { x: 5.0, y: 10.0 };
let rect = Rectangle { bottom_left: p1, top_right: p2 };

println!("Area: {}", rect.area());
println!("Perimeter: {}", rect.perimeter());

Output:

Area: 50.0
Perimeter: 30.0

Explanation: The rectangle spans from (0,0) to (5,10). The width is 5.0 and the height is 10.0. Area = width * height = 5.0 * 10.0 = 50.0. Perimeter = 2 * (width + height) = 2 * (5.0 + 10.0) = 30.0.

Example 2:

let p1 = Point { x: 0.0, y: 0.0 };
let p2 = Point { x: 5.0, y: 10.0 };
let rect = Rectangle { bottom_left: p1, top_right: p2 };

let inside_point = Point { x: 2.5, y: 5.0 };
let outside_point = Point { x: 6.0, y: 5.0 };
let on_edge_point = Point { x: 5.0, y: 7.5 };

println!("Contains (2.5, 5.0): {}", rect.contains(inside_point));
println!("Contains (6.0, 5.0): {}", rect.contains(outside_point));
println!("Contains (5.0, 7.5): {}", rect.contains(on_edge_point));

Output:

Contains (2.5, 5.0): true
Contains (6.0, 5.0): false
Contains (5.0, 7.5): true

Explanation:

  • (2.5, 5.0) is within the rectangle.
  • (6.0, 5.0) is outside the rectangle.
  • (5.0, 7.5) is on the right edge of the rectangle, which is considered contained.

Example 3: (Zero width/height rectangle)

let p1 = Point { x: 3.0, y: 4.0 };
let p2 = Point { x: 3.0, y: 4.0 }; // A single point, essentially a rectangle with zero width and height
let rect = Rectangle { bottom_left: p1, top_right: p2 };

let point_on = Point { x: 3.0, y: 4.0 };
let point_off = Point { x: 3.1, y: 4.0 };

println!("Area: {}", rect.area());
println!("Perimeter: {}", rect.perimeter());
println!("Contains (3.0, 4.0): {}", rect.contains(point_on));
println!("Contains (3.1, 4.0): {}", rect.contains(point_off));

Output:

Area: 0.0
Perimeter: 0.0
Contains (3.0, 4.0): true
Contains (3.1, 4.0): false

Explanation: A rectangle defined by the same point has zero area and perimeter. It only contains the exact point it represents.

Constraints

  • x and y coordinates will be within the range of standard floating-point types (e.g., f64).
  • Input Rectangle structs will have bottom_left.x <= top_right.x and bottom_left.y <= top_right.y.
  • Calculations should be performed using f64 for precision.
  • Performance is not a primary concern for this challenge; correctness is paramount.

Notes

  • Remember to derive Debug and potentially Copy/Clone for your structs if you find it convenient for testing and usage.
  • Consider how to calculate width and height from the bottom_left and top_right points.
  • For the contains method, ensure your logic correctly handles all boundary conditions.
Loading editor...
rust