static double arrow_length_generic(double lenfact, double arrowsize, double penwidth, int flag);
static double arrow_length_normal(double lenfact, double arrowsize, double penwidth, int flag);
static double arrow_length_box(double lenfact, double arrowsize, double penwidth, int flag);
+static double arrow_length_diamond(double lenfact, double arrowsize, double penwidth, int flag);
static double arrow_length_dot(double lenfact, double arrowsize, double penwidth, int flag);
static const arrowtype_t Arrowtypes[] = {
{ARR_TYPE_CROW, 1.0, arrow_type_crow, arrow_length_generic},
{ARR_TYPE_TEE, 0.5, arrow_type_tee, arrow_length_generic},
{ARR_TYPE_BOX, 1.0, arrow_type_box, arrow_length_box},
- {ARR_TYPE_DIAMOND, 1.2, arrow_type_diamond, arrow_length_generic},
+ {ARR_TYPE_DIAMOND, 1.2, arrow_type_diamond, arrow_length_diamond},
{ARR_TYPE_DOT, 0.8, arrow_type_dot, arrow_length_dot},
{ARR_TYPE_CURVE, 1.0, arrow_type_curve, arrow_length_generic},
{ARR_TYPE_GAP, 0.5, arrow_type_gap, arrow_length_generic},
return lenfact * arrowsize * ARROW_LENGTH + penwidth / 2;
}
+static double arrow_length_diamond(double lenfact, double arrowsize,
+ double penwidth, int flag) {
+ pointf a[5];
+ // set arrow end point at origin
+ const pointf p = {0, 0};
+ // generate an arrowhead vector along x-axis
+ const pointf u = {lenfact * arrowsize * ARROW_LENGTH, 0};
+
+ // arrow start point
+ pointf q = arrow_type_diamond0(p, u, penwidth, flag, a);
+
+ // calculate overlap using a triangle with its base at the left and right
+ // corners of the diamond and its tip at the end point
+ const pointf base1 = a[3];
+ const pointf base2 = a[1];
+ const pointf tip = a[2];
+ const double full_length = q.x / 2;
+ assert(full_length > 0 && "non-positive full length");
+ const double nominal_length = fabs(base1.x - tip.x);
+ const double nominal_base_width = base2.y - base1.y;
+ assert(nominal_base_width > 0 && "non-positive nominal base width");
+ // the full base width is proportionally scaled with the length
+ const double full_base_width =
+ nominal_base_width * full_length / nominal_length;
+ assert(full_base_width > 0 && "non-positive full base width");
+
+ // we want a small overlap between the edge path (stem) and the arrow to avoid
+ // gaps beetween them in case the arrow has a corner towards the edge path
+
+ // overlap the tip to a point where its width is equal to the penwidth
+ const double length_where_width_is_penwidth =
+ full_length * penwidth / full_base_width;
+ const double overlap_at_tip = length_where_width_is_penwidth;
+
+ const double overlap = overlap_at_tip;
+
+ // arrow length is the x value of the start point since the arrow points along
+ // the positive x axis and ends at origin
+ return 2 * full_length - overlap;
+}
+
static double arrow_length_dot(double lenfact, double arrowsize,
double penwidth, int flag) {
(void)flag;