/*
* Geo.h -- Header for common geometric routines.
*
* Authors : Patrick Lecoanet.
* Creation date :
*
* $Id: Geo.h,v 1.21 2005/10/19 10:58:11 lecoanet Exp $
*/
/*
* Copyright (c) 1993 - 2005 CENA, Patrick Lecoanet --
*
* See the file "Copyright" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#ifndef _Geo_h
#define _Geo_h
#include "Attrs.h"
#include "List.h"
#include <math.h>
#include <limits.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
#ifndef M_PI_4
#define M_PI_4 0.78539816339744830962
#endif
#define PRECISION_LIMIT 1.0e-10
#define X_PRECISION_LIMIT 5.0e-2
#define ZN_LINE_END_POINTS 6
/*
* Constants used to specify circle approximation quality.
*/
#define ZN_CIRCLE_COARSE 0
#define ZN_CIRCLE_MEDIUM ZN_CIRCLE_COARSE+1
#define ZN_CIRCLE_FINE ZN_CIRCLE_MEDIUM+1
#define ZN_CIRCLE_FINER ZN_CIRCLE_FINE+1
#define ZN_CIRCLE_FINEST ZN_CIRCLE_FINER+1
/*
* I would like to make these be floats,
* but have to investigate how. Structures
* handed to GL or GLU tess _must_ have
* points has doubles.
*/
typedef struct {
double x, y;
} ZnPoint;
typedef struct {
double x, y, w, h;
} ZnRect;
/*
* ZnBBox: orig is into the area while corner is not.
* Thus the test: ((bbox.orig.x == bbox.corner.x) ||
* (bbox.orig.y == bbox.corner.y))
* tells whether the bbox is empty or not.
* When interpreting bboxes the X coordinate system is
* the norm. x goes from left toward the right and y
* goes from the top toward the bottom. Bboxes are
* always axes aligned.
*/
typedef struct {
ZnPoint orig, corner;
} ZnBBox;
typedef struct {
unsigned int num_points;
ZnPoint *points;
char *controls;
ZnBool cw;
} ZnContour;
/*
* contour1 can be used to store a single contour
* without having to alloc the contours array.
*/
typedef struct {
unsigned int num_contours;
ZnContour *contours;
ZnContour contour1;
} ZnPoly;
/*
* Keep this enum in sync with op_strings in Contour()
* in tkZinc.c.
*/
typedef enum {
ZN_CONTOUR_ADD, ZN_CONTOUR_REMOVE
} ZnContourCmd;
typedef struct {
unsigned int num_points;
ZnPoint *points;
ZnBool fan; /* When using a fan, all contour vertices must be
* included to describe the contour as a polygon
* (clipping code use that to speed up region
* rendering) and the center must be the first
* vertex. */
} ZnStrip;
typedef struct {
unsigned int num_strips;
ZnStrip *strips;
ZnStrip strip1;
} ZnTriStrip;
#ifndef MIN
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#endif
#ifndef ABS
#define ABS(a) ((a) < 0 ? -(a) : (a))
#endif
#define ZnDegRad(angle) \
(M_PI * (double) (angle) / 180.0)
#define ZnRadDeg(angle) \
(fmod((angle) * 180.0 / M_PI, 360.0))
#define ZnRadDeg360(angle) \
(fmod(ZnRadDeg(angle)+360.0,360.0))
#define ZnNearestInt(d) \
(((int) ((d) + (((d) > 0) ? 0.5 : -0.5))))
void
ZnPolyInit(ZnPoly *poly);
void
ZnPolyContour1(ZnPoly *poly,
ZnPoint *pts,
unsigned int num_pts,
ZnBool cw);
void
ZnPolySet(ZnPoly *poly1,
ZnPoly *poly2);
void
ZnPolyFree(ZnPoly *poly);
void
ZnTriStrip1(ZnTriStrip *tristrip,
ZnPoint *pts,
unsigned int num_pts,
ZnBool fan);
void
ZnTriFree(ZnTriStrip *tristrip);
void
ZnAnchor2Origin(ZnPoint *position,
ZnDim width,
ZnDim height,
Tk_Anchor anchor,
ZnPoint *origin);
void
ZnOrigin2Anchor(ZnPoint *origin,
ZnDim width,
ZnDim height,
Tk_Anchor anchor,
ZnPoint *position);
void ZnRectOrigin2Anchor(ZnPoint *rect, Tk_Anchor anchor, ZnPoint *position);
void
ZnBBox2XRect(ZnBBox *bbox,
XRectangle *rect);
void
ZnGetStringBBox(char *str,
Tk_Font font,
ZnPos x,
ZnPos y,
ZnBBox *str_bbox);
void
ZnResetBBox(ZnBBox *bbox);
void
ZnCopyBBox(ZnBBox *bbox_from,
ZnBBox *bbox_to);
void
ZnIntersectBBox(ZnBBox *bbox1,
ZnBBox *bbox2,
ZnBBox *bbox_inter);
ZnBool
ZnIsEmptyBBox(ZnBBox *bbox);
void
ZnAddBBoxToBBox(ZnBBox *bbox,
ZnBBox *bbox2);
void
ZnAddPointToBBox(ZnBBox *bbox,
ZnPos px,
ZnPos py);
void
ZnAddPointsToBBox(ZnBBox *bbox,
ZnPoint *points,
unsigned int num_points);
void
ZnAddStringToBBox(ZnBBox *bbox,
char *str,
Tk_Font font,
ZnPos cx,
ZnPos cy);
ZnBool
ZnPointInBBox(ZnBBox *bbox,
ZnPos x,
ZnPos y);
int
ZnLineInBBox(ZnPoint *p1,
ZnPoint *p2,
ZnBBox *bbox);
int
ZnBBoxInBBox(ZnBBox *bbox1,
ZnBBox *bbox2);
int
ZnPolylineInBBox(ZnPoint *points,
unsigned int num_points,
ZnDim width,
int cap_style,
int join_style,
ZnBBox *bbox);
int
ZnPolygonInBBox(ZnPoint *points,
unsigned int num_points,
ZnBBox *bbox,
ZnBool *area_enclosed);
int
ZnOvalInBBox(ZnPoint *center,
ZnDim width,
ZnDim height,
ZnBBox *bbox);
ZnBool
ZnHorizLineToArc(ZnReal x1,
ZnReal x2,
ZnReal y,
ZnReal rx,
ZnReal ry,
int start_angle,
int angle_extent);
ZnBool
ZnVertLineToArc(ZnReal x,
ZnReal y1,
ZnReal y2,
ZnReal rx,
ZnReal ry,
int start_angle,
int angle_extent);
ZnBool
ZnPointInAngle(int start_angle,
int angle_extent,
ZnPoint *p);
void
ZnPointCartesianToPolar(ZnReal heading,
ZnReal *rho,
ZnReal *theta,
ZnReal delta_x,
ZnReal delta_y);
void
ZnPointPolarToCartesian(ZnReal heading,
ZnReal rho,
ZnReal theta,
ZnReal *delta_x,
ZnReal *delta_y);
ZnReal
ZnProjectionToAngle(ZnReal dx,
ZnReal dy);
ZnDim
ZnRectangleToPointDist(ZnBBox *bbox,
ZnPoint *p);
ZnDim ZnLineToPointDist(ZnPoint *p1, ZnPoint *p2, ZnPoint *p, ZnPoint *closest);
ZnDim
ZnPolygonToPointDist(ZnPoint *points,
unsigned int num_points,
ZnPoint *p);
ZnDim
ZnPolylineToPointDist(ZnPoint *points,
unsigned int num_points,
ZnDim width,
int cap_style,
int join_style,
ZnPoint *p);
ZnDim
ZnOvalToPointDist(ZnPoint *center,
ZnDim width,
ZnDim height,
ZnDim line_width,
ZnPoint *p);
void
ZnGetButtPoints(ZnPoint *p1,
ZnPoint *p2,
ZnDim width,
ZnBool projecting,
ZnPoint *c1,
ZnPoint *c2);
ZnBool
ZnGetMiterPoints(ZnPoint *p1,
ZnPoint *p2,
ZnPoint *p3,
ZnDim width,
ZnPoint *c1,
ZnPoint *c2);
ZnBool
ZnIntersectLines(ZnPoint *a1,
ZnPoint *a2,
ZnPoint *b1,
ZnPoint *b2,
ZnPoint *pi);
void
ZnShiftLine(ZnPoint *p1,
ZnPoint *p2,
ZnDim dist,
ZnPoint *p3,
ZnPoint *p4);
void
ZnInsetPolygon(ZnPoint *p,
unsigned int num_points,
ZnDim inset);
void
ZnSmoothPathWithBezier(ZnPoint *from_points,
unsigned int num_points,
ZnList to_points);
void
ZnGetBezierPoints(ZnPoint *p1,
ZnPoint *c1,
ZnPoint *c2,
ZnPoint *p2,
ZnList to_points,
double eps);
void
ZnGetBezierPath(ZnList from_points,
ZnList to_points);
ZnPoint *
ZnGetCirclePoints(int type,
int quality,
ZnReal start_angle,
ZnReal angle_extent,
unsigned int *num_points,
ZnList point_list);
void
ZnGetArcPath(ZnReal start_angle,
ZnReal end_angle,
int type,
ZnList to_points);
void
ZnFitBezier(ZnPoint *pts,
unsigned int num_points,
ZnReal error,
ZnList controls);
ZnBool
ZnTestCCW(ZnPoint *p,
unsigned int num_points);
#endif /* _Geo_h */