From 2f11a58328d0ea936e22ad84f803941686c2e09d Mon Sep 17 00:00:00 2001 From: David Thompson Date: Mon, 12 Aug 2013 22:37:24 -0400 Subject: Create rect module. --- 2d/rect.scm | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 2d/rect.scm diff --git a/2d/rect.scm b/2d/rect.scm new file mode 100644 index 0000000..85943db --- /dev/null +++ b/2d/rect.scm @@ -0,0 +1,99 @@ +;;; guile-2d +;;; Copyright (C) 2013 David Thompson +;;; +;;; Guile-2d is free software: you can redistribute it and/or modify it +;;; under the terms of the GNU Lesser General Public License as +;;; published by the Free Software Foundation, either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; Guile-2d is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this program. If not, see +;;; . + +;;; Commentary: +;; +;; Rects are axis-aligned bounding boxes that can be used for +;; performing simple collision detection. +;; +;;; Code: + +(define-module (2d rect) + #:use-module (srfi srfi-9) + #:export ( + make-rect + rect? + rect-x + rect-y + rect-x2 + rect-y2 + rect-width + rect-height + rect-move + rect-inflate + rect-union + rect-contains? + rect-collides?)) + +(define-record-type + (make-rect x y width height) + rect? + (x rect-x) + (y rect-y) + (width rect-width) + (height rect-height)) + +(define (rect-x2 rect) + (+ (rect-x rect) (rect-width rect))) + +(define (rect-y2 rect) + (+ (rect-y rect) (rect-height rect))) + +(define (rect-move rect x y) + "Moves a rect by the given offset." + (make-rect (+ (rect-x rect) x) + (+ (rect-y rect) y) + (rect-width rect) + (rect-height rect))) + +(define (rect-inflate rect width height) + "Grows the rect by the given amount. The rect stays centered around +its current center." + (make-rect (+ (rect-x rect) (/ width 2)) + (+ (rect-y rect) (/ height 2)) + (+ (rect-width rect) width) + (+ (rect-height rect) height))) + +(define (rect-union rect1 rect2) + "Returns a rect that covers the area of rect1 and rect2." + (let ((x1 (min (rect-x rect1) (rect-x rect2))) + (x2 (max (rect-x2 rect1) (rect-x2 rect2))) + (y1 (min (rect-y rect1) (rect-y rect2))) + (y2 (max (rect-y2 rect1) (rect-y2 rect2)))) + (make-rect x1 y1 (- x2 x1) (- y2 y1)))) + +(define (rect-contains? rect1 rect2) + "Tests if rect2 is completely within rect1." + (and (>= (rect-x rect2) (rect-x rect1)) + (<= (rect-x rect2) (rect-x2 rect1)) + (>= (rect-x2 rect2) (rect-x rect1)) + (<= (rect-x2 rect2) (rect-x2 rect1)) + (>= (rect-y rect2) (rect-y rect1)) + (<= (rect-y rect2) (rect-y2 rect1)) + (>= (rect-y2 rect2) (rect-y rect1)) + (<= (rect-y2 rect2) (rect-y2 rect1)))) + +(define (rect-collides? rect1 rect2) + "Tests if rect2 overlaps rect1." + (or (and (>= (rect-x rect2) (rect-x rect1)) + (<= (rect-x rect2) (rect-x2 rect1))) + (and (>= (rect-x2 rect2) (rect-x rect1)) + (<= (rect-x2 rect2) (rect-x2 rect1))) + (and (>= (rect-y rect2) (rect-y rect1)) + (<= (rect-y rect2) (rect-y2 rect1))) + (and (>= (rect-y2 rect2) (rect-y rect1)) + (<= (rect-y2 rect2) (rect-y2 rect1))))) -- cgit v1.2.3