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.
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
31 #include "cpml-line.h"
32 #include "cpml-pair.h"
35 * cpml_line_type_get_npoints:
37 * Returns the number of point needed to properly specify a line primitive.
42 cpml_line_type_get_npoints(void)
49 * @line: the #CpmlPrimitive line data
50 * @pair: the destination pair
51 * @pos: the position value
53 * Given the @line line, finds the coordinates at position @pos
54 * (where 0 is the start and 1 is the end) and stores the result
57 * @pos can be less than 0 or greater than 1, in which case the
58 * coordinates are interpolated.
61 cpml_line_pair_at(const CpmlPrimitive
*line
, CpmlPair
*pair
, double pos
)
63 cairo_path_data_t
*p1
, *p2
;
65 p1
= cpml_primitive_get_point(line
, 0);
66 p2
= cpml_primitive_get_point(line
, 1);
68 pair
->x
= p1
->point
.x
+ (p1
->point
.x
- p1
->point
.x
) * pos
;
69 pair
->y
= p1
->point
.y
+ (p2
->point
.y
- p1
->point
.y
) * pos
;
73 * cpml_line_vector_at:
74 * @line: the #CpmlPrimitive line data
75 * @vector: the destination vector
76 * @pos: the position value
78 * Gets the slope on @line at the position @pos. Being the
79 * line a straight segment, the vector is always the same, so
80 * @pos is not used. Mathematically speaking, the equation
83 * @vector = endpoint(@line) - startpoint(@line).
86 cpml_line_vector_at(const CpmlPrimitive
*line
, CpmlVector
*vector
, double pos
)
88 cairo_path_data_t
*p1
, *p2
;
90 p1
= cpml_primitive_get_point(line
, 0);
91 p2
= cpml_primitive_get_point(line
, 1);
93 vector
->x
= p2
->point
.x
- p1
->point
.x
;
94 vector
->y
= p2
->point
.y
- p1
->point
.y
;
98 * cpml_line_intersection:
99 * @line: the first line
100 * @line2: the second line
101 * @dest: the destination #CpmlPair
103 * Given two lines (@line and @line2), gets their intersection point
104 * and store the result in @dest.
106 * Return value: 1 on success, 0 on no intersections
109 cpml_line_intersection(const CpmlPrimitive
*line
,
110 const CpmlPrimitive
*line2
, CpmlPair
*dest
)
112 const cairo_path_data_t
*p1a
, *p2a
, *p1b
, *p2b
;
116 p1a
= cpml_primitive_get_point(line
, 0);
117 p2a
= cpml_primitive_get_point(line
, 1);
118 p1b
= cpml_primitive_get_point(line2
, 0);
119 p2b
= cpml_primitive_get_point(line2
, 1);
121 va
.x
= p2a
->point
.x
- p1a
->point
.x
;
122 va
.y
= p2a
->point
.y
- p1a
->point
.y
;
123 vb
.x
= p2b
->point
.x
- p1b
->point
.x
;
124 vb
.y
= p2b
->point
.y
- p1b
->point
.y
;
126 factor
= va
.x
* vb
.y
- va
.y
* vb
.x
;
128 /* Check if the lines are parallel */
132 factor
= ((p1a
->point
.y
- p1b
->point
.y
) * vb
.x
-
133 (p1a
->point
.x
- p1b
->point
.x
) * vb
.y
) / factor
;
135 dest
->x
= p1a
->point
.x
+ va
.x
* factor
;
136 dest
->y
= p1a
->point
.y
+ va
.y
* factor
;
143 * @line: the #CpmlPrimitive line data
144 * @offset: distance for the computed parallel line
146 * Given a line segment specified by the @line primitive data,
147 * computes the parallel line distant @offset from the original one
148 * and returns the result by changing @line.
151 cpml_line_offset(CpmlPrimitive
*line
, double offset
)
153 cairo_path_data_t
*p1
, *p2
;
156 p1
= cpml_primitive_get_point(line
, 0);
157 p2
= cpml_primitive_get_point(line
, 1);
159 cpml_line_vector_at(line
, &normal
, 0.);
160 cpml_vector_normal(&normal
);
161 cpml_vector_set_length(&normal
, offset
);
163 p1
->point
.x
+= normal
.x
;
164 p1
->point
.y
+= normal
.y
;
165 p2
->point
.x
+= normal
.x
;
166 p2
->point
.y
+= normal
.y
;