;;; This software is being provided to you, the LICENSEE, by the
;;; Massachusetts Institute of Technology (M.I.T.), and the NEC Research
;;; Institute (NECI) under the following license.  By obtaining, using
;;; and/or copying this software, you agree that you have read,
;;; understood, and will comply with these terms and conditions:
;;; 
;;; Permission to use, copy, modify and distribute, including the right to
;;; grant others rights to distribute at any tier, this software and its
;;; documentation for research purposes only and without fee or royalty is
;;; hereby granted, provided that you agree to comply with the following
;;; copyright notice and statements, including the disclaimer, and that
;;; the same appear on ALL copies of the software and documentation,
;;; including modifications that you make for internal use or for
;;; distribution:
;;; 
;;; Copyright 1995 by the Massachusetts Institute of Technology.  All
;;; rights reserved.  Copyright 1995 by NEC Research Institute Inc. All
;;; rights reserved
;;; 
;;; THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. and NECI MAKE NO
;;; REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.  By way of example,
;;; but not limitation, M.I.T. and NECI MAKE NO REPRESENTATIONS OR
;;; WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR
;;; THAT THE USE OF THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT
;;; INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER
;;; RIGHTS.
;;; 
;;; The name of the Massachusetts Institute of Technology or M.I.T., or
;;; NEC Research Institute, or NECI may NOT be used in advertising or
;;; publicity pertaining to distribution of the software.  Title to
;;; copyright in this software and any associated documentation shall at
;;; all times remain with M.I.T. and NECI, and USER agrees to preserve
;;; same.
;;; 

;;; -*- Mode: LISP; Base: 10; Package: 2DG; Syntax: Common-Lisp -*-
(in-package '2DG)

(defun RANDOMLY-POSE (obj)
      (let ((ang (random *2pi*))
	    (dx (random 100.0))
	    (dy (random 100.0)))
	(rotate (translate obj dx dy) ang)))

(defun RANDOM-POSE-VARS ()
  (list (random *2pi*) (random 1.0) (random 1.0)))

(defun APPLY-POSE-VARS (obj lst)
  (let ((ang (car lst))
	(dx (cadr lst))
	(dy (caddr lst)))
    (rotate (translate obj dx dy) ang)))

(defun TEST-INSIDE-ON-POINT (container)
  (let ((vars (random-pose-vars)))
    (inside? (apply-pose-vars (random-choose (defining-points-list container)) vars)
	     (apply-pose-vars container vars))))

(defun RANDOM-POINT ()
  (make-point (random-between -100 100) (random-between -100 100)))

(defun TEST1-RECTANGLE ()
  (test-inside-on-point (make-rectangle -7 12 3 8)))

(defun TEST2-POLYGON ()
  (let* ((poly (make-polygon (list (random-point) (random-point) (random-point))))
	 (pt (random-point))
	 (rect (bounding-box poly)))
    (when (and (not (inside? pt rect)) (inside? pt poly))
      (error "Point is inside a polygon, but not inside a bounding box around it?"))))

(defun TEST3-POLYGON (n)
  (let ((poly (make-polygon
		(append (list (make-point 30 0) (make-point 0 0) (make-point 2 2))
			(loop for i from 3 to 29 by 2
			      appending
			      (list (make-point i 1) (make-point (1+ i) 2)))))))
    (loop for i from 1 to n
	  doing
      (let* ((vars (random-pose-vars))
	     (point (make-point (random-between 5.0 25.0) 1.5))
	     (inside? (inside? (apply-pose-vars point vars) (apply-pose-vars poly vars)))
	     (really-inside? (or (~= .5 (mod (point-x point) 1))
				 (evenp (round (point-x point))))))
	(when (or (and inside? (not really-inside?))
		  (and (not inside?) really-inside?))
	  (error "What can I say?"))))))

(defun TEST-INTERSECT-LINE-SEGMENT-AND-RECTANGLE (&optional outside?)
  (let* ((min-x (random-between -10.0 10.0))
	 (min-y (random-between -10.0 10.0))
	 (max-x (random-between min-x 15.0))
	 (max-y (random-between min-y 15.0)))
    (let ((rect (make-rectangle min-x max-x min-y max-y))
	  (ls (make-line-segment (make-point (random-between -10.0 20.0) (random-between -10.0 20.0))
				 (make-point (random-between -10.0 20.0) (random-between -10.0 20.0)))))
      (when (xor (intersect-line-segment-and-rectangle? ls rect)
		 (or (intersect-line-segment-and-line-segment? (make-line-segment (make-point min-x min-y)
										  (make-point min-x max-y))
							       ls)
		     (intersect-line-segment-and-line-segment? (make-line-segment (make-point min-x min-y)
										  (make-point max-x min-y))
							       ls)
		     (intersect-line-segment-and-line-segment? (make-line-segment (make-point max-x max-y)
										  (make-point min-x max-y))
							       ls)
		     (intersect-line-segment-and-line-segment? (make-line-segment (make-point max-x max-y)
										  (make-point max-x min-y))
							       ls)
		     (inside? (line-segment-point-1 ls) rect)
		     (inside? (line-segment-point-2 ls) rect)))
	(error "One method found intersection, the other didn't.")))))
