Specify direction of an arc in a curve containing many segments
Andrew Martchenko <[email protected]> Thu, 24 Nov 2016 16:54:58 +1100
| Newsgroups | gmane.comp.graphics.ipe.general |
|---|---|
| Message-ID | <[email protected]> |
Hi all,
I have written an ipelet (attached) called "fillet", which will create
circular fillets on a polyline or polygon. The problem I am having is
that I am unable to specify which side of an arc to draw when
constructing the filleted curve. On line 108, swapping x1 and x2 around
in the function
ipe.Arc(ipe.Matrix(r, 0, 0, r, c.x, c.y), x1, x2)
does not make a difference to the arc that gets drawn.
I have attached a test.ipe file to illustrate the problem. Here's how to
run the ipelet
1) select the shape
2) type Ctrl-F
3) enter 12 for the radius of the fillet and select OK
Notice that the inner fillets are correctly applied while the outer
fillets are incorrect. So how can I specify the direction in which the
arc is drawn.
Also, how would I go about deleting the old polygon/polyline?
Cheers,
Andrew M.
_______________________________________________
Ipe-discuss mailing list
Ipe-discuss-rGrgPyRx506NN8uzcEdRPYRWq/[email protected]
http://lists.science.uu.nl/mailman/listinfo/ipe-discuss
fillet.lua
(text/x-lua, 2.9 KB)
label = "Fillet"
about = [[
Create fillets in a polyline or polygon
]]
function get_polysegments(obj)
if obj:type() ~= "path" then return end
local shape = obj:shape()
if (#shape ~= 1 or shape[1].type ~= "curve" or #shape[1] < 2) then return end
local m = obj:matrix()
local v
local seg = {}
-- get all the line segments
for i=1,#shape[1] do
v = shape[1][i]
if v.type ~= "segment" then return end
seg[#seg+1] = ipe.Segment(m*v[1],m*v[2])
end
local closed = shape[1].closed
if closed then
local a,b = seg[#seg]:endpoints()
local c,d = seg[1]:endpoints()
seg[#seg+1] = ipe.Segment(b,c)
seg[#seg+1] = seg[1]
end
return seg, closed
end
function run(model)
local p = model:page()
local prim = p:primarySelection()
if not prim then model.ui:explain("no selection") return end
local obj = p[prim]
local seg, closed = get_polysegments(obj)
if seg==nil then
model:warning("Primary selection is not a polyline or polygon")
end
local str = model:getString("Enter fillet radius in pts")
if not str or str:match("^%s*$") then return end
local r = tonumber(str)
local s11,s12,s21,s22
local n1,n2,p11,p12,p21,p22
local c
local x1, x2
local shape={type="curve", closed=closed}
for i=1,#seg-1 do
-- normals of line segments with length equal to r
n1 = r*seg[i]:line():normal()
n2 = r*seg[i+1]:line():normal()
-- endpoints of line segments
p11,p12 = seg[i]:endpoints()
p21,p22 = seg[i+1]:endpoints()
-- line segments translated by +/- the respective normals
s11 = ipe.Segment(p11+n1,p12+n1)
s12 = ipe.Segment(p11-n1,p12-n1)
s21 = ipe.Segment(p21+n2,p22+n2)
s22 = ipe.Segment(p21-n2,p22-n2)
-- find center of the joing arc which is equal to the intersection
-- of two of the translated line segments
if s11:intersects(s21) then
c = s11:intersects(s21)
elseif s11:intersects(s22) then
c = s11:intersects(s22)
elseif s12:intersects(s21) then
c = s12:intersects(s21)
elseif s12:intersects(s22) then
c = s12:intersects(s22)
end
-- start and end point of the arc
x1 = seg[i]:project(c)
x2 = seg[i+1]:project(c)
-- append segments and arcs to form filleted shape
if i>1 then
shape[#shape+1] = {type="segment", shape[#shape][2],x1}
elseif i==1 and closed==false then
shape[#shape+1] = {type="segment", p11,x1}
end
shape[#shape+1] = {type="arc", x1,x2,arc=ipe.Arc(ipe.Matrix(r, 0, 0, r, c.x, c.y),x1,x2)}
if i==#seg-1 and closed==false then
shape[#shape+1] = {type="segment", x2,p22}
end
end
local path = ipe.Path(model.attributes, { shape } )
model:creation("create excircles of triangles", path)
end
----------------------------------------------------------------------
shortcuts.ipelet_1_fillet = "Shift+f"
test.ipe
(text/xml, 6.3 KB)
<?xml version="1.0"?>
<!DOCTYPE ipe SYSTEM "ipe.dtd">
<ipe version="70107" creator="Ipe 7.2.5">
<info created="D:20160627205049" modified="D:20161124162812"/>
<ipestyle name="basic">
<symbol name="arrow/arc(spx)">
<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
0 0 m
-1 0.333 l
-1 -0.333 l
h
</path>
</symbol>
<symbol name="arrow/farc(spx)">
<path stroke="sym-stroke" fill="white" pen="sym-pen">
0 0 m
-1 0.333 l
-1 -0.333 l
h
</path>
</symbol>
<symbol name="arrow/ptarc(spx)">
<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
0 0 m
-1 0.333 l
-0.8 0 l
-1 -0.333 l
h
</path>
</symbol>
<symbol name="arrow/fptarc(spx)">
<path stroke="sym-stroke" fill="white" pen="sym-pen">
0 0 m
-1 0.333 l
-0.8 0 l
-1 -0.333 l
h
</path>
</symbol>
<symbol name="mark/circle(sx)" transformations="translations">
<path fill="sym-stroke">
0.6 0 0 0.6 0 0 e
0.4 0 0 0.4 0 0 e
</path>
</symbol>
<symbol name="mark/disk(sx)" transformations="translations">
<path fill="sym-stroke">
0.6 0 0 0.6 0 0 e
</path>
</symbol>
<symbol name="mark/fdisk(sfx)" transformations="translations">
<group>
<path fill="sym-fill">
0.5 0 0 0.5 0 0 e
</path>
<path fill="sym-stroke" fillrule="eofill">
0.6 0 0 0.6 0 0 e
0.4 0 0 0.4 0 0 e
</path>
</group>
</symbol>
<symbol name="mark/box(sx)" transformations="translations">
<path fill="sym-stroke" fillrule="eofill">
-0.6 -0.6 m
0.6 -0.6 l
0.6 0.6 l
-0.6 0.6 l
h
-0.4 -0.4 m
0.4 -0.4 l
0.4 0.4 l
-0.4 0.4 l
h
</path>
</symbol>
<symbol name="mark/square(sx)" transformations="translations">
<path fill="sym-stroke">
-0.6 -0.6 m
0.6 -0.6 l
0.6 0.6 l
-0.6 0.6 l
h
</path>
</symbol>
<symbol name="mark/fsquare(sfx)" transformations="translations">
<group>
<path fill="sym-fill">
-0.5 -0.5 m
0.5 -0.5 l
0.5 0.5 l
-0.5 0.5 l
h
</path>
<path fill="sym-stroke" fillrule="eofill">
-0.6 -0.6 m
0.6 -0.6 l
0.6 0.6 l
-0.6 0.6 l
h
-0.4 -0.4 m
0.4 -0.4 l
0.4 0.4 l
-0.4 0.4 l
h
</path>
</group>
</symbol>
<symbol name="mark/cross(sx)" transformations="translations">
<group>
<path fill="sym-stroke">
-0.43 -0.57 m
0.57 0.43 l
0.43 0.57 l
-0.57 -0.43 l
h
</path>
<path fill="sym-stroke">
-0.43 0.57 m
0.57 -0.43 l
0.43 -0.57 l
-0.57 0.43 l
h
</path>
</group>
</symbol>
<symbol name="arrow/fnormal(spx)">
<path stroke="sym-stroke" fill="white" pen="sym-pen">
0 0 m
-1 0.333 l
-1 -0.333 l
h
</path>
</symbol>
<symbol name="arrow/pointed(spx)">
<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
0 0 m
-1 0.333 l
-0.8 0 l
-1 -0.333 l
h
</path>
</symbol>
<symbol name="arrow/fpointed(spx)">
<path stroke="sym-stroke" fill="white" pen="sym-pen">
0 0 m
-1 0.333 l
-0.8 0 l
-1 -0.333 l
h
</path>
</symbol>
<symbol name="arrow/linear(spx)">
<path stroke="sym-stroke" pen="sym-pen">
-1 0.333 m
0 0 l
-1 -0.333 l
</path>
</symbol>
<symbol name="arrow/fdouble(spx)">
<path stroke="sym-stroke" fill="white" pen="sym-pen">
0 0 m
-1 0.333 l
-1 -0.333 l
h
-1 0 m
-2 0.333 l
-2 -0.333 l
h
</path>
</symbol>
<symbol name="arrow/double(spx)">
<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
0 0 m
-1 0.333 l
-1 -0.333 l
h
-1 0 m
-2 0.333 l
-2 -0.333 l
h
</path>
</symbol>
<pen name="heavier" value="0.8"/>
<pen name="fat" value="1.2"/>
<pen name="ultrafat" value="2"/>
<symbolsize name="large" value="5"/>
<symbolsize name="small" value="2"/>
<symbolsize name="tiny" value="1.1"/>
<arrowsize name="large" value="10"/>
<arrowsize name="small" value="5"/>
<arrowsize name="tiny" value="3"/>
<color name="red" value="1 0 0"/>
<color name="green" value="0 1 0"/>
<color name="blue" value="0 0 1"/>
<color name="yellow" value="1 1 0"/>
<color name="orange" value="1 0.647 0"/>
<color name="gold" value="1 0.843 0"/>
<color name="purple" value="0.627 0.125 0.941"/>
<color name="gray" value="0.745"/>
<color name="brown" value="0.647 0.165 0.165"/>
<color name="navy" value="0 0 0.502"/>
<color name="pink" value="1 0.753 0.796"/>
<color name="seagreen" value="0.18 0.545 0.341"/>
<color name="turquoise" value="0.251 0.878 0.816"/>
<color name="violet" value="0.933 0.51 0.933"/>
<color name="darkblue" value="0 0 0.545"/>
<color name="darkcyan" value="0 0.545 0.545"/>
<color name="darkgray" value="0.663"/>
<color name="darkgreen" value="0 0.392 0"/>
<color name="darkmagenta" value="0.545 0 0.545"/>
<color name="darkorange" value="1 0.549 0"/>
<color name="darkred" value="0.545 0 0"/>
<color name="lightblue" value="0.678 0.847 0.902"/>
<color name="lightcyan" value="0.878 1 1"/>
<color name="lightgray" value="0.827"/>
<color name="lightgreen" value="0.565 0.933 0.565"/>
<color name="lightyellow" value="1 1 0.878"/>
<dashstyle name="dashed" value="[4] 0"/>
<dashstyle name="dotted" value="[1 3] 0"/>
<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>
<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>
<textsize name="large" value="\large"/>
<textsize name="small" value="\small"/>
<textsize name="tiny" value="\tiny"/>
<textsize name="Large" value="\Large"/>
<textsize name="LARGE" value="\LARGE"/>
<textsize name="huge" value="\huge"/>
<textsize name="Huge" value="\Huge"/>
<textsize name="footnote" value="\footnotesize"/>
<textstyle name="center" begin="\begin{center}" end="\end{center}"/>
<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/>
<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>
<gridsize name="4 pts" value="4"/>
<gridsize name="8 pts (~3 mm)" value="8"/>
<gridsize name="16 pts (~6 mm)" value="16"/>
<gridsize name="32 pts (~12 mm)" value="32"/>
<gridsize name="10 pts (~3.5 mm)" value="10"/>
<gridsize name="20 pts (~7 mm)" value="20"/>
<gridsize name="14 pts (~5 mm)" value="14"/>
<gridsize name="28 pts (~10 mm)" value="28"/>
<gridsize name="56 pts (~20 mm)" value="56"/>
<anglesize name="90 deg" value="90"/>
<anglesize name="60 deg" value="60"/>
<anglesize name="45 deg" value="45"/>
<anglesize name="30 deg" value="30"/>
<anglesize name="22.5 deg" value="22.5"/>
<opacity name="10%" value="0.1"/>
<opacity name="30%" value="0.3"/>
<opacity name="50%" value="0.5"/>
<opacity name="75%" value="0.75"/>
<tiling name="falling" angle="-60" step="4" width="1"/>
<tiling name="rising" angle="30" step="4" width="1"/>
</ipestyle>
<page>
<layer name="alpha"/>
<view layers="alpha" active="alpha"/>
<path layer="alpha" stroke="black">
258.945 794.847 m
295.908 741.175 l
397.176 749.783 l
301.478 695.098 l
359.707 624.21 l
273.629 662.186 l
186.032 617.122 l
226.033 706.744 l
137.93 749.276 l
241.73 743.2 l
h
</path>
</page>
</ipe>