| 1117 | } |
| 1118 | |
| 1119 | bool IsValidAelOrder(const Active& resident, const Active& newcomer) |
| 1120 | { |
| 1121 | if (newcomer.curr_x != resident.curr_x) |
| 1122 | return newcomer.curr_x > resident.curr_x; |
| 1123 | |
| 1124 | //get the turning direction a1.top, a2.bot, a2.top |
| 1125 | int i = CrossProductSign(resident.top, newcomer.bot, newcomer.top); |
| 1126 | if (i != 0) return i < 0; |
| 1127 | |
| 1128 | //edges must be collinear to get here |
| 1129 | //for starting open paths, place them according to |
| 1130 | //the direction they're about to turn |
| 1131 | if (!IsMaxima(resident) && (resident.top.y > newcomer.top.y)) |
| 1132 | { |
| 1133 | return (CrossProductSign(newcomer.bot, resident.top, NextVertex(resident)->pt) <= 0); |
| 1134 | } |
| 1135 | else if (!IsMaxima(newcomer) && (newcomer.top.y > resident.top.y)) |
| 1136 | { |
| 1137 | return (CrossProductSign(newcomer.bot, newcomer.top, NextVertex(newcomer)->pt) >= 0); |
| 1138 | } |
| 1139 | |
| 1140 | int64_t y = newcomer.bot.y; |
| 1141 | bool newcomerIsLeft = newcomer.is_left_bound; |
| 1142 | |
| 1143 | if (resident.bot.y != y || resident.local_min->vertex->pt.y != y) |
| 1144 | return newcomer.is_left_bound; |
| 1145 | //resident must also have just been inserted |
| 1146 | else if (resident.is_left_bound != newcomerIsLeft) |
| 1147 | return newcomerIsLeft; |
| 1148 | else if (IsCollinear(PrevPrevVertex(resident)->pt, |
| 1149 | resident.bot, resident.top)) return true; |
| 1150 | else |
| 1151 | //compare turning direction of the alternate bound |
| 1152 | return (CrossProductSign(PrevPrevVertex(resident)->pt, |
| 1153 | newcomer.bot, PrevPrevVertex(newcomer)->pt) > 0) == newcomerIsLeft; |
| 1154 | } |
| 1155 | |
| 1156 | |
| 1157 | void ClipperBase::InsertLeftEdge(Active& e) |
no test coverage detected