Skip to content

Commit 7ff3dbc

Browse files
authored
Merge pull request #47 from Wikunia/documentation-offset
documentation for offsetting
2 parents 48dfca4 + f0c3d4d commit 7ff3dbc

File tree

10 files changed

+226
-24
lines changed

10 files changed

+226
-24
lines changed

.github/workflows/CI.yml

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,30 +43,24 @@ jobs:
4343
github-token: ${{ secrets.GITHUB_TOKEN }}
4444
flag-name: run${{ matrix.os }}-${{ matrix.version }}-${{ matrix.arch }}
4545
parallel: true
46-
# docs:
47-
# name: Documentation
48-
# runs-on: ubuntu-latest
49-
# steps:
50-
# - uses: actions/checkout@v2
51-
# - uses: julia-actions/setup-julia@v1
52-
# with:
53-
# version: '1'
54-
# - run: |
55-
# julia --project=docs -e '
56-
# using Pkg
57-
# Pkg.develop(PackageSpec(path=pwd()))
58-
# Pkg.instantiate()'
59-
# - run: |
60-
# julia --project=docs -e '
61-
# using Documenter: DocMeta, doctest
62-
# using Clipper
63-
# DocMeta.setdocmeta!(Clipper, :DocTestSetup, :(using Clipper); recursive=true)
64-
# doctest(Clipper)'
65-
# - run: julia --project=docs docs/make.jl
66-
# env:
67-
# JULIA_PKG_SERVER: ""
68-
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
69-
# DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
46+
docs:
47+
name: Documentation
48+
runs-on: ubuntu-latest
49+
steps:
50+
- uses: actions/checkout@v2
51+
- run: sudo apt-get install xvfb && Xvfb :99 &
52+
- uses: julia-actions/setup-julia@v1
53+
with:
54+
version: '1'
55+
- run: |
56+
julia --project=docs -e '
57+
using Pkg
58+
Pkg.develop(PackageSpec(path=pwd()))
59+
Pkg.instantiate()'
60+
- run: julia --project=docs docs/make.jl
61+
env:
62+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63+
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
7064
# finish:
7165
# needs: test
7266
# if: always()

docs/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build/
2+
site/

docs/Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[deps]
2+
Clipper = "c8f6d549-b3ab-5508-a0d1-48fe138e8cc1"
3+
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
4+
5+
[compat]
6+
julia = "1"

docs/make.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Documenter
2+
using Clipper
3+
4+
makedocs(
5+
# See https://github.com/JuliaDocs/Documenter.jl/issues/868
6+
format = Documenter.HTML(prettyurls = get(ENV, "CI", nothing) == "true"),
7+
strict = true,
8+
sitename = "Clipper",
9+
pages = [
10+
"Home" => "index.md",
11+
"Reference" => "reference.md",
12+
],
13+
)
14+
15+
deploydocs(repo = "github.com/JuliaGeometry/Clipper.jl.git")

docs/src/assets/offset_diff_types.png

37 KB
Loading

docs/src/assets/offset_in.png

19.8 KB
Loading

docs/src/assets/offset_out.png

19.8 KB
Loading

docs/src/draw_diff_types.jl

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using Clipper
2+
using Luxor
3+
4+
polygon = IntPoint[]
5+
push!(polygon, IntPoint(348,257))
6+
push!(polygon, IntPoint(364,148))
7+
push!(polygon, IntPoint(362,148))
8+
push!(polygon, IntPoint(326,241))
9+
push!(polygon, IntPoint(295,219))
10+
push!(polygon, IntPoint(258,88))
11+
push!(polygon, IntPoint(440,129))
12+
push!(polygon, IntPoint(370,196))
13+
push!(polygon, IntPoint(372,275))
14+
15+
co = ClipperOffset()
16+
add_path!(co, polygon, JoinTypeRound, EndTypeClosedPolygon)
17+
round_offset_polygons = execute(co, 7.0)
18+
19+
co = ClipperOffset()
20+
add_path!(co, polygon, JoinTypeSquare, EndTypeClosedPolygon)
21+
square_offset_polygons = execute(co, 7.0)
22+
23+
co = ClipperOffset()
24+
add_path!(co, polygon, JoinTypeMiter, EndTypeClosedPolygon)
25+
miter_offset_polygons = execute(co, 7.0)
26+
27+
fpolygon = Point.(tofloat.(polygon, 3,3))
28+
round_foffset_polygons = [Point.(tofloat.(round_offset_polygon, 3,3)) for round_offset_polygon in round_offset_polygons]
29+
square_foffset_polygons = [Point.(tofloat.(square_offset_polygon, 3,3)) for square_offset_polygon in square_offset_polygons]
30+
miter_foffset_polygons = [Point.(tofloat.(miter_offset_polygon, 3,3)) for miter_offset_polygon in miter_offset_polygons]
31+
@png begin
32+
fontsize(30)
33+
text("JoinTypeRound", Point(-100, -300))
34+
translate(-300, -370)
35+
sethue("blue")
36+
poly(fpolygon, :stroke, close=true)
37+
sethue("green")
38+
setopacity(0.4)
39+
poly.(round_foffset_polygons, :fill, close=true)
40+
setopacity(1.0)
41+
translate(0, 200)
42+
sethue("blue")
43+
poly(fpolygon, :stroke, close=true)
44+
sethue("green")
45+
setopacity(0.4)
46+
poly.(square_foffset_polygons, :fill, close=true)
47+
setopacity(1.0)
48+
translate(0, 200)
49+
sethue("blue")
50+
poly(fpolygon, :stroke, close=true)
51+
sethue("green")
52+
setopacity(0.4)
53+
poly.(miter_foffset_polygons, :fill, close=true)
54+
end 500 700 "offset_diff_types.png"

