[AdgPath] Updated docblock of adg_path_chamfer()
[adg.git] / cpml / cpml-line.c
blob9512deed8ddb12ce3dd6171ee395d2bce4f858cf
1 /* CPML - Cairo Path Manipulation Library
2 * Copyright (C) 2008, 2009 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 /**
21 * SECTION:line
22 * @title: Straight lines
23 * @short_description: Line primitive management
25 * The following functions manipulate %CAIRO_PATH_LINE_TO #CpmlPrimitive.
26 * No check is made on the primitive struct, so be sure the
27 * <structname>CpmlPrimitive</structname> is effectively a line before
28 * calling these APIs.
29 **/
31 #include "cpml-line.h"
32 #include "cpml-pair.h"
34 /**
35 * cpml_line_type_get_npoints:
37 * Returns the number of point needed to properly specify a line primitive.
39 * Return value: 2
40 **/
41 int
42 cpml_line_type_get_npoints(void)
44 return 2;
47 /**
48 * cpml_line_length:
49 * @line: the #CpmlPrimitive line data
51 * Given the @line primitive, returns the distance between its
52 * start and end points.
54 * Return value: the requested distance, that is the @line length
55 **/
56 double
57 cpml_line_length(const CpmlPrimitive *line)
59 CpmlPair p1, p2;
61 cpml_pair_from_cairo(&p1, cpml_primitive_get_point(line, 0));
62 cpml_pair_from_cairo(&p2, cpml_primitive_get_point(line, -1));
64 return cpml_pair_distance(&p1, &p2);
67 /**
68 * cpml_line_pair_at:
69 * @line: the #CpmlPrimitive line data
70 * @pair: the destination pair
71 * @pos: the position value
73 * Given the @line line, finds the coordinates at position @pos
74 * (where 0 is the start and 1 is the end) and stores the result
75 * in @pair.
77 * @pos can be less than 0 or greater than 1, in which case the
78 * coordinates are interpolated.
79 **/
80 void
81 cpml_line_pair_at(const CpmlPrimitive *line, CpmlPair *pair, double pos)
83 cairo_path_data_t *p1, *p2;
85 p1 = cpml_primitive_get_point(line, 0);
86 p2 = cpml_primitive_get_point(line, -1);
88 pair->x = p1->point.x + (p2->point.x - p1->point.x) * pos;
89 pair->y = p1->point.y + (p2->point.y - p1->point.y) * pos;
92 /**
93 * cpml_line_vector_at:
94 * @line: the #CpmlPrimitive line data
95 * @vector: the destination vector
96 * @pos: the position value
98 * Gets the slope on @line at the position @pos. Being the
99 * line a straight segment, the vector is always the same, so
100 * @pos is not used. Mathematically speaking, the equation
101 * performed is:
103 * @vector = endpoint(@line) - startpoint(@line).
105 void
106 cpml_line_vector_at(const CpmlPrimitive *line, CpmlVector *vector, double pos)
108 cairo_path_data_t *p1, *p2;
110 p1 = cpml_primitive_get_point(line, 0);
111 p2 = cpml_primitive_get_point(line, 1);
113 vector->x = p2->point.x - p1->point.x;
114 vector->y = p2->point.y - p1->point.y;
118 * cpml_line_intersection:
119 * @line: the first line
120 * @line2: the second line
121 * @dest: the destination #CpmlPair
123 * Given two lines (@line and @line2), gets their intersection point
124 * and store the result in @dest.
126 * Return value: 1 on success, 0 on no intersections
129 cpml_line_intersection(const CpmlPrimitive *line,
130 const CpmlPrimitive *line2, CpmlPair *dest)
132 const cairo_path_data_t *p1a, *p2a, *p1b, *p2b;
133 CpmlVector va, vb;
134 double factor;
136 p1a = cpml_primitive_get_point(line, 0);
137 p2a = cpml_primitive_get_point(line, 1);
138 p1b = cpml_primitive_get_point(line2, 0);
139 p2b = cpml_primitive_get_point(line2, 1);
141 va.x = p2a->point.x - p1a->point.x;
142 va.y = p2a->point.y - p1a->point.y;
143 vb.x = p2b->point.x - p1b->point.x;
144 vb.y = p2b->point.y - p1b->point.y;
146 factor = va.x * vb.y - va.y * vb.x;
148 /* Check if the lines are parallel */
149 if (factor == 0)
150 return 0;
152 factor = ((p1a->point.y - p1b->point.y) * vb.x -
153 (p1a->point.x - p1b->point.x) * vb.y) / factor;
155 dest->x = p1a->point.x + va.x * factor;
156 dest->y = p1a->point.y + va.y * factor;
158 return 1;
162 * cpml_line_offset:
163 * @line: the #CpmlPrimitive line data
164 * @offset: distance for the computed parallel line
166 * Given a line segment specified by the @line primitive data,
167 * computes the parallel line distant @offset from the original one
168 * and returns the result by changing @line.
170 void
171 cpml_line_offset(CpmlPrimitive *line, double offset)
173 cairo_path_data_t *p1, *p2;
174 CpmlVector normal;
176 p1 = cpml_primitive_get_point(line, 0);
177 p2 = cpml_primitive_get_point(line, 1);
179 cpml_line_vector_at(line, &normal, 0.);
180 cpml_vector_normal(&normal);
181 cpml_vector_set_length(&normal, offset);
183 p1->point.x += normal.x;
184 p1->point.y += normal.y;
185 p2->point.x += normal.x;
186 p2->point.y += normal.y;