blob: b753a91141c447d2c2f07dcd1bddb2b4c708fd5d [file] [log] [blame]
Brian Salomonab664fa2017-03-24 16:07:20 +00001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Jim Van Verth4db18ed2018-04-03 10:00:37 -04008#ifndef SkOffsetPolygon_DEFINED
9#define SkOffsetPolygon_DEFINED
Brian Salomonab664fa2017-03-24 16:07:20 +000010
Jim Van Verthda965502017-04-11 15:29:14 -040011#include <functional>
12
Brian Salomonab664fa2017-03-24 16:07:20 +000013#include "SkTDArray.h"
14#include "SkPoint.h"
15
Jim Van Verthda965502017-04-11 15:29:14 -040016/**
Jim Van Verthbdde4282018-06-14 09:09:18 -040017 * Generates a polygon that is inset a variable distance (controlled by offsetDistanceFunc)
18 * from the boundary of a given convex polygon.
Brian Salomonab664fa2017-03-24 16:07:20 +000019 *
20 * @param inputPolygonVerts Array of points representing the vertices of the original polygon.
21 * It should be convex and have no coincident points.
22 * @param inputPolygonSize Number of vertices in the original polygon.
Jim Van Verthbdde4282018-06-14 09:09:18 -040023 * @param insetDistanceFunc How far we wish to inset the polygon for a given position.
Jim Van Verthda965502017-04-11 15:29:14 -040024 * This should return a positive value.
Brian Salomonab664fa2017-03-24 16:07:20 +000025 * @param insetPolygon The resulting inset polygon, if any.
26 * @return true if an inset polygon exists, false otherwise.
27 */
28bool SkInsetConvexPolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize,
Jim Van Verthbdde4282018-06-14 09:09:18 -040029 std::function<SkScalar(const SkPoint&)> insetDistanceFunc,
Jim Van Verthda965502017-04-11 15:29:14 -040030 SkTDArray<SkPoint>* insetPolygon);
31
Jim Van Verthbdde4282018-06-14 09:09:18 -040032/**
33 * Generates a polygon that is inset a constant from the boundary of a given convex polygon.
34 *
35 * @param inputPolygonVerts Array of points representing the vertices of the original polygon.
36 * It should be convex and have no coincident points.
37 * @param inputPolygonSize Number of vertices in the original polygon.
38 * @param inset How far we wish to inset the polygon. This should be a positive value.
39 * @param insetPolygon The resulting inset polygon, if any.
40 * @return true if an inset polygon exists, false otherwise.
41 */
Jim Van Verthda965502017-04-11 15:29:14 -040042inline bool SkInsetConvexPolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize,
Jim Van Verth4db18ed2018-04-03 10:00:37 -040043 SkScalar inset, SkTDArray<SkPoint>* insetPolygon) {
Jim Van Verthda965502017-04-11 15:29:14 -040044 return SkInsetConvexPolygon(inputPolygonVerts, inputPolygonSize,
Jim Van Verthbdde4282018-06-14 09:09:18 -040045 [inset](const SkPoint&) { return inset; },
Jim Van Verthda965502017-04-11 15:29:14 -040046 insetPolygon);
47}
48
49/**
Jim Van Verthbdde4282018-06-14 09:09:18 -040050 * Generates a simple polygon (if possible) that is offset a variable distance (controlled by
51 * offsetDistanceFunc) from the boundary of a given simple polygon.
Jim Van Verth8664a1d2018-06-28 16:26:50 -040052 * The input polygon must be simple and have no coincident vertices or collinear edges.
Jim Van Verth4db18ed2018-04-03 10:00:37 -040053 *
54 * @param inputPolygonVerts Array of points representing the vertices of the original polygon.
55 * @param inputPolygonSize Number of vertices in the original polygon.
Jim Van Verthbdde4282018-06-14 09:09:18 -040056 * @param offsetDistanceFunc How far we wish to offset the polygon for a given position.
57 * Positive values indicate insetting, negative values outsetting.
Jim Van Verth4db18ed2018-04-03 10:00:37 -040058 * @param offsetPolgon The resulting offset polygon, if any.
Jim Van Verth872da6b2018-04-10 11:24:11 -040059 * @param polygonIndices The indices of the original polygon that map to the new one.
Jim Van Verth4db18ed2018-04-03 10:00:37 -040060 * @return true if an offset simple polygon exists, false otherwise.
61 */
62bool SkOffsetSimplePolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize,
Jim Van Verthbdde4282018-06-14 09:09:18 -040063 std::function<SkScalar(const SkPoint&)> offsetDistanceFunc,
64 SkTDArray<SkPoint>* offsetPolygon,
Jim Van Verth872da6b2018-04-10 11:24:11 -040065 SkTDArray<int>* polygonIndices = nullptr);
Jim Van Verth4db18ed2018-04-03 10:00:37 -040066
67/**
Jim Van Verthbdde4282018-06-14 09:09:18 -040068 * Generates a simple polygon (if possible) that is offset a constant distance from the boundary
69 * of a given simple polygon.
Jim Van Verth8664a1d2018-06-28 16:26:50 -040070 * The input polygon must be simple and have no coincident vertices or collinear edges.
Jim Van Verthbdde4282018-06-14 09:09:18 -040071 *
72 * @param inputPolygonVerts Array of points representing the vertices of the original polygon.
73 * @param inputPolygonSize Number of vertices in the original polygon.
74 * @param offset How far we wish to offset the polygon.
75 * Positive values indicate insetting, negative values outsetting.
76 * @param offsetPolgon The resulting offset polygon, if any.
77 * @param polygonIndices The indices of the original polygon that map to the new one.
78 * @return true if an offset simple polygon exists, false otherwise.
79 */
80inline bool SkOffsetSimplePolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize,
81 SkScalar offset, SkTDArray<SkPoint>* offsetPolygon,
82 SkTDArray<int>* polygonIndices = nullptr) {
83 return SkOffsetSimplePolygon(inputPolygonVerts, inputPolygonSize,
84 [offset](const SkPoint&) { return offset; },
85 offsetPolygon, polygonIndices);
86}
87
88/**
Jim Van Verthda965502017-04-11 15:29:14 -040089 * Offset a segment by the given distance at each point.
90 * Uses the outer tangents of two circles centered on each endpoint.
91 * See: https://en.wikipedia.org/wiki/Tangent_lines_to_circles
92 *
93 * @param p0 First endpoint.
94 * @param p1 Second endpoint.
95 * @param d0 Offset distance from first endpoint.
96 * @param d1 Offset distance from second endpoint.
97 * @param side Indicates whether we want to offset to the left (1) or right (-1) side of segment.
98 * @param offset0 First endpoint of offset segment.
99 * @param offset1 Second endpoint of offset segment.
100 * @return true if an offset segment exists, false otherwise.
101 */
102bool SkOffsetSegment(const SkPoint& p0, const SkPoint& p1, SkScalar d0, SkScalar d1,
103 int side, SkPoint* offset0, SkPoint* offset1);
Brian Salomonab664fa2017-03-24 16:07:20 +0000104
Jim Van Verth8664a1d2018-06-28 16:26:50 -0400105/**
106 * Compute the number of points needed for a circular join when offsetting a vertex.
107 * The lengths of offset0 and offset1 don't have to equal r -- only the direction matters.
108 * The segment lengths will be approximately four pixels.
109 *
110 * @param offset0 Starting offset vector direction.
111 * @param offset1 Ending offset vector direction.
112 * @param r Length of offset.
113 * @param rotSin Sine of rotation delta per step.
114 * @param rotCos Cosine of rotation delta per step.
115 * @param n Number of steps to fill out the arc.
Jim Van Verth061cc212018-07-11 14:09:09 -0400116 * @return true for success, false otherwise
Jim Van Verth8664a1d2018-06-28 16:26:50 -0400117 */
Jim Van Verth061cc212018-07-11 14:09:09 -0400118bool SkComputeRadialSteps(const SkVector& offset0, const SkVector& offset1, SkScalar r,
Jim Van Verth8664a1d2018-06-28 16:26:50 -0400119 SkScalar* rotSin, SkScalar* rotCos, int* n);
120
121/**
Jim Van Verth6784ffa2018-07-03 16:12:39 -0400122 * Determine winding direction for a polygon.
123 * The input polygon must be simple or the result will be meaningless.
124 *
125 * @param polygonVerts Array of points representing the vertices of the polygon.
126 * @param polygonSize Number of vertices in the polygon.
127 * @return 1 for cw, -1 for ccw, and 0 if zero signed area (either degenerate or self-intersecting).
128 * The y-axis is assumed to be pointing down.
129 */
130int SkGetPolygonWinding(const SkPoint* polygonVerts, int polygonSize);
131
132/**
133 * Determine whether a polygon is convex or not.
134 *
135 * @param polygonVerts Array of points representing the vertices of the polygon.
136 * @param polygonSize Number of vertices in the polygon.
137 * @return true if the polygon is convex, false otherwise.
138 */
139bool SkIsConvexPolygon(const SkPoint* polygonVerts, int polygonSize);
140
141/**
Jim Van Verth8664a1d2018-06-28 16:26:50 -0400142 * Determine whether a polygon is simple (i.e., not self-intersecting) or not.
Jim Van Verth6784ffa2018-07-03 16:12:39 -0400143 * The input polygon must have no coincident vertices or the test will fail.
Jim Van Verth8664a1d2018-06-28 16:26:50 -0400144 *
145 * @param polygonVerts Array of points representing the vertices of the polygon.
146 * @param polygonSize Number of vertices in the polygon.
147 * @return true if the polygon is simple, false otherwise.
148 */
149 bool SkIsSimplePolygon(const SkPoint* polygonVerts, int polygonSize);
150
151 /**
152 * Compute indices to triangulate the given polygon.
153 * The input polygon must be simple (i.e. it is not self-intersecting)
154 * and have no coincident vertices or collinear edges.
155 *
156 * @param polygonVerts Array of points representing the vertices of the polygon.
157 * @param indexMap Mapping from index in the given array to the final index in the triangulation.
158 * @param polygonSize Number of vertices in the polygon.
159 * @param triangleIndices Indices of the resulting triangulation.
160 * @return true if successful, false otherwise.
161 */
162 bool SkTriangulateSimplePolygon(const SkPoint* polygonVerts, uint16_t* indexMap, int polygonSize,
163 SkTDArray<uint16_t>* triangleIndices);
164
Brian Salomonab664fa2017-03-24 16:07:20 +0000165#endif