docs/src/index.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Clipper.jl
2+
3+
Clipper.jl is a Julia wrapper for [Angus Johnson's Clipper library (ver. 6.4.2)](http://www.angusj.com/delphi/clipper.php).
4+
5+
It can be used for the following two tasks:
6+
- offsetting a polygon
7+
- compute boolean operations between two or more polygons
8+
9+
## General description of a polygon
10+
11+
A polygon consists of a list of vertices $v_1, \dots, v_n$ such that $v_1$ is connected to $v_2$ and $v_n$. $v_i$ is connected to $v_{i-1}$ and $v_{i+1}$.
12+
All functionality in Clipper only works with vertices that have discrete coordinates. Therefore the struct [`IntPoint`](@ref) is used.
13+
Points which consist of two floating point coordinates can however be easily converted using the [`IntPoint`](@ref) method.
14+
15+
```julia
16+
p = (1.1, 2.1)
17+
ip = IntPoint(p..., 1, 3) # [110, 210]
18+
```
19+
20+
Here `1` is the magnitude and `3` is the number of significant digits.
21+
22+
There is also the function [`tofloat`](@ref) which can be used to convert a [`IntPoint`](@ref) back to the floating point coordinates.
23+
24+
```julia
25+
tofloat(ip, 1, 3) # (1.1, 2.1)
26+
```
27+
28+
Using broadcasting you can also easily convert several points like a whole polygon this way:
29+
30+
```julia
31+
ps = rand(100, 2)
32+
ips = IntPoint.(ps[:,1], ps[:,2], 1, 3)
33+
```
34+
35+
and back
36+
```julia
37+
tofloat.(ips, 1, 3)
38+
```
39+
40+
## Offsetting a polygon
41+
42+
[Original Clipper documentation](http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/_Body.htm).
43+
44+
A polygon can be offset (inflated/deflated) in the following way using Clipper.jl:
45+
46+
47+
```julia
48+
polygon = IntPoint[]
49+
push!(polygon, IntPoint(348,257))
50+
push!(polygon, IntPoint(364,148))
51+
push!(polygon, IntPoint(362,148))
52+
push!(polygon, IntPoint(326,241))
53+
push!(polygon, IntPoint(295,219))
54+
push!(polygon, IntPoint(258,88))
55+
push!(polygon, IntPoint(440,129))
56+
push!(polygon, IntPoint(370,196))
57+
push!(polygon, IntPoint(372,275))
58+
59+
co = ClipperOffset()
60+
add_path!(co, polygon, JoinTypeRound, EndTypeClosedPolygon)
61+
offset_polygons = execute(co, -7.0)
62+
```
63+
64+
```@meta
65+
# using Luxor
66+
# fpolygon = Point.(tofloat.(polygon, 3,3))
67+
# foffset_polygons = [Point.(tofloat.(offset_polygon, 3,3)) for offset_polygon in offset_polygons]
68+
# @png begin
69+
# translate(-650, -400)
70+
# scale(2)
71+
# sethue("blue")
72+
# poly(fpolygon, :stroke, close=true)
73+
# sethue("green")
74+
# setopacity(0.4)
75+
# poly.(foffset_polygons, :fill, close=true)
76+
# end 600 600 "offset_in.png"
77+
```
78+
79+
![Offset polygon](assets/offset_in.png)
80+
In the image above the blue polygon is the initial polygon and by offsetting it two polygons are created
81+
which are drawn as the filled green polygons.
82+
83+
We can also inflate the polygon by using a positive value in the execute function.
84+
```julia
85+
offset_polygons = execute(co, 7.0)
86+
```
87+
88+
![Inflating the polygon](assets/offset_out.png)
89+
90+
In this example we can visualize the meaning of the third argument in the `add_path!` function which is currently set to `JoinTypeRound`.
91+
92+
```julia
93+
co = ClipperOffset()
94+
add_path!(co, polygon, JoinTypeRound, EndTypeClosedPolygon)
95+
round_offset_polygons = execute(co, 7.0)
96+
97+
co = ClipperOffset()
98+
add_path!(co, polygon, JoinTypeSquare, EndTypeClosedPolygon)
99+
square_offset_polygons = execute(co, 7.0)
100+
101+
co = ClipperOffset()
102+
add_path!(co, polygon, JoinTypeMiter, EndTypeClosedPolygon)
103+
miter_offset_polygons = execute(co, 7.0)
104+
```
105+
106+
![Different offsetting types](assets/offset_diff_types.png)
107+
108+
`JoinTypeRound` produces rounded corners, `JoinTypeSquare` produces squared corners.
109+
In the case of `JoinTypeMiter` it depends on the degree of the angle or in different words the maximum offsetted distance if corners.
110+
would not be squared. If the maximum distance is bigger than `MiterLimit * delta` than it is squared which would be the case in the upper right corner.
111+
112+
The `MiterLimit` is the first argument of `ClipperOffset` for example `ClipperOffset(3.0)` would set it to `3.0` (default is `2.0`).
113+
`delta` is simply the distance we want to offset in our case above we set it to `7.0` as the second parameter of the `execute` function.
114+
115+
The three different types are also explained in the [official documentation](http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm).
116+
117+
## Boolean operations between two or more polygons
118+
119+
Needs to be written. Feel free to open a PR.
120+
121+

docs/src/reference.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
```@meta
2+
CurrentModule = Clipper
3+
```
4+
5+
# Public functions
6+
7+
```@autodocs
8+
Modules = [Clipper]
9+
Private = false
10+
```

0 commit comments

Comments
 (0)