| 1597 | |
| 1598 | |
| 1599 | static void |
| 1600 | ThickLine( Mat& img, Point2l p0, Point2l p1, const void* color, |
| 1601 | int thickness, int line_type, int flags, int shift ) |
| 1602 | { |
| 1603 | static const double INV_XY_ONE = 1./XY_ONE; |
| 1604 | |
| 1605 | p0.x <<= XY_SHIFT - shift; |
| 1606 | p0.y <<= XY_SHIFT - shift; |
| 1607 | p1.x <<= XY_SHIFT - shift; |
| 1608 | p1.y <<= XY_SHIFT - shift; |
| 1609 | |
| 1610 | if( thickness <= 1 ) |
| 1611 | { |
| 1612 | if( line_type < CV_AA ) |
| 1613 | { |
| 1614 | if( line_type == 1 || line_type == 4 || shift == 0 ) |
| 1615 | { |
| 1616 | p0.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT; |
| 1617 | p0.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT; |
| 1618 | p1.x = (p1.x + (XY_ONE>>1)) >> XY_SHIFT; |
| 1619 | p1.y = (p1.y + (XY_ONE>>1)) >> XY_SHIFT; |
| 1620 | Line( img, Point((int)(p0.x), (int)(p0.y)), Point((int)(p1.x), (int)(p1.y)), color, line_type ); |
| 1621 | } |
| 1622 | else |
| 1623 | Line2( img, p0, p1, color ); |
| 1624 | } |
| 1625 | else |
| 1626 | LineAA( img, p0, p1, color ); |
| 1627 | } |
| 1628 | else |
| 1629 | { |
| 1630 | Point2l pt[4], dp = Point2l(0,0); |
| 1631 | double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE; |
| 1632 | double r = dx * dx + dy * dy; |
| 1633 | int i, oddThickness = thickness & 1; |
| 1634 | thickness <<= XY_SHIFT - 1; |
| 1635 | |
| 1636 | if( fabs(r) > DBL_EPSILON ) |
| 1637 | { |
| 1638 | r = (thickness + oddThickness*XY_ONE*0.5)/std::sqrt(r); |
| 1639 | dp.x = cvRound( dy * r ); |
| 1640 | dp.y = cvRound( dx * r ); |
| 1641 | |
| 1642 | pt[0].x = p0.x + dp.x; |
| 1643 | pt[0].y = p0.y + dp.y; |
| 1644 | pt[1].x = p0.x - dp.x; |
| 1645 | pt[1].y = p0.y - dp.y; |
| 1646 | pt[2].x = p1.x - dp.x; |
| 1647 | pt[2].y = p1.y - dp.y; |
| 1648 | pt[3].x = p1.x + dp.x; |
| 1649 | pt[3].y = p1.y + dp.y; |
| 1650 | |
| 1651 | FillConvexPoly( img, pt, 4, color, line_type, XY_SHIFT ); |
| 1652 | } |
| 1653 | |
| 1654 | for( i = 0; i < 2; i++ ) |
| 1655 | { |
| 1656 | if( flags & (i+1) ) |