initOriginAndBound sets the origin containment for the given point and then calls the initialization for the bounds objects and the internal index.
()
| 123 | // initOriginAndBound sets the origin containment for the given point and then calls |
| 124 | // the initialization for the bounds objects and the internal index. |
| 125 | func (l *Loop) initOriginAndBound() { |
| 126 | if len(l.vertices) < 3 { |
| 127 | // Check for the special "empty" and "full" loops (which have one vertex). |
| 128 | if !l.isEmptyOrFull() { |
| 129 | l.originInside = false |
| 130 | return |
| 131 | } |
| 132 | |
| 133 | // This is the special empty or full loop, so the origin depends on if |
| 134 | // the vertex is in the southern hemisphere or not. |
| 135 | l.originInside = l.vertices[0].Z < 0 |
| 136 | } else { |
| 137 | // The brute force point containment algorithm works by counting edge |
| 138 | // crossings starting at a fixed reference point (chosen as OriginPoint() |
| 139 | // for historical reasons). Loop initialization would be more efficient |
| 140 | // if we used a loop vertex such as vertex(0) as the reference point |
| 141 | // instead, however making this change would be a lot of work because |
| 142 | // originInside is currently part of the Encode() format. |
| 143 | // |
| 144 | // In any case, we initialize originInside by first guessing that it is |
| 145 | // outside, and then seeing whether we get the correct containment result |
| 146 | // for vertex 1. If the result is incorrect, the origin must be inside |
| 147 | // the loop instead. Note that the Loop is not necessarily valid and so |
| 148 | // we need to check the requirements of AngleContainsVertex first. |
| 149 | v1Inside := l.vertices[0] != l.vertices[1] && |
| 150 | l.vertices[2] != l.vertices[1] && |
| 151 | AngleContainsVertex(l.vertices[0], l.vertices[1], l.vertices[2]) |
| 152 | |
| 153 | // initialize before calling ContainsPoint |
| 154 | l.originInside = false |
| 155 | |
| 156 | // Note that ContainsPoint only does a bounds check once initIndex |
| 157 | // has been called, so it doesn't matter that bound is undefined here. |
| 158 | if v1Inside != l.ContainsPoint(l.vertices[1]) { |
| 159 | l.originInside = true |
| 160 | } |
| 161 | |
| 162 | } |
| 163 | |
| 164 | // We *must* call initBound before initializing the index, because |
| 165 | // initBound calls ContainsPoint which does a bounds check before using |
| 166 | // the index. |
| 167 | l.initBound() |
| 168 | |
| 169 | // Create a new index and add us to it. |
| 170 | l.index = NewShapeIndex() |
| 171 | l.index.Add(l) |
| 172 | } |
| 173 | |
| 174 | // initBound sets up the approximate bounding Rects for this loop. |
| 175 | func (l *Loop) initBound() { |
no test coverage detected