Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify and test properties of Rectangle #27

Open
skaldarnar opened this issue Apr 2, 2021 · 4 comments
Open

Clarify and test properties of Rectangle #27

skaldarnar opened this issue Apr 2, 2021 · 4 comments

Comments

@skaldarnar
Copy link
Member

skaldarnar commented Apr 2, 2021

Currently, our primitives use a closed interval semantics, i.e., both min and max are included.

To avoid confusion about floating point rounding to integer domain we do not offer floating-point variants of methods on integer primitives, e.g., we don't offer contains(float) and similar methods with floating points on Rectanglei.

As I like the idea of testing based on properties and invariants here's what I got from the review of #23, plus a few additional things (as discussed on Discord with @pollend and @4Denthusiast):

Let A, B, C be rectangles, and let p be a point. Let ∅ denote an invalid rectangle without size.

  • isValid

    • if min ≤ max
  • lenght/area

    • Rectanglei: number of discrete integer points
    • count(rect.iterable) == rect.area == rect.sizeX * rect.sizeY

    ⚠️ Rectanglei is not iterable, and we cannot get the contained discrtete points...

  • contains/intersection

    • iff p ∈ A && p ∈ B ⇒ p ∈ A ∩ B
    • ∀ p ∈ A ∩ B ⇒ p ∈ A && p ∈ B
    • B ⊆ A, p ∈ B ⇒ p ∈ A
    • B ⊆ A, C ⊆ B ⇒ C ⊆ A
    • maxₐ ∈ A, minₐ ∈ A (closed interval)
  • intersection

    • A ∩ A == A
    • A.intersects(B) == (A ∩ B ≠ ∅), where A.intersects(B) is the test for intersection
  • union

    • A ⊆ (A ∪ B)
    • B ⊆ (A ∪ B)
    • A ∪ A == A
  • Rectangled/f

    • bounds are inclusive
    • we cannot count the points inside a rectangle, so the same test as above does not work
@skaldarnar
Copy link
Member Author

(more notes from Discord conversation)

From the invariants and properties we defined before the following assumptions should hold:

// 1) rectangle from point should be valid, since min <= max
assertTrue(rect.isValid())

// 2) rectangle from point should contain the point 
assertTrue(rect.contains(0, 0));

// 3) area of rectangle should be number of discrete integer points 
assertEquals(1, rect.area())

// 4) area of rectanlge should be equal to width x height
assertEquals(rect.area(), rect.getSizeX() * rect.getSizeY())

From 3) and 4) it follows that the size cannot be 'max - min'. Instead, it must be 'max - min + 1'. This would need to change the current semantics max is inclusive).

The last point leads to questions on how the discrete Rectanglei relates to the continuous Rectangled/f. We cannot compute the area and size the same way, so we would be inconsinstent there.

@skaldarnar
Copy link
Member Author

Half-open intervals are also an option. However, we decided on Discord that we don't want to go down this route. Adding the respective assertions here for completeness.

Rectanglei rect = new Rectangle(0, 0);

// 1) rectangle from point should be valid, since min <= max
assertTrue(rect.isValid())

// 2) rectangle from point does NOT contain the point 
assertFalse(rect.contains(0, 0));

// 3) area of rectangle should be number of discrete integer points 
assertEquals(0, rect.area())

// 4) area of rectanlge should be equal to width x height
assertEquals(rect.area(), rect.getSizeX() * rect.getSizeY())

// 5) size is equal to 'max - min'
assertEquals(rect.maxX() - rect.minX(), rect.getSizeX())

@4Denthusiast
Copy link

The intersection of two rectangles may be empty, so one of the properties you list is incorrect.

@skaldarnar
Copy link
Member Author

updated the issue - I think the property is correct, but maybe a bit confusing as it is written down:

A.intersects(B) == (A ∩ B ≠ ∅), where A.intersects(B) is the test for intersection

I put this down explicitly because we have a test for intersection right now that's true even though the result of the intersection is ∅ ("touching" rectangles)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants