+#ifdef SPLAY
+static void actlist_splay_dump(actlist_t*a);
+segment_t* actlist_find(actlist_t*a, point_t p1, point_t p2)
+{
+#ifdef CHECKS
+ segment_t*t = a->list;
+ char to_the_left = 0;
+ char fail = 0;
+ while(t) {
+ double d = single_cmp(t, p1);
+ assert(!(d>=0 && to_the_left));
+ if(d<0) to_the_left=1;
+ t = t->right;
+ }
+#if 0
+ if(a->size > 100) {
+ static actlist_t*last = 0;
+ if(last != a) {
+ last = a;
+ actlist_splay_dump(a);
+ }
+ }
+#endif
+#endif
+ segment_t*last=0, *s = a->root;
+ if(!s) return 0;
+ double d=0;
+ int depth = 0;
+ while(s) {
+ last = s;
+ depth++;
+ d = single_cmp(s, p1);
+ if(d<=0) {
+ s = s->leftchild;
+ } else {
+ s = s->rightchild;
+ }
+ }
+//#ifdef DEBUG
+#if 0
+ if(a->size > 1) {
+ /* 80% hit, average cost per miss ~ 4 nodes */
+ int expected_depth = (int)((double)log2((double)a->size+1))+1;
+ static int hits = 0;
+ static int misses = 0;
+ static int miss_cost = 0;
+ if(depth <= expected_depth) hits++;
+ else {misses++;
+ miss_cost += depth - expected_depth;
+ }
+ if(hits && misses)
+ fprintf(stderr, "%02.2f%% %f\n", hits / (double)(hits+misses), miss_cost / (double)misses);
+ }
+#endif
+
+ segment_t*out = last;
+ if(d<0 || (d==0 && LINE_EQ(p2,last)<0)) {
+ last = last->left;
+ if(!last) {
+ assert(cmp(a->list, p1, p2)<0);
+ return 0;
+ }
+ } else {
+ while(last->right && cmp(last->right, p1, p2)>=0) {
+ last = last->right;
+ }
+ }
+
+#ifdef CHECKS
+ segment_t*l=0;
+ s = a->list;
+ while(s) {
+ if(cmp(s, p1, p2)<0)
+ break;
+ l = s;s = s->right;
+ }
+ if(l!=last) {
+ printf("[%d]!=[%d]\n", SEGNR(l), SEGNR(last));
+ printf("after tree: [%d]\n", SEGNR(out));
+ actlist_splay_dump(a);
+ s = a->list;
+ while(s) {
+ double d1 = single_cmp(s,p1);
+ double d2 = cmp(s,p1,p2);
+ int x1 = d1<0?-1:(d1>0?1:0);
+ int x2 = d2<0?-1:(d2>0?1:0);
+ printf("[%d](%d,%d) ", SEGNR(s), x1, x2);
+ s = s->right;
+ }
+ printf("\n");
+ }
+ assert(l == last);
+#endif
+
+ return last;
+}
+#else