/* DiaCanvas -- A technical drawing canvas.
 * Copyright (C) 1999, Arjan Molenaar
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
/* Original license:
 * Dia -- an diagram creation/manipulation program
 * Copyright (C) 1998 Alexander Larsson
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

/* geometry.h
 * ----------
 * Geometry functions for global use
 * (that's why they don't have a name-prefix).
 * NOTE: the results are put in the first parameter, unless the
 *       operation has a return value.
 */

#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__

#include <glib.h>
#include <diacanvas/diadefs.h>

DIA_OPEN

/*
 *  Coordinate system used:
 *  +---> x
 *  |
 *  V y
 */

//typedef gfloat coord;
//typedef gfloat real;
  
typedef struct _Point Point;
typedef struct _Rectangle Rectangle;

struct _Point {
  gfloat x;
  gfloat y;
};

struct _Rectangle {
  gfloat top;
  gfloat left;
  gfloat bottom;
  gfloat right;
};

#define ROUND(x) ((gint) floor((x)+0.5))

/* Point operations
 */

  /* p1 = p1 + p2 */
void       point_add (Point *p1, Point *p2);

  /* p1 = p1 - p2 */
void       point_sub (Point *p1, Point *p2);

  /* result = (p1->x * p2->x) + (p1->y * p2->y) */
gfloat     point_dot (Point *p1, Point *p2);

void       point_scale (Point *p, gfloat alpha);

void       point_normalize (Point *p);

/* line operations
 */
/* Approach the DC (Direction Coefficient = dy/dx) of a line: */
gfloat calc_dc (gfloat dy, gfloat dx);

/* Determine if and where two lines intersect. If both line parts do not
 * intersect, FALSE is returned. If the lines do cross, TRUE is returned
 * and the intersection point is places in INTERSECT if it is non NULL.
 */
gboolean line_line_intersection (Point *start1, Point *end1,
				 Point *start2, Point *end2,
				 Point *intersect);

/* Determine where a line intersects with the border of a rectangle.
 * an array of POINTs is returned with NULL as last element.
 * Don't forget to free *INTERSECT every time after calling this function!
 */
gboolean line_rectangle_intersection (Point *start, Point *end,
				      Rectangle *rect,
				      Point **intersect);

/* rectangle operations
 */
  /* unite r1 and r2 --> result in r1 */
void       rectangle_union (Rectangle *r1, Rectangle *r2);

void       rectangle_intersection (Rectangle *r1, Rectangle *r2);

gboolean   rectangle_intersects (Rectangle *r1, Rectangle *r2);

gboolean   point_in_rectangle (Rectangle *r, Point *p);

gboolean   rectangle_in_rectangle (Rectangle *outer, Rectangle *inner);

void       rectangle_add_point (Rectangle *r, Point *p);

/* distance calculation
 */
gfloat     distance_point_point (Point *p1, Point *p2);

/* time-efficient distance calculation: */
gfloat     distance_point_point_manhattan (Point *p1, Point *p2);

/* This function estimates the distance from a point to a rectangle.
 * If the point is in the rectangle, 0.0 is returned. Otherwise the
 * distance in a manhattan metric from the point to the nearest point
 * on the rectangle is returned.
 */
gfloat     distance_rectangle_point (Rectangle *rect, Point *point);

/* This function estimates the distance from a point to a line segment
 * specified by two endpoints.
 * If the point is on the line, 0.0 is returned. Otherwise the
 * distance in the R^2 metric from the point to the nearest point
 * on the line segment is returned. Does one sqrt per call.
 */
gfloat     distance_line_point (Point *line_start, Point *line_end,
				gfloat line_width, Point *point,
				Point *point_on_line);

DIA_CLOSE

#endif /* __GEOMETRY_H__ */







