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:
area(): A method that calculates and returns the area of the rectangle.perimeter(): A method that calculates and returns the perimeter of the rectangle.contains(point): A method that takes anotherPointstruct as an argument and returnstrueif the given point lies within or on the boundary of the rectangle, andfalseotherwise.
You will also need to define a Point struct to represent coordinates.
Key Requirements
- Define a
Pointstruct withxandyfields (floating-point numbers). - Define a
Rectanglestruct withbottom_leftandtop_rightfields, both of typePoint. - Implement the
area()method forRectangle. - Implement the
perimeter()method forRectangle. - Implement the
contains(point)method forRectangle. - All methods should take
&selfas 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.xorbottom_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 wherebottom_leftis indeed the bottom-left andtop_rightis 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
xandycoordinates will be within the range of standard floating-point types (e.g.,f64).- Input
Rectanglestructs will havebottom_left.x <= top_right.xandbottom_left.y <= top_right.y. - Calculations should be performed using
f64for precision. - Performance is not a primary concern for this challenge; correctness is paramount.
Notes
- Remember to derive
Debugand potentiallyCopy/Clonefor your structs if you find it convenient for testing and usage. - Consider how to calculate width and height from the
bottom_leftandtop_rightpoints. - For the
containsmethod, ensure your logic correctly handles all boundary conditions.