@@ -127,8 +127,8 @@ plot.igraph <- function(
127127 edge.label.color <- params(" edge" , " label.color" )
128128 elab.x <- params(" edge" , " label.x" )
129129 elab.y <- params(" edge" , " label.y" )
130- arrow.size <- params(" edge" , " arrow.size" )[ 1 ]
131- arrow.width <- params(" edge" , " arrow.width" )[ 1 ]
130+ arrow.size <- params(" edge" , " arrow.size" )
131+ arrow.width <- params(" edge" , " arrow.width" )
132132 curved <- params(" edge" , " curved" )
133133 if (is.function(curved )) {
134134 curved <- curved(graph )
@@ -1611,204 +1611,163 @@ rglplot.igraph <- function(x, ...) {
16111611# slightly modified: code argument added
16121612
16131613# ' @importFrom graphics par xyinch segments xspline lines polygon
1614- igraph.Arrows <-
1615- function (
1616- x1 ,
1617- y1 ,
1618- x2 ,
1619- y2 ,
1620- code = 2 ,
1621- size = 1 ,
1622- width = 1.2 / 4 / cin ,
1623- open = TRUE ,
1624- sh.adj = 0.1 ,
1625- sh.lwd = 1 ,
1626- sh.col = par(" fg" ),
1627- sh.lty = 1 ,
1628- h.col = sh.col ,
1629- h.col.bo = sh.col ,
1630- h.lwd = sh.lwd ,
1631- h.lty = sh.lty ,
1632- curved = FALSE
1633- ) {
1634- # # Author: Andreas Ruckstuhl, refined by Rene Locher
1635- # # Version: 2005-10-17
1636- cin <- size * par(" cin" )[2 ]
1637- width <- width * (1.2 / 4 / cin )
1638- uin <- 1 / xyinch()
1614+ # Vectorized and modular igraph.Arrows refactor
1615+ igraph.Arrows <- function (
1616+ x1 ,
1617+ y1 ,
1618+ x2 ,
1619+ y2 ,
1620+ code = 2 ,
1621+ size = 1 ,
1622+ width = 1.2 / 4 / par(" cin" )[2 ],
1623+ open = TRUE ,
1624+ sh.adj = 0.1 ,
1625+ sh.lwd = 1 ,
1626+ sh.col = par(" fg" ),
1627+ sh.lty = 1 ,
1628+ h.col = sh.col ,
1629+ h.col.bo = sh.col ,
1630+ h.lwd = sh.lwd ,
1631+ h.lty = sh.lty ,
1632+ curved = FALSE
1633+ ) {
1634+ n <- length(x1 )
1635+
1636+ recycle <- function (x ) rep(x , length.out = n )
1637+
1638+ x1 <- recycle(x1 )
1639+ y1 <- recycle(y1 )
1640+ x2 <- recycle(x2 )
1641+ y2 <- recycle(y2 )
1642+ size <- recycle(size )
1643+ width <- recycle(width )
1644+ curved <- recycle(curved )
1645+ sh.lwd <- recycle(sh.lwd )
1646+ sh.col <- recycle(sh.col )
1647+ sh.lty <- recycle(sh.lty )
1648+ h.col <- recycle(h.col )
1649+ h.col.bo <- recycle(h.col.bo )
1650+ h.lwd <- recycle(h.lwd )
1651+ h.lty <- recycle(h.lty )
1652+
1653+ uin <- 1 / xyinch()
1654+
1655+ label_x <- numeric (n )
1656+ label_y <- numeric (n )
1657+
1658+ for (i in seq_len(n )) {
1659+ cin <- size [i ] * par(" cin" )[2 ]
1660+ w <- width [i ] * (1.2 / 4 / cin )
1661+ delta <- sqrt(h.lwd [i ]) * par(" cin" )[2 ] * 0.005
1662+
1663+ # Arrowhead shape
16391664 x <- sqrt(seq(0 , cin ^ 2 , length.out = floor(35 * cin ) + 2 ))
1640- delta <- sqrt(h.lwd ) * par(" cin" )[2 ] * 0.005 # # has been 0.05
16411665 x.arr <- c(- rev(x ), - x )
1642- wx2 <- width * x ^ 2
1666+ wx2 <- w * x ^ 2
16431667 y.arr <- c(- rev(wx2 + delta ), wx2 + delta )
16441668 deg.arr <- c(atan2(y.arr , x.arr ), NA )
16451669 r.arr <- c(sqrt(x.arr ^ 2 + y.arr ^ 2 ), NA )
16461670
1647- # # backup
1648- bx1 <- x1
1649- bx2 <- x2
1650- by1 <- y1
1651- by2 <- y2
1652-
1653- # # shaft
1654- lx <- length(x1 )
1655- r.seg <- rep(cin * sh.adj , lx )
1656- theta1 <- atan2((y1 - y2 ) * uin [2 ], (x1 - x2 ) * uin [1 ])
1657- th.seg1 <- theta1 + rep(atan2(0 , - cin ), lx )
1658- theta2 <- atan2((y2 - y1 ) * uin [2 ], (x2 - x1 ) * uin [1 ])
1659- th.seg2 <- theta2 + rep(atan2(0 , - cin ), lx )
1671+ theta1 <- atan2((y1 [i ] - y2 [i ]) * uin [2 ], (x1 [i ] - x2 [i ]) * uin [1 ])
1672+ theta2 <- atan2((y2 [i ] - y1 [i ]) * uin [2 ], (x2 [i ] - x1 [i ]) * uin [1 ])
1673+ r.seg <- cin * sh.adj
1674+
16601675 x1d <- y1d <- x2d <- y2d <- 0
16611676 if (code %in% c(1 , 3 )) {
1662- x2d <- r.seg * cos(th.seg2 ) / uin [1 ]
1663- y2d <- r.seg * sin(th.seg2 ) / uin [2 ]
1677+ x2d <- r.seg * cos(theta2 ) / uin [1 ]
1678+ y2d <- r.seg * sin(theta2 ) / uin [2 ]
16641679 }
16651680 if (code %in% c(2 , 3 )) {
1666- x1d <- r.seg * cos(th.seg1 ) / uin [1 ]
1667- y1d <- r.seg * sin(th.seg1 ) / uin [2 ]
1681+ x1d <- r.seg * cos(theta1 ) / uin [1 ]
1682+ y1d <- r.seg * sin(theta1 ) / uin [2 ]
16681683 }
1669- if (
1670- is.logical(curved ) && all(! curved ) || is.numeric(curved ) && all(! curved )
1671- ) {
1684+
1685+ sx1 <- x1 [i ] + x1d
1686+ sy1 <- y1 [i ] + y1d
1687+ sx2 <- x2 [i ] + x2d
1688+ sy2 <- y2 [i ] + y2d
1689+
1690+ if (! curved [i ]) {
16721691 segments(
1673- x1 + x1d ,
1674- y1 + y1d ,
1675- x2 + x2d ,
1676- y2 + y2d ,
1677- lwd = sh.lwd ,
1678- col = sh.col ,
1679- lty = sh.lty
1692+ sx1 ,
1693+ sy1 ,
1694+ sx2 ,
1695+ sy2 ,
1696+ lwd = sh.lwd [ i ] ,
1697+ col = sh.col [ i ] ,
1698+ lty = sh.lty [ i ]
16801699 )
1681- phi <- atan2(y1 - y2 , x1 - x2 )
1682- r <- sqrt((x1 - x2 )^ 2 + (y1 - y2 )^ 2 )
1683- lc.x <- x2 + 2 / 3 * r * cos(phi )
1684- lc.y <- y2 + 2 / 3 * r * sin(phi )
1700+ phi <- atan2(y1 [ i ] - y2 [ i ] , x1 [ i ] - x2 [ i ] )
1701+ r <- sqrt((x1 [ i ] - x2 [ i ] )^ 2 + (y1 [ i ] - y2 [ i ] )^ 2 )
1702+ label_x [ i ] <- x2 [ i ] + 2 / 3 * r * cos(phi )
1703+ label_y [ i ] <- y2 [ i ] + 2 / 3 * r * sin(phi )
16851704 } else {
1686- if (is.numeric(curved )) {
1687- lambda <- curved
1688- } else {
1689- lambda <- as.logical(curved ) * 0.5
1705+ lambda <- if (is.numeric(curved )) curved [i ] else 0.5
1706+ midx <- (x1 [i ] + x2 [i ]) / 2
1707+ midy <- (y1 [i ] + y2 [i ]) / 2
1708+ spx <- midx - lambda * 1 / 2 * (sy2 - sy1 )
1709+ spy <- midy + lambda * 1 / 2 * (sx2 - sx1 )
1710+
1711+ spl <- xspline(
1712+ x = c(sx1 , spx , sx2 ),
1713+ y = c(sy1 , spy , sy2 ),
1714+ shape = 1 ,
1715+ draw = FALSE
1716+ )
1717+ lines(spl , lwd = sh.lwd [i ], col = sh.col [i ], lty = sh.lty [i ])
1718+ label_x [i ] <- spl $ x [round(2 / 3 * length(spl $ x ))]
1719+ label_y [i ] <- spl $ y [round(2 / 3 * length(spl $ y ))]
1720+
1721+ if (code %in% c(2 , 3 )) {
1722+ x1 [i ] <- spl $ x [round(3 / 4 * length(spl $ x ))]
1723+ y1 [i ] <- spl $ y [round(3 / 4 * length(spl $ y ))]
16901724 }
1691- lambda <- rep(lambda , length.out = length(x1 ))
1692- c.x1 <- x1 + x1d
1693- c.y1 <- y1 + y1d
1694- c.x2 <- x2 + x2d
1695- c.y2 <- y2 + y2d
1696-
1697- midx <- (x1 + x2 ) / 2
1698- midy <- (y1 + y2 ) / 2
1699- spx <- midx - lambda * 1 / 2 * (c.y2 - c.y1 )
1700- spy <- midy + lambda * 1 / 2 * (c.x2 - c.x1 )
1701- sh.col <- rep(sh.col , length.out = length(c.x1 ))
1702- sh.lty <- rep(sh.lty , length.out = length(c.x1 ))
1703- sh.lwd <- rep(sh.lwd , length.out = length(c.x1 ))
1704- lc.x <- lc.y <- numeric (length(c.x1 ))
1705-
1706- for (i in seq_len(length(c.x1 ))) {
1707- # # Straight line?
1708- if (lambda [i ] == 0 ) {
1709- segments(
1710- c.x1 [i ],
1711- c.y1 [i ],
1712- c.x2 [i ],
1713- c.y2 [i ],
1714- lwd = sh.lwd [i ],
1715- col = sh.col [i ],
1716- lty = sh.lty [i ]
1717- )
1718- phi <- atan2(y1 [i ] - y2 [i ], x1 [i ] - x2 [i ])
1719- r <- sqrt((x1 [i ] - x2 [i ])^ 2 + (y1 [i ] - y2 [i ])^ 2 )
1720- lc.x [i ] <- x2 [i ] + 2 / 3 * r * cos(phi )
1721- lc.y [i ] <- y2 [i ] + 2 / 3 * r * sin(phi )
1722- } else {
1723- spl <- xspline(
1724- x = c(c.x1 [i ], spx [i ], c.x2 [i ]),
1725- y = c(c.y1 [i ], spy [i ], c.y2 [i ]),
1726- shape = 1 ,
1727- draw = FALSE
1728- )
1729- lines(spl , lwd = sh.lwd [i ], col = sh.col [i ], lty = sh.lty [i ])
1730- if (code %in% c(2 , 3 )) {
1731- x1 [i ] <- spl $ x [3 * length(spl $ x ) / 4 ]
1732- y1 [i ] <- spl $ y [3 * length(spl $ y ) / 4 ]
1733- }
1734- if (code %in% c(1 , 3 )) {
1735- x2 [i ] <- spl $ x [length(spl $ x ) / 4 ]
1736- y2 [i ] <- spl $ y [length(spl $ y ) / 4 ]
1737- }
1738- lc.x [i ] <- spl $ x [2 / 3 * length(spl $ x )]
1739- lc.y [i ] <- spl $ y [2 / 3 * length(spl $ y )]
1740- }
1725+ if (code %in% c(1 , 3 )) {
1726+ x2 [i ] <- spl $ x [round(1 / 4 * length(spl $ x ))]
1727+ y2 [i ] <- spl $ y [round(1 / 4 * length(spl $ y ))]
17411728 }
17421729 }
17431730
1744- # # forward arrowhead
1745- if ( code %in% c( 2 , 3 )) {
1746- theta <- atan2(( by2 - y1 ) * uin [ 2 ], ( bx2 - x1 ) * uin [ 1 ] )
1747- Rep <- rep(length(deg.arr ), lx )
1748- p.x2 <- rep( bx2 , Rep )
1749- p.y2 <- rep( by2 , Rep )
1750- ttheta <- rep( theta , Rep ) + rep( deg .arr, lx )
1751- r.arr.rep <- rep( r.arr , lx )
1731+ draw_arrowhead <- function ( px , py , theta ) {
1732+ px2 <- rep( px , length( deg.arr ))
1733+ py2 <- rep( py , length( deg.arr ) )
1734+ ttheta <- rep(theta , length(deg.arr )) + deg.arr
1735+
1736+ xhead <- px2 + r.arr * cos( ttheta ) / uin [ 1 ]
1737+ yhead <- py2 + r .arr * sin( ttheta ) / uin [ 2 ]
1738+
17521739 if (open ) {
1753- lines(
1754- (p.x2 + r.arr.rep * cos(ttheta ) / uin [1 ]),
1755- (p.y2 + r.arr.rep * sin(ttheta ) / uin [2 ]),
1756- lwd = h.lwd ,
1757- col = h.col.bo ,
1758- lty = h.lty
1759- )
1740+ lines(xhead , yhead , lwd = h.lwd [i ], col = h.col.bo [i ], lty = h.lty [i ])
17601741 } else {
17611742 polygon(
1762- p.x2 + r.arr.rep * cos( ttheta ) / uin [ 1 ] ,
1763- p.y2 + r.arr * sin( ttheta ) / uin [ 2 ] ,
1764- col = h.col ,
1765- lwd = h.lwd ,
1766- border = h.col.bo ,
1767- lty = h.lty
1743+ xhead ,
1744+ yhead ,
1745+ col = h.col [ i ] ,
1746+ lwd = h.lwd [ i ] ,
1747+ border = h.col.bo [ i ] ,
1748+ lty = h.lty [ i ]
17681749 )
17691750 }
17701751 }
17711752
1772- # # backward arrow head
1753+ if (code %in% c(2 , 3 )) {
1754+ draw_arrowhead(
1755+ x2 [i ],
1756+ y2 [i ],
1757+ atan2((y2 [i ] - y1 [i ]) * uin [2 ], (x2 [i ] - x1 [i ]) * uin [1 ])
1758+ )
1759+ }
17731760 if (code %in% c(1 , 3 )) {
1774- x1 <- bx1
1775- y1 <- by1
1776- tmp <- x1
1777- x1 <- x2
1778- x2 <- tmp
1779- tmp <- y1
1780- y1 <- y2
1781- y2 <- tmp
1782- theta <- atan2((y2 - y1 ) * uin [2 ], (x2 - x1 ) * uin [1 ])
1783- lx <- length(x1 )
1784- Rep <- rep(length(deg.arr ), lx )
1785- p.x2 <- rep(x2 , Rep )
1786- p.y2 <- rep(y2 , Rep )
1787- ttheta <- rep(theta , Rep ) + rep(deg.arr , lx )
1788- r.arr.rep <- rep(r.arr , lx )
1789-
1790- if (open ) {
1791- lines(
1792- (p.x2 + r.arr.rep * cos(ttheta ) / uin [1 ]),
1793- (p.y2 + r.arr.rep * sin(ttheta ) / uin [2 ]),
1794- lwd = h.lwd ,
1795- col = h.col.bo ,
1796- lty = h.lty
1797- )
1798- } else {
1799- polygon(
1800- p.x2 + r.arr.rep * cos(ttheta ) / uin [1 ],
1801- p.y2 + r.arr.rep * sin(ttheta ) / uin [2 ],
1802- col = h.col ,
1803- lwd = h.lwd ,
1804- border = h.col.bo ,
1805- lty = h.lty
1806- )
1807- }
1761+ draw_arrowhead(
1762+ x1 [i ],
1763+ y1 [i ],
1764+ atan2((y1 [i ] - y2 [i ]) * uin [2 ], (x1 [i ] - x2 [i ]) * uin [1 ])
1765+ )
18081766 }
1767+ }
18091768
1810- list (lab.x = lc.x , lab.y = lc.y )
1811- } # Arrows
1769+ list (lab.x = label_x , lab.y = label_y )
1770+ }
18121771
18131772# ' @importFrom graphics xspline
18141773igraph.polygon <- function (
0 commit comments