Changeset 342

Show
Ignore:
Timestamp:
05/27/08 08:28:25 (6 months ago)
Author:
FeepingCreature
Message:
  • WHEE
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/qd/dsss.conf

    r338 r342  
    3030buildflags=-L-lSDL -L-lSDL_ttf -O 
    3131[test13.d] 
    32 buildflags=-L-lSDL 
     32buildflags=-L-lSDL -O -release -inline 
  • trunk/qd/test13.d

    r341 r342  
    11module test13; 
    22 
    3 import qd, dglut.vector, std.stdio, tools.base
     3import qd, dglut.vector, std.stdio, tools.base, tools.log
    44 
    5 class dist { 
    6   vec2f line_start, line_end, d, v; 
    7   this(vec2f ls, vec2f le) { 
    8     line_start = ls; 
    9     line_end = le; 
    10     d = line_end - line_start; 
    11     v = vec2f(d.y, -d.x).normalized(); 
     5bool _polygons_overlap_4(vec2f[4] poly_1, vec2f[4] poly_2) { 
     6  int next_1(int i) { if (i == poly_1.length - 1) return 0; else return i+1; } 
     7  foreach (i, pt; poly_1) { 
     8    auto pt2 = poly_1[next_1(i)]; 
     9    auto d = pt2 - pt, perp = vec2f(d.y, -d.x); 
     10    bool check(vec2f v) { return perp.dot(v) > 0; } 
     11    bool side = check(poly_1[next_1(next_1(i))] - pt); // check which side poly_1 is on 
     12    bool separating = true; 
     13    foreach (other_pt; poly_2) { 
     14      // if any point of the other polygon is on the _same_ side, this is not a separating line. Abort. 
     15      if (check(other_pt - pt) == side) { 
     16        separating = false; 
     17        break; 
     18      } 
     19    } 
     20    if (separating) return false; 
     21  } 
     22  return true; // no separating side found; see http://gpwiki.org/index.php/Polygon_Collision 
     23
     24 
     25bool polygons_overlap_4(vec2f[4] poly_1, vec2f[4] poly_2) { 
     26  return _polygons_overlap_4(poly_1, poly_2) && _polygons_overlap_4(poly_2, poly_1); 
     27
     28 
     29class FatLine { 
     30  vec2f[] pts, ds, vs; 
     31  float width; 
     32  this(vec2f[] pts, float w) { 
     33    width = w; 
     34    this.pts = pts.dup; 
     35    for (int i = 0; i < pts.length - 1; ++i) { 
     36      auto d = pts[i+1] - pts[i], v = vec2f(d.y, -d.x).normalized(); 
     37      ds ~= d; vs ~= v; 
     38    } 
     39  } 
     40  bool overlap(vec2f tl, vec2f br) { 
     41    auto tr = vec2f(br.x, tl.y), bl = vec2f(tl.x, br.y); 
     42    auto square = [tl, tr, br, bl]; 
     43    for (int i = 0; i < pts.length - 1; ++i) { 
     44      // construct polygon for line 
     45      auto line_start = pts[i], line_end = pts[i+1]; 
     46      auto d = line_end - line_start, d_norm = d.normalized(), d_extend = d_norm * width; 
     47      auto offs = vec2f(d_norm.y, -d_norm.x) * width; 
     48      auto start_extend = line_start - d_extend, end_extend = line_end + d_extend; 
     49      auto line = [start_extend + offs, start_extend - offs, end_extend - offs, end_extend + offs]; 
     50      if (polygons_overlap_4(line, square)) return true; 
     51    } 
     52    return false; 
    1253  } 
    1354  float normal_dist(vec2f pt) { 
    14     auto start_diff = pt - line_start, end_diff = pt - line_end; 
    15     auto dist2 = d.dot(start_diff) > 0, dist3 = d.dot(end_diff) < 0; 
    16     if (dist2 && dist3) return v.dot(start_diff); 
    17     else { 
    18       auto d1 = start_diff.lensq(), d2 = end_diff.lensq(); 
    19       return sqrt(min(d1, d2)); 
     55    auto smallest_sqr = float.infinity, smallest = float.nan; 
     56    vec2f start_diff, end_diff = pt - pts[0]; 
     57    for (int i = 0; i < pts.length - 1; ++i) { 
     58      start_diff = end_diff; end_diff = pt - pts[i+1]; 
     59      auto dist2 = ds[i].dot(start_diff) > 0, dist3 = ds[i].dot(end_diff) < 0; 
     60      if (dist2 && dist3) { 
     61        auto whee = vs[i].dot(start_diff), whee_sq = whee * whee; 
     62        if (whee_sq < smallest_sqr) { 
     63          smallest_sqr = whee_sq; 
     64          smallest = abs(whee); 
     65        } 
     66      } else { 
     67        auto d1 = start_diff.lensq(), d2 = end_diff.lensq(); 
     68        if (smallest_sqr > d1) { smallest_sqr = d1; smallest = float.nan; } 
     69        if (smallest_sqr > d2) { smallest_sqr = d2; smallest = float.nan; } 
     70      } 
    2071    } 
     72    if (!isnan(smallest)) return smallest; 
     73    else return sqrt(smallest_sqr); 
    2174  } 
    2275  alias normal_dist opCall; 
    23   float sideclass(vec2f pt) { 
    24     return v.dot(pt - line_start); 
    25   } 
    26   bool same_sideclass(vec2f tl, vec2f br, float delegate(float) post) { 
    27     auto v1 = post(sideclass(tl)), v2 = post(sideclass(vec2f(tl.x, br.y))), 
    28       v3 = post(sideclass(vec2f(br.x, tl.y))), v4 = post(sideclass(br)); 
    29     return (v1 == v2) && (v2 == v3) && (v3 == v4); 
    30   } 
    3176} 
    3277 
     
    4186} 
    4287 
    43 import tools.functional, std.math
     88import tools.functional, std.math, tools.mersenne
    4489void main() { 
    45   screen(640, 480); 
     90  screen(1024, 768); 
    4691  auto start = vec2f(20, 20); 
    4792  auto end = vec2f(100, 200); 
    48   auto fps = gen_fps(), df = new dist(start, end)
    49   bool change_first
     93  auto current = ([start, end]).dup
     94  auto fps = gen_fps(), df = new FatLine(current, 20)
    5095  void update_mouse() { 
    51     if (mouse.clicked) change_first = !change_first; 
    52     if (change_first) start = vec2f(mouse.pos.x, mouse.pos.y); 
    53     else end = vec2f(mouse.pos.x, mouse.pos.y); 
    54     df = new dist(start, end); 
     96    if (mouse.clicked) current ~= vec2f(mouse.pos.x, mouse.pos.y); 
     97    df = new FatLine(current, df.width); 
     98  } 
     99  void jiggle() { 
     100    foreach (ref v; current) v += vec2f(randf() - .5f, randf() - .5f); 
     101    df = new FatLine(current, df.width); 
    55102  } 
    56103  typeof(White) color(float d) { 
    57     if (abs(d) > 5) return Black.blend(White, 0.1); 
    58     else if (abs(d) > 4) return Black.blend(White, 0.1).blend(White, 5f - abs(d)); 
     104    if (abs(d) > df.width) return Black.blend(White, 0.1); 
     105    else if (abs(d) > df.width - 2) return Black.blend(White, 0.1).blend(White, (df.width - abs(d)) / 2f); 
     106    else if (abs(d) > df.width - 4) return White.blend(Black, (df.width - 2 - abs(d)) / 2f); 
     107    else if (abs(d) > df.width - 6) return Black.blend(White, (df.width - 4 - abs(d)) / 2f); 
    59108    else return White; 
    60109  } 
     
    65114  } 
    66115  const MAXSIZE = 4; 
    67   void quad_descent(vec2f tl, vec2f br, float[] dists = null) { 
     116  void quad_descent(vec2f tl, vec2f br, float[4] dists = [float.nan, 0f, 0f, 0f]) { 
    68117    bool maxdepth = ((br.x-tl.x) < MAXSIZE) || ((br.y-tl.y) < MAXSIZE); 
    69     if (!dists.length) { 
    70       dists = [df(tl), df(vec2f(br.x, tl.y)), df(vec2f(tl.x, br.y)), df(br)]; 
     118    if (isnan(dists[0])) { 
     119      dists[] = [df(tl), df(vec2f(br.x, tl.y)), df(vec2f(tl.x, br.y)), df(br)]; 
    71120    } 
    72121    void try_desc(vec2f new_tl, vec2f new_br, float[4] dists) { 
    73       if (df.same_sideclass(new_tl, new_br, (float f) { if (abs(f) >= 6f) return (f>0)?-float.infinity:float.infinity; else return f; })) { 
    74         line(new_tl.tuple, new_br.tuple, Fill=color(dists[0])); 
     122      if (!df.overlap(new_tl, new_br)) { 
     123        line(new_tl.tuple, new_br.tuple, Fill=color(dists[0])/*, Box=Blue*/); 
    75124        return; 
    76125      } 
     
    81130    else { 
    82131      auto half = (tl + br) / 2; 
    83       auto new_dists = [df(vec2f(half.x, tl.y)), df(vec2f(tl.x, half.y)), df(vec2f(br.x, half.y)), df(vec2f(half.x, br.y)), ]; 
     132      auto new_dists = [df(vec2f(half.x, tl.y)), df(vec2f(tl.x, half.y)), df(vec2f(br.x, half.y)), df(vec2f(half.x, br.y))]; 
    84133      auto center = df(half); 
    85134      try_desc(tl, half, [dists[0], new_dists[0], new_dists[1], center]); 
     
    93142    flip; 
    94143    events; 
     144    // jiggle(); 
    95145    update_mouse(); 
    96146    fps();