Advertisement
Zeda

find_closest_coordinate

Jun 30th, 2019
696
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. find_closest:
  2. ;Input:
  3. ;   HL points to an array of coordinates
  4. ;   DE = (x0,y0), the point to compare
  5. ;   B is the number of elements to search
  6. ;Output:
  7. ;   A is the closest element
  8. ;   C = B-C, with 'B' being the input 'B'
  9. ;   IX is (distance^2)>>1
  10. ;0 elements : 40cc
  11. ;if last element is closest, +12cc
  12. ;64+n*(252+2*{0,3}+2*C_Times_C+{20,{0,11+{0,22}{p0,1-p0}}{p1,1-p1}}{p2,1-p2})
  13. ;p0 is the probability that our new candidate is definitely closer
  14. ;p1 is the probability that our new candidates adjusted distance is equal to the current candidate
  15. ;p2 is the probability that, if the adjusted distances are equal, our candidate had odd distance (before adjustment)
  16. ;min: 64+n*640
  17. ;max: 64+n*783
  18. ;avg: 64+n*720.4    ;Determined with probabilistic methods, no clue on precision, but probably +-.05
  19.  
  20. ; Initialize C to 0
  21.     ld c,0
  22.  
  23. ; Initialize "closest" distance
  24.     ld ix,-1
  25.  
  26. ; First we'll play it safe and verify that B!=0
  27.     inc b
  28.     dec b
  29.     ret z
  30.  
  31. ; Save B for the end adjustment
  32.     push bc
  33.  
  34. ; Begin the loop
  35. find_closest_loop:
  36.     push bc   ;save the counter
  37.     ; Load the next coordinates, but find the absolute value
  38.     ; of their differences from the input coords
  39.     ld a,e
  40.     sub (hl)
  41.     jr nc,+_
  42.     neg
  43. _:
  44.     ld c,a
  45.     inc hl
  46.  
  47.     ld a,d
  48.     sub (hl)
  49.     jr nc,+_
  50.     neg
  51. _:
  52.     ld b,a
  53.     inc hl
  54.  
  55. ; BC is the adjusted coordinates,
  56. ; HL is the pointer to the next coordinate
  57.     push hl
  58.  
  59. ; Now we need to compute B^2 + C^2
  60.   ld a,b
  61.   call C_Times_C
  62.   ex de,hl         ;C^2
  63.   ld c,a
  64.   call C_Times_C
  65.  
  66.   ; This might overflow, so we are going to shift right,
  67.   ;losing information in the bottom bit :/
  68.   xor a
  69.   add hl,de
  70.   rr h
  71.   rr l
  72.   rra   ;save the carry, but reset carry flag for next sbc
  73.  
  74.   ; If no carry, and HL<=IX, then this is a guaranteed
  75.   ;candidate for closest.
  76.   ; If the carry flag is set and HL==IX, do not select
  77.   ;this coordinate
  78.  
  79.   ld b,ixh
  80.   ld c,ixl
  81.   sbc hl,bc
  82.  
  83.   ;if carry, then definitely select this candidate
  84.   jr c,select_new_candidate
  85.  
  86.   ;If they are not equal, keep searching
  87.   jr nz,find_next_candidate
  88.  
  89.   ;Otherwise, they are equal. If top bit of A is reset,
  90.   ;select as the candidate
  91.   rla
  92.   jr c,find_next_candidate
  93.  
  94. select_new_candidate:
  95.   ld b,h
  96.   ld c,l
  97.   add ix,bc
  98.   pop hl
  99.   pop bc
  100.   ld c,b
  101.   djnz find_closest_loop
  102.   jr +_
  103.  
  104. find_next_candidate:
  105.   pop hl
  106.   pop bc
  107.   djnz find_closest_loop
  108.  
  109. _:
  110. ; Gotta finalize!
  111. ; We actually want A = B-C
  112.   pop af
  113.   sub c
  114.   ret
  115.  
  116.  
  117. C_Times_C:
  118. ;min: 194cc
  119. ;max: 246cc
  120. ;avg: 220cc
  121.   ld h,c
  122. H_Times_C:
  123. ;min: 190cc
  124. ;max: 242cc
  125. ;avg: 216cc
  126.   ld b,0
  127.   ld l,b
  128.   sla h \ jr nc,$+3 \ ld l,c
  129.   add hl,hl \ jr nc,$+3 \ add hl,bc
  130.   add hl,hl \ jr nc,$+3 \ add hl,bc
  131.   add hl,hl \ jr nc,$+3 \ add hl,bc
  132.   add hl,hl \ jr nc,$+3 \ add hl,bc
  133.   add hl,hl \ jr nc,$+3 \ add hl,bc
  134.   add hl,hl \ jr nc,$+3 \ add hl,bc
  135.   add hl,hl \ ret nc \ add hl,bc \ ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement