pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 /* GTS - Library for the manipulation of triangulated surfaces 00002 * Copyright (C) 1999 Stéphane Popinet 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Library General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Library General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Library General Public 00015 * License along with this library; if not, write to the 00016 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 * Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include <stdlib.h> 00021 #include "gts.h" 00022 00023 #define PARENT(i) ((i) >= 2 ? (i)/2 : 0) 00024 #define LEFT_CHILD(i) (2*(i)) 00025 #define RIGHT_CHILD(i) (2*(i) + 1) 00026 00027 00035 GtsEHeap * gts_eheap_new (GtsKeyFunc key_func, 00036 gpointer data) 00037 { 00038 GtsEHeap * heap; 00039 00040 heap = g_malloc (sizeof(GtsEHeap)); 00041 heap->elts = g_ptr_array_new (); 00042 heap->func = key_func; 00043 heap->data = data; 00044 heap->frozen = FALSE; 00045 heap->randomized = FALSE; 00046 return heap; 00047 } 00048 00049 static void sift_up (GtsEHeap * heap, guint i) 00050 { 00051 GtsEHeapPair * parent, * child; 00052 guint p; 00053 gpointer * pdata = heap->elts->pdata; 00054 gdouble key; 00055 00056 child = pdata[i - 1]; 00057 key = child->key; 00058 while ((p = PARENT (i))) { 00059 parent = pdata[p - 1]; 00060 if (parent->key > key || 00061 (heap->randomized && parent->key == key && rand () < RAND_MAX/2)) { 00062 pdata[p - 1] = child; 00063 pdata[i - 1] = parent; 00064 child->pos = p; 00065 parent->pos = i; 00066 i = p; 00067 } 00068 else 00069 i = 0; 00070 } 00071 } 00072 00084 GtsEHeapPair * gts_eheap_insert (GtsEHeap * heap, gpointer p) 00085 { 00086 GtsEHeapPair * pair; 00087 GPtrArray * elts; 00088 00089 g_return_val_if_fail (heap != NULL, NULL); 00090 g_return_val_if_fail (heap->func != NULL, NULL); 00091 00092 elts = heap->elts; 00093 pair = g_malloc (sizeof (GtsEHeapPair)); 00094 g_ptr_array_add (elts, pair); 00095 pair->data = p; 00096 pair->pos = elts->len; 00097 pair->key = (*heap->func) (p, heap->data); 00098 if (!heap->frozen) 00099 sift_up (heap, elts->len); 00100 return pair; 00101 } 00102 00115 GtsEHeapPair * gts_eheap_insert_with_key (GtsEHeap * heap, 00116 gpointer p, 00117 gdouble key) 00118 { 00119 GtsEHeapPair * pair; 00120 GPtrArray * elts; 00121 00122 g_return_val_if_fail (heap != NULL, NULL); 00123 00124 elts = heap->elts; 00125 pair = g_malloc (sizeof (GtsEHeapPair)); 00126 g_ptr_array_add (elts, pair); 00127 pair->data = p; 00128 pair->pos = elts->len; 00129 pair->key = key; 00130 if (!heap->frozen) 00131 sift_up (heap, elts->len); 00132 return pair; 00133 } 00134 00135 static void sift_down (GtsEHeap * heap, guint i) 00136 { 00137 GtsEHeapPair * left_child, * right_child, * child, * parent; 00138 guint lc, rc, c; 00139 gpointer * pdata = heap->elts->pdata; 00140 guint len = heap->elts->len; 00141 gdouble key; 00142 00143 lc = LEFT_CHILD (i); 00144 rc = RIGHT_CHILD (i); 00145 left_child = lc <= len ? pdata[lc - 1] : NULL; 00146 right_child = rc <= len ? pdata[rc - 1] : NULL; 00147 00148 parent = pdata[i - 1]; 00149 key = parent->key; 00150 while (left_child != NULL) { 00151 if (right_child == NULL || left_child->key < right_child->key) { 00152 child = left_child; 00153 c = lc; 00154 } 00155 else { 00156 child = right_child; 00157 c = rc; 00158 } 00159 if (key > child->key) { 00160 pdata[i - 1] = child; 00161 child->pos = i; 00162 pdata[c - 1] = parent; 00163 parent->pos = c; 00164 i = c; 00165 lc = LEFT_CHILD (i); 00166 rc = RIGHT_CHILD (i); 00167 left_child = lc <= len ? pdata[lc - 1] : NULL; 00168 right_child = rc <= len ? pdata[rc - 1] : NULL; 00169 } 00170 else 00171 left_child = NULL; 00172 } 00173 } 00174 00185 gpointer gts_eheap_remove_top (GtsEHeap * heap, gdouble * key) 00186 { 00187 gpointer root; 00188 GPtrArray * elts; 00189 guint len; 00190 GtsEHeapPair * pair; 00191 00192 g_return_val_if_fail (heap != NULL, NULL); 00193 00194 elts = heap->elts; 00195 len = elts->len; 00196 00197 if (len == 0) 00198 return NULL; 00199 if (len == 1) { 00200 pair = g_ptr_array_remove_index (elts, 0); 00201 root = pair->data; 00202 if (key) 00203 *key = pair->key; 00204 g_free (pair); 00205 return root; 00206 } 00207 00208 pair = elts->pdata[0]; 00209 root = pair->data; 00210 if (key) 00211 *key = pair->key; 00212 g_free (pair); 00213 pair = g_ptr_array_remove_index (elts, len - 1); 00214 elts->pdata[0] = pair; 00215 pair->pos = 1; 00216 sift_down (heap, 1); 00217 return root; 00218 } 00219 00228 gpointer gts_eheap_top (GtsEHeap * heap, gdouble * key) 00229 { 00230 GtsEHeapPair * pair; 00231 GPtrArray * elts; 00232 00233 g_return_val_if_fail (heap != NULL, NULL); 00234 00235 elts = heap->elts; 00236 00237 if (elts->len == 0) 00238 return NULL; 00239 00240 pair = elts->pdata[0]; 00241 if (key) 00242 *key = pair->key; 00243 return pair->data; 00244 } 00245 00252 void gts_eheap_destroy (GtsEHeap * heap) 00253 { 00254 guint i; 00255 00256 g_return_if_fail (heap != NULL); 00257 00258 for (i = 0; i < heap->elts->len; i++) 00259 g_free (heap->elts->pdata[i]); 00260 g_ptr_array_free (heap->elts, TRUE); 00261 g_free (heap); 00262 } 00263 00271 void gts_eheap_thaw (GtsEHeap * heap) 00272 { 00273 guint i; 00274 00275 g_return_if_fail (heap != NULL); 00276 00277 if (!heap->frozen) 00278 return; 00279 00280 for (i = heap->elts->len/2; i > 0; i--) 00281 sift_down (heap, i); 00282 00283 heap->frozen = FALSE; 00284 } 00285 00292 void gts_eheap_foreach (GtsEHeap * heap, 00293 GFunc func, 00294 gpointer data) 00295 { 00296 guint i; 00297 GPtrArray * elts; 00298 00299 g_return_if_fail (heap != NULL); 00300 g_return_if_fail (func != NULL); 00301 00302 elts = heap->elts; 00303 for (i = 0; i < elts->len; i++) 00304 (*func) (((GtsEHeapPair *) elts->pdata[i])->data, data); 00305 } 00306 00316 gpointer gts_eheap_remove (GtsEHeap * heap, GtsEHeapPair * p) 00317 { 00318 GtsEHeapPair ** pdata; 00319 GtsEHeapPair * parent; 00320 guint i, par; 00321 gpointer data; 00322 00323 g_return_val_if_fail (heap != NULL, NULL); 00324 g_return_val_if_fail (p != NULL, NULL); 00325 00326 pdata = (GtsEHeapPair **)heap->elts->pdata; 00327 i = p->pos; 00328 data = p->data; 00329 00330 g_return_val_if_fail (i > 0 && i <= heap->elts->len, NULL); 00331 g_return_val_if_fail (p == pdata[i - 1], NULL); 00332 00333 /* move element to the top */ 00334 while ((par = PARENT (i))) { 00335 parent = pdata[par - 1]; 00336 pdata[par - 1] = p; 00337 pdata[i - 1] = parent; 00338 p->pos = par; 00339 parent->pos = i; 00340 i = par; 00341 } 00342 00343 gts_eheap_remove_top (heap, NULL); 00344 00345 return data; 00346 } 00347 00357 void gts_eheap_decrease_key (GtsEHeap * heap, 00358 GtsEHeapPair * p, 00359 gdouble new_key) 00360 { 00361 guint i; 00362 00363 g_return_if_fail (heap != NULL); 00364 g_return_if_fail (p != NULL); 00365 00366 i = p->pos; 00367 g_return_if_fail (i > 0 && i <= heap->elts->len); 00368 g_return_if_fail (p == heap->elts->pdata[i - 1]); 00369 00370 g_return_if_fail (new_key <= p->key); 00371 00372 p->key = new_key; 00373 if (!heap->frozen) 00374 sift_up (heap, i); 00375 } 00376 00385 void gts_eheap_freeze (GtsEHeap * heap) 00386 { 00387 g_return_if_fail (heap != NULL); 00388 00389 heap->frozen = TRUE; 00390 } 00391 00398 guint gts_eheap_size (GtsEHeap * heap) 00399 { 00400 g_return_val_if_fail (heap != NULL, 0); 00401 00402 return heap->elts->len; 00403 } 00404 00411 void gts_eheap_update (GtsEHeap * heap) 00412 { 00413 guint i, len; 00414 GtsEHeapPair ** pairs; 00415 gpointer data; 00416 GtsKeyFunc func; 00417 00418 g_return_if_fail (heap != NULL); 00419 g_return_if_fail (heap->func != NULL); 00420 00421 heap->frozen = TRUE; 00422 00423 len = heap->elts->len; 00424 pairs = (GtsEHeapPair **) heap->elts->pdata; 00425 data = heap->data; 00426 func = heap->func; 00427 00428 for (i = 0; i < len; i++) { 00429 GtsEHeapPair * pair = pairs[i]; 00430 pair->key = (*func) (pair->data, data); 00431 } 00432 00433 gts_eheap_thaw (heap); 00434 } 00435 00443 gdouble gts_eheap_key (GtsEHeap * heap, gpointer p) 00444 { 00445 g_return_val_if_fail (heap != NULL, 0.); 00446 g_return_val_if_fail (heap->func != NULL, 0.); 00447 00448 return (* heap->func) (p, heap->data); 00449 } 00450 00456 void gts_eheap_randomized (GtsEHeap * heap, gboolean randomized) 00457 { 00458 g_return_if_fail (heap != NULL); 00459 00460 heap->randomized = randomized; 00461 }