1//----------------------------------------------------------------------------
2// Anti-Grain Geometry - Version 2.4
3// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4//
5// Permission to copy, use, modify, sell and distribute this software
6// is granted provided this copyright notice appears in all copies.
7// This software is provided "as is" without express or implied
8// warranty, and with no claim as to its suitability for any purpose.
9//
10//----------------------------------------------------------------------------
11// Contact: mcseem@antigrain.com
12//          mcseemagg@yahoo.com
13//          http://www.antigrain.com
14//----------------------------------------------------------------------------
15
16#include <math.h>
17#include "agg_line_aa_basics.h"
18
19namespace agg
20{
21    //-------------------------------------------------------------------------
22    // The number of the octant is determined as a 3-bit value as follows:
23    // bit 0 = vertical flag
24    // bit 1 = sx < 0
25    // bit 2 = sy < 0
26    //
27    // [N] shows the number of the orthogonal quadrant
28    // <M> shows the number of the diagonal quadrant
29    //               <1>
30    //   [1]          |          [0]
31    //       . (3)011 | 001(1) .
32    //         .      |      .
33    //           .    |    .
34    //             .  |  .
35    //    (2)010     .|.     000(0)
36    // <2> ----------.+.----------- <0>
37    //    (6)110   .  |  .   100(4)
38    //           .    |    .
39    //         .      |      .
40    //       .        |        .
41    //         (7)111 | 101(5)
42    //   [2]          |          [3]
43    //               <3>
44    //                                                        0,1,2,3,4,5,6,7
45    const int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 };
46    const int8u line_parameters::s_diagonal_quadrant[8]   = { 0,1,2,1,0,3,2,3 };
47
48
49
50    //-------------------------------------------------------------------------
51    void bisectrix(const line_parameters& l1,
52                   const line_parameters& l2,
53                   int* x, int* y)
54    {
55        double k = double(l2.len) / double(l1.len);
56        double tx = l2.x2 - (l2.x1 - l1.x1) * k;
57        double ty = l2.y2 - (l2.y1 - l1.y1) * k;
58
59        //All bisectrices must be on the right of the line
60        //If the next point is on the left (l1 => l2.2)
61        //then the bisectix should be rotated by 180 degrees.
62        if(double(l2.x2 - l2.x1) * double(l2.y1 - l1.y1) <
63           double(l2.y2 - l2.y1) * double(l2.x1 - l1.x1) + 100.0)
64        {
65            tx -= (tx - l2.x1) * 2.0;
66            ty -= (ty - l2.y1) * 2.0;
67        }
68
69        // Check if the bisectrix is too short
70        double dx = tx - l2.x1;
71        double dy = ty - l2.y1;
72        if((int)sqrt(dx * dx + dy * dy) < line_subpixel_scale)
73        {
74            *x = (l2.x1 + l2.x1 + (l2.y1 - l1.y1) + (l2.y2 - l2.y1)) >> 1;
75            *y = (l2.y1 + l2.y1 - (l2.x1 - l1.x1) - (l2.x2 - l2.x1)) >> 1;
76            return;
77        }
78        *x = iround(tx);
79        *y = iround(ty);
80    }
81
82}
83