From db23d996a7c6b481435f56c679c255a9b48b455a Mon Sep 17 00:00:00 2001 From: lecoanet Date: Wed, 16 Aug 2006 14:43:48 +0000 Subject: * Added a compilation selectable attribute -omtechstuff to ease debugging anti-overlapping algorithms. It is intended to report decision making data from the algorithm. It can be compiled by defining OM_TECH. * Fixed a bad reported position in return from ZnQueryLabelPosition. Now the same algorithm is used by the widget for its internal use and for reporting purposes. --- generic/Track.c | 184 ++++++++++++++++++++++++++++++++++++-------------------- generic/Track.h | 6 +- 2 files changed, 123 insertions(+), 67 deletions(-) (limited to 'generic') diff --git a/generic/Track.c b/generic/Track.c index f10e461..8fb3e0c 100644 --- a/generic/Track.c +++ b/generic/Track.c @@ -49,6 +49,10 @@ static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " #define DEFAULT_LABEL_PREFERRED_ANGLE 0 #define DEFAULT_CONVERGENCE_STYLE 0 +#ifdef OM_TECH +#define OMTECHSTUFFLEN 256 /* length of technical buffer for OM purpose */ +#endif + #define SPEED_VECTOR_PICKING_THRESHOLD 5 /* In pixels */ /* @@ -122,6 +126,9 @@ typedef struct _TrackItemStruct { ZnDim speed_vector_width; ZnGradient *history_color; ZnDim history_width; +#ifdef OM_TECH + char *omtechstuff; +#endif /* Private data */ ZnFieldSetStruct field_set; @@ -253,6 +260,12 @@ static ZnAttrConfig track_attrs[] = { ZN_DRAW_FLAG|ZN_REPICK_FLAG|ZN_VIS_FLAG, False }, { ZN_CONFIG_BOOL, "-historyvisible", NULL, Tk_Offset(TrackItemStruct, flags), HISTORY_VISIBLE_BIT, ZN_COORDS_FLAG, False }, +#ifdef OM_TECH + /* This read only attribut receives reason value transmitted by + ZnSetLabelAngleFromOm; it can be read by application to + understand OM internal strategy */ + { ZN_CONFIG_STRING, "-omtechstuff", NULL, Tk_Offset(TrackItemStruct, omtechstuff), 0, 0, True }, +#endif { ZN_CONFIG_END, NULL, NULL, 0, 0, 0, False } }; @@ -385,6 +398,9 @@ Init(ZnItem item, track->label_distance = DEFAULT_LABEL_DISTANCE; SET(track->flags, POLAR_BIT); CLEAR(track->flags, FROZEN_LABEL_BIT); +#ifdef OM_TECH + track->omtechstuff = NULL; +#endif track->label_preferred_angle = DEFAULT_LABEL_PREFERRED_ANGLE; track->label_convergence_style = DEFAULT_CONVERGENCE_STYLE ; @@ -473,6 +489,9 @@ static void Clone(ZnItem item) { TrackItem track = (TrackItem) item; +#ifdef OM_TECH + char *omtechstuffclone; +#endif if (track->history) { track->history = ZnListDuplicate(track->history); @@ -495,6 +514,14 @@ Clone(ZnItem item) ZnFIELD.CloneFields(&track->field_set); track->field_set.item = item; +#ifdef OM_TECH + if (track->omtechstuff) { + omtechstuffclone = ZnMalloc( (OMTECHSTUFFLEN + 1) * sizeof(char)); + strcpy(omtechstuffclone, track->omtechstuff); + track->omtechstuff = omtechstuffclone; + } +#endif + /* * We get all shared resources, colors bitmaps. */ @@ -538,6 +565,12 @@ Destroy(ZnItem item) if (track->history) { ZnListFree(track->history); } + +#ifdef OM_TECH + if (track->omtechstuff) { + ZnFree(track->omtechstuff); + } +#endif /* * Release shared resources. @@ -681,6 +714,52 @@ Query(ZnItem item, } +static void +AdjustLabelDistance(TrackItem track, + ZnTransfo *current_t, + ZnReal theta, // Angle to adjust for + ZnDim bb_width, + ZnDim bb_height, + ZnPoint *label_pos, + ZnReal *label_dx, + ZnReal *label_dy) +{ + ZnReal rho, rotation, dist; + int it; + ZnBBox bbox; + + rho = track->label_distance; + /* + * Compute heading after applying the transform. + */ + ZnTransfoDecompose(current_t, NULL, NULL, &rotation, NULL); + /*printf("rotation=%g, heading=%g, angle=%d\n", rotation, + ZnProjectionToAngle(track->speed_vector.x, track->speed_vector.y), + track->label_angle);*/ + rotation = ZnProjectionToAngle(track->speed_vector.x, track->speed_vector.y)-rotation; + /* + * Adjust the distance to match the requested label_distance + * whatever the label angle. + */ + it = 0; + while (1) { + ZnPointPolarToCartesian(rotation, rho, theta, label_dx, label_dy); + label_pos->x = track->dev.x + *label_dx; + label_pos->y = track->dev.y - *label_dy; + ZnAnchor2Origin(label_pos, bb_width, bb_height, track->label_anchor, label_pos); + ZnResetBBox(&bbox); + ZnAddPointToBBox(&bbox, label_pos->x, label_pos->y); + ZnAddPointToBBox(&bbox, label_pos->x + bb_width, label_pos->y + bb_height); + dist = ZnRectangleToPointDist(&bbox, &track->dev); + dist = track->label_distance - dist; + if (ABS(dist) < 1.0 || it > 5) { + break; + } + it++; + rho += dist; + } +} + /* ********************************************************************************** * @@ -816,13 +895,12 @@ ComputeCoordinates(ZnItem item, track->dev.x + (ZnPos) track->marker_size_dev, track->dev.y + (ZnPos) track->marker_size_dev); } - + /* Compute the new label bounding box. */ if (field_set->label_format && field_set->num_fields) { - ZnDim bb_width, bb_height; - ZnReal rho, theta, dist; - ZnPoint leader_end; - int it; + ZnDim bb_width, bb_height; + ZnReal theta, dist; + ZnPoint leader_end; ZnFIELD.GetLabelBBox(field_set, &bb_width, &bb_height); /* @@ -832,38 +910,9 @@ ComputeCoordinates(ZnItem item, /* * Update label_dx, label_dy from label_distance, label_angle */ - rho = track->label_distance; - /* - * Compute heading after applying the transform. - */ - ZnTransfoDecompose(wi->current_transfo, NULL, NULL, &rotation, NULL); - /*printf("rotation=%g, heading=%g, angle=%d\n", rotation, - ZnProjectionToAngle(track->speed_vector.x, track->speed_vector.y), - track->label_angle);*/ - rotation = ZnProjectionToAngle(track->speed_vector.x, track->speed_vector.y)-rotation; - /* - * Adjust the distance to match the requested label_distance - * whatever the label_angle. - */ - it = 0; - while (1) { - ZnPointPolarToCartesian(rotation, rho, (ZnReal) track->label_angle, - &track->label_dx, &track->label_dy); - field_set->label_pos.x = track->dev.x + track->label_dx; - field_set->label_pos.y = track->dev.y - track->label_dy; - ZnAnchor2Origin(&field_set->label_pos, bb_width, bb_height, - track->label_anchor, &field_set->label_pos); - ZnResetBBox(&bbox); - ZnAddPointToBBox(&bbox, field_set->label_pos.x, field_set->label_pos.y); - ZnAddPointToBBox(&bbox, field_set->label_pos.x + bb_width, field_set->label_pos.y + bb_height); - dist = ZnRectangleToPointDist(&bbox, &track->dev); - dist = track->label_distance - dist; - if (ABS(dist) < 1.0 || it > 5) { - break; - } - it++; - rho += dist; - } + AdjustLabelDistance(track, wi->current_transfo, track->label_angle, + bb_width, bb_height, &field_set->label_pos, + &track->label_dx, &track->label_dy); } else { /* @@ -1927,10 +1976,14 @@ ZnSendTrackToOm(void *ptr, ********************************************************************************** */ void -ZnSetLabelAngleFromOm(void *ptr, /* No longer in use. */ - void *item, - int rho, - int theta) +ZnSetLabelAngleFromOm(void *ptr, /* No longer in use. */ + void *item, + int rho, + int theta +#ifdef OM_TECH + , char *reason /* Technical data explaining algorithm processing */ +#endif + ) { TrackItem track = (TrackItem) item; @@ -1947,6 +2000,13 @@ ZnSetLabelAngleFromOm(void *ptr, /* No longer in use. */ ZnITEM.Invalidate((ZnItem) item, ZN_COORDS_FLAG); /* ZnGroupSetCallOm(((ZnItem)item)->parent, True);*/ } +#ifdef OM_TECH + /* Setup reason regardless of redrawing options. */ + if (!track->omtechstuff) { + track->omtechstuff = ZnMalloc( (OMTECHSTUFFLEN + 1) * sizeof(char)); + } + strncpy(track->omtechstuff, reason, OMTECHSTUFFLEN); +#endif } @@ -1959,36 +2019,28 @@ ZnSetLabelAngleFromOm(void *ptr, /* No longer in use. */ ********************************************************************************** */ void -ZnQueryLabelPosition(void *ptr, /* No longer in use. */ - void *item, - int theta, - int *x, - int *y, - int *w, - int *h) +ZnQueryLabelPosition(void *ptr, /* No longer in use. */ + void *item, + int theta, + int *x, + int *y, + int *w, + int *h) { - ZnItem it = (ZnItem) item; - ZnWInfo *wi = it->wi; - TrackItem track = (TrackItem) it; + ZnItem it = (ZnItem) item; + TrackItem track = (TrackItem) it; if (track->field_set.label_format) { - ZnDim bb_width, bb_height; - ZnDim delta_x, delta_y; - ZnReal heading; + ZnDim bb_width, bb_height; + ZnPoint pos; + ZnReal dx, dy; + ZnTransfo t; - /* - * !! BUG !! This doesn't work if the current transform has some rotation. - */ - heading = ZnProjectionToAngle(track->speed_vector.x, track->speed_vector.y); - ZnPointPolarToCartesian(heading, track->label_distance, (ZnReal) theta, &delta_x, &delta_y); ZnFIELD.GetLabelBBox(&track->field_set, &bb_width, &bb_height); - /* - * !! BUG !! This assume a label placing relative to the center anchor. - * We must fix this by taking into account the label anchor. - */ - *x = (int) track->dev.x + (int) (delta_x - bb_width/2); - *y = (int) track->dev.y - (int) (delta_y + bb_height/2); - *y = ((int) wi->height) - *y; + ZnITEM.GetItemTransform(item, &t); + AdjustLabelDistance(track, &t, theta, bb_width, bb_height, &pos, &dx, &dy); + *x = (int) pos.x; + *y = (int) pos.y; *w = (int) bb_width; *h = (int) bb_height; } diff --git a/generic/Track.h b/generic/Track.h index d96a7a6..98bc4c5 100644 --- a/generic/Track.h +++ b/generic/Track.h @@ -38,7 +38,11 @@ void *ZnSendTrackToOm(void *ptr, void *item, int *x, int *y, int *label_width, int *label_height,*/ int *rho, int *theta, int *visibility, int *locked, int *preferred_angle, int *convergence_style); -void ZnSetLabelAngleFromOm(void *ptr, void *item, int rho, int theta); +void ZnSetLabelAngleFromOm(void *ptr, void *item, int rho, int theta +#ifdef OM_TECH + , char *reason /* Technical data explaining algorithm processing */ +#endif + ); void ZnQueryLabelPosition(void *ptr, void *item, int theta, int *x, int *y, int *w, int *h); void ZnSetHistoryVisibility(ZnItem item, int index, ZnBool visibility); -- cgit v1.1