/* * Created on 12.11.2005 * */ package org.geogebra.common.kernel; /** * @author HOHENWARTER * * sorted list of point pairs (sorted by distance) used in * AlgoInteresectConics and AlgoIntersecLineConic */ public class PointPairList { private PointPair head; private int size = 0; private boolean isStrict = true; /** * @return whether this list is empty */ final public boolean isEmpty() { return head == null; } /** * Clears the list */ public final void clear() { head = null; isStrict = true; size = 0; } /** * Inserts pair (indexD, indexQ) in ascending order of distance where alive * points come before others and points Q on path come before others. * * @param indexD * index of point in D * @param isPalive * tru if point in P is alive * @param indexQ * index of point in Q * @param isQonPath * true if point in Q is on path * @param distance * distance between point in D and point in Q */ public final void insertPointPair(int indexD, boolean isPalive, int indexQ, boolean isQonPath, double distance) { PointPair newPair = new PointPair(indexD, isPalive, indexQ, isQonPath, distance); // insert as head if (head == null || smallerThan(newPair, head)) { newPair.next = head; head = newPair; size++; return; } PointPair currentPair = head; while (currentPair.next != null) { if (smallerThan(newPair, currentPair.next)) { break; } currentPair = currentPair.next; } // check strictness // TODO: check relevance of isQonPath // if (currentPair.isPalive && newPair.isPalive && // !reallySmallerThan(currentPair,newPair)) // isStrict = false; // add after currentPair newPair.next = currentPair.next; currentPair.next = newPair; size++; } /** * Checks a < b. Ascending ordering by isPalive and isQonPath and distance, * where isPalive == true comes before isPalive == false and isQonPath == * true comes before isQonPath == false. */ private static boolean smallerThan(PointPair a, PointPair b) { if (a.isPalive) { if (b.isPalive) { // both are alive return smallerThan2(a, b); } // a alive, b not return true; } // a not alive, b is alive: a > b if (b.isPalive) { return false; } // both not alive return smallerThan2(a, b); } /** * Checks a < b. Ascending ordering by isQonPath and distance, where * isQonPath == true comes before isQonPath == false. */ private static boolean smallerThan2(PointPair a, PointPair b) { if (a.isQonPath) { if (b.isQonPath) { // both on path return (a.dist < b.dist); } // a on path, b not on path: a < b return true; } // a not on path, b on path: a > b if (b.isQonPath) { return false; } // both not on path return (a.dist < b.dist); } /** * Removes all PointPairs where indexP == pair.indexP or indexQ == * pair.indexQ * * @param pair * pair such that pairs with one same point must be removed */ public final void removeAllPairs(PointPair pair) { if (head == null) { return; } while (head.indexP == pair.indexP || head.indexQ == pair.indexQ) { head = head.next; if (head == null) { return; } } PointPair prevPair = head, currentPair = head.next; while (currentPair != null) { if (currentPair.indexP == pair.indexP || currentPair.indexQ == pair.indexQ) { // remove currentPair prevPair.next = currentPair.next; currentPair = currentPair.next; size--; } else { // move on to next pair prevPair = currentPair; currentPair = currentPair.next; } } } /** * @return first pair in the list */ public final PointPair getHead() { return head; } /** * @return true */ public final boolean isStrict() { isStrict = true; return isStrict; } /** * @return size of the list */ public final int size() { return size; } /** * already assumed that the list is sorted. * * @param indexQ * index of Q-point * @return index of closest P-point */ public final int getClosestPWithindexQ(int indexQ) { PointPair pair = this.getHead(); while (pair != null) { if (pair.indexQ == indexQ) { return pair.indexP; } pair = pair.next; } return -1; // indexQ not found } /** * already assumed that the list is sorted. * * @param indexP * index of P-point * @return index of closest Q-point */ public final int getClosestQWithindexP(int indexP) { PointPair pair = this.getHead(); while (pair != null) { if (pair.indexP == indexP) { return pair.indexP; } pair = pair.next; } return -1; // indexQ not found } /* * final public String toString() { StringBuilder sb = new StringBuilder(); * PointPair currentPair = head; while (currentPair != null) { * sb.append(currentPair); currentPair = currentPair.next; } return * sb.toString(); } */ }