rubylabs 0.6.4 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/randomlab.rb +143 -224
- data/lib/rubylabs.rb +262 -38
- data/lib/spherelab.rb +566 -209
- data/lib/tsplab.rb +308 -276
- data/test/sphere_test.rb +32 -0
- metadata +2 -22
- data/data/aafreq.txt +0 -20
- data/data/cars.txt +0 -50
- data/data/century.txt +0 -1
- data/data/colors.txt +0 -64
- data/data/earth.yaml +0 -15
- data/data/fruit.txt +0 -45
- data/data/hacodes.txt +0 -35
- data/data/hafreq.txt +0 -16
- data/data/hvfreq.txt +0 -5
- data/data/nbody.R +0 -23
- data/data/nbody.out +0 -731
- data/data/nbody.pdf +0 -3111
- data/data/nbody.png +0 -0
- data/data/nbody3d.pdf +0 -3201
- data/data/outer.pdf +0 -182785
- data/data/solarsystem.txt +0 -17
- data/data/suits.txt +0 -1
- data/data/wordlist.txt +0 -210653
- data/lib/sortlab.rb +0 -213
- data/lib/viewer.rb +0 -65
data/lib/rubylabs.rb
CHANGED
@@ -24,8 +24,6 @@ autoload :ElizaLab, "elizalab.rb"
|
|
24
24
|
autoload :SphereLab, "spherelab.rb"
|
25
25
|
autoload :TSPLab, "tsplab.rb"
|
26
26
|
|
27
|
-
autoload :Viewer, "viewer.rb"
|
28
|
-
|
29
27
|
module RubyLabs
|
30
28
|
|
31
29
|
=begin rdoc
|
@@ -432,52 +430,278 @@ Similar to TestArray, but draws random words from a file.
|
|
432
430
|
to make sure line numbers are valid.
|
433
431
|
=end
|
434
432
|
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
433
|
+
def Source.lines(spec, id)
|
434
|
+
if spec.class == Fixnum && Source.range_check(spec, id)
|
435
|
+
return [spec]
|
436
|
+
elsif spec.class == Array
|
437
|
+
res = Array.new
|
438
|
+
spec.each do |line|
|
439
|
+
raise "line number must be an integer" unless line.class == Fixnum
|
440
|
+
res << line if Source.range_check(line, id)
|
441
|
+
end
|
442
|
+
return res
|
443
|
+
elsif spec.class == String
|
444
|
+
res = Array.new
|
445
|
+
for i in @@base[id]..(@@base[id]+@@size[id]-1)
|
446
|
+
line = SCRIPT_LINES__[@@file[id]][i-1].chomp
|
447
|
+
res << i - @@base[id] + 1 if line.index(spec)
|
448
|
+
end
|
449
|
+
return res
|
450
|
+
else
|
451
|
+
raise "invalid spec: '#{spec}' (must be an integer, array of integers, or a pattern)"
|
452
|
+
end
|
453
|
+
end
|
456
454
|
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
455
|
+
def Source.range_check(n, id)
|
456
|
+
max = @@size[id]
|
457
|
+
raise "line number must be between 1 and #{max}" unless n >= 1 && n <= max
|
458
|
+
return true
|
459
|
+
end
|
462
460
|
|
463
461
|
=begin rdoc
|
464
462
|
Internal use only -- show info about method
|
465
463
|
=end
|
466
464
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
465
|
+
def Source.info(name)
|
466
|
+
unless id = Source.find(name)
|
467
|
+
puts "Can't find method named '#{name}'"
|
468
|
+
return
|
469
|
+
end
|
472
470
|
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
471
|
+
printf "file: %s\n", @@file[name]
|
472
|
+
printf "size: %d\n", @@size[name]
|
473
|
+
printf "base: %d\n", @@base[name]
|
474
|
+
printf "probes: %s\n", @@probes[name].inspect
|
475
|
+
end
|
478
476
|
|
479
477
|
end # Source
|
480
478
|
|
479
|
+
=begin rdoc
|
480
|
+
Module for interactive graphics.
|
481
|
+
=end
|
482
|
+
|
483
|
+
module Canvas
|
484
|
+
|
485
|
+
def Canvas.init(width, height, title, *opts)
|
486
|
+
require 'tk'
|
487
|
+
|
488
|
+
@@title = "RubyLabs::#{title}"
|
489
|
+
@@width = width
|
490
|
+
@@height = height
|
491
|
+
|
492
|
+
if @@tkroot.nil?
|
493
|
+
# @@tkroot = TkRoot.new { title @@title }
|
494
|
+
# @@content = TkFrame.new(@@tkroot)
|
495
|
+
# @@canvas = TkCanvas.new(@@content, :width => width, :height => height)
|
496
|
+
# @@canvas.grid :column => 0, :row => 0, :columnspan => 4, :padx => 10, :pady => 10
|
497
|
+
# @@content.pack :pady => 20
|
498
|
+
|
499
|
+
@@tkroot = TkRoot.new { title @@title }
|
500
|
+
# @@content = TkFrame.new(@@tkroot)
|
501
|
+
@@canvas = TkCanvas.new(@@tkroot, :width => width, :height => height)
|
502
|
+
# @@canvas.grid :column => 0, :row => 0, :columnspan => 4, :padx => 10, :pady => 10
|
503
|
+
@@canvas.pack :padx => 10, :pady => 10
|
504
|
+
# @@content.pack :pady => 20
|
505
|
+
|
506
|
+
@@threads = []
|
507
|
+
@@threads << Thread.new() do
|
508
|
+
Tk.mainloop
|
509
|
+
end
|
510
|
+
else
|
511
|
+
Canvas.clear
|
512
|
+
@@canvas.height = height
|
513
|
+
@@canvas.width = width
|
514
|
+
@@tkroot.title = @@title
|
515
|
+
end
|
516
|
+
return opts[0] == :debug ? @@canvas : true
|
517
|
+
end
|
518
|
+
|
519
|
+
def Canvas.width
|
520
|
+
@@width
|
521
|
+
end
|
522
|
+
|
523
|
+
def Canvas.height
|
524
|
+
@@height
|
525
|
+
end
|
526
|
+
|
527
|
+
def Canvas.root
|
528
|
+
@@tkroot
|
529
|
+
end
|
530
|
+
|
531
|
+
# Idea for the future, abandoned for now: allow applications to define a coordinate
|
532
|
+
# system, e.g. cartesian with the origin in the middle of the canvas, and map coords
|
533
|
+
# pass to line, rectangle, etc from user-specified coordinates to Tk coordinates.
|
534
|
+
# Lots of complications, though -- e.g. if an application calls the coords method to
|
535
|
+
# get object coordinates (e.g. RandomLab#add_tick gets y coordinate of number line)
|
536
|
+
# it will have to map back from Tk to the selected mapping.....
|
537
|
+
|
538
|
+
# def Canvas.origin(option)
|
539
|
+
# case option
|
540
|
+
# when :tk
|
541
|
+
# @@map = lambda { |x,y| return x, y }
|
542
|
+
# when :quadrant
|
543
|
+
# @@map = lambda { |x,y| return x, @@height - y }
|
544
|
+
# when :cartesian
|
545
|
+
# @@map = lambda { |x,y| return x + @@width/2, @@height/2 - y }
|
546
|
+
# end
|
547
|
+
# end
|
548
|
+
#
|
549
|
+
# def Canvas.map(a)
|
550
|
+
# (0...a.length).step(2) do |i|
|
551
|
+
# a[i], a[i+1] = @@map.call( a[i], a[i+1] )
|
552
|
+
# end
|
553
|
+
# end
|
554
|
+
|
555
|
+
def Canvas.clear
|
556
|
+
@@objects.each { |x| x.delete }
|
557
|
+
@@objects.clear
|
558
|
+
end
|
559
|
+
|
560
|
+
# total hack -- if on OS X and version is 1.8 and called directly from irb pause to
|
561
|
+
# synch the drawing thread....
|
562
|
+
|
563
|
+
def Canvas.sync
|
564
|
+
if RUBY_VERSION =~ %r{^1\.8} && RUBY_PLATFORM =~ %r{darwin} && caller[2] =~ %r{workspace}
|
565
|
+
sleep(0.1)
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
=begin rdoc
|
570
|
+
Draw a line from (x0,y0) to (x1,y1)
|
571
|
+
=end
|
572
|
+
|
573
|
+
def Canvas.line(x0, y0, x1, y1, opts = {})
|
574
|
+
return nil unless @@canvas
|
575
|
+
line = TkcLine.new( @@canvas, x0, y0, x1, y1, opts )
|
576
|
+
@@objects << line
|
577
|
+
return line
|
578
|
+
end
|
579
|
+
|
580
|
+
=begin rdoc
|
581
|
+
Draw a rectangle with upper left at (x0,y0) and lower right at (x1,y1).
|
582
|
+
=end
|
583
|
+
|
584
|
+
def Canvas.rectangle(x0, y0, x1, y1, opts = {})
|
585
|
+
return nil unless @@canvas
|
586
|
+
rect = TkcRectangle.new( @@canvas, x0, y0, x1, y1, opts)
|
587
|
+
Canvas.makeObject(rect, (x1-x0)/2, (y1-y0)/2)
|
588
|
+
end
|
589
|
+
|
590
|
+
=begin rdoc
|
591
|
+
Draw a circle with center at (x,y) and radius r
|
592
|
+
=end
|
593
|
+
|
594
|
+
def Canvas.circle(x, y, r, opts = {})
|
595
|
+
return nil unless @@canvas
|
596
|
+
ulx, uly, lrx, lry = x-r, y-r, x+r, y+r
|
597
|
+
circ = TkcOval.new( @@canvas, ulx, uly, lrx, lry, opts )
|
598
|
+
Canvas.makeObject(circ, r, r)
|
599
|
+
end
|
600
|
+
|
601
|
+
=begin rdoc
|
602
|
+
Draw a polygon with vertices defined by array a. The array can be a flat
|
603
|
+
list of x's and y's (e.g. [100,100,100,200,200,100]) or a list of (x,y)
|
604
|
+
pairs (e.g. [[100,100], [100,200], [200,100]]).
|
605
|
+
=end
|
606
|
+
|
607
|
+
def Canvas.polygon(a, opts = {})
|
608
|
+
return nil unless @@canvas
|
609
|
+
poly = TkcPolygon.new( @@canvas, a, opts)
|
610
|
+
Canvas.makeObject(poly, 0, 0)
|
611
|
+
end
|
612
|
+
|
613
|
+
=begin rdoc
|
614
|
+
Move an object by an amount dx, dy
|
615
|
+
=end
|
616
|
+
|
617
|
+
def Canvas.move(obj, dx, dy, option = nil)
|
618
|
+
a = obj.coords
|
619
|
+
if option == :track
|
620
|
+
x0 = a[0] + obj.penx
|
621
|
+
y0 = a[1] + obj.peny
|
622
|
+
end
|
623
|
+
(0...a.length).step(2) do |i|
|
624
|
+
a[i] += dx
|
625
|
+
a[i+1] += dy
|
626
|
+
end
|
627
|
+
obj.coords = a
|
628
|
+
if option == :track
|
629
|
+
x1 = a[0] + obj.penx
|
630
|
+
y1 = a[1] + obj.peny
|
631
|
+
@@objects << TkcLine.new( @@canvas, x0, y0, x1, y1, :width => 1, :fill => '#777777' )
|
632
|
+
obj.raise
|
633
|
+
end
|
634
|
+
return a
|
635
|
+
end
|
636
|
+
|
637
|
+
=begin rdoc
|
638
|
+
Attach a "pen point" to an object by adding new accessor methods named penx and peny,
|
639
|
+
and save the object in a local list so it can be erased by Canvas.clear
|
640
|
+
=end
|
641
|
+
|
642
|
+
def Canvas.makeObject(obj, xoff, yoff)
|
643
|
+
class <<obj
|
644
|
+
attr_accessor :penx, :peny
|
645
|
+
end
|
646
|
+
obj.penx = xoff
|
647
|
+
obj.peny = yoff
|
648
|
+
@@objects << obj
|
649
|
+
return obj
|
650
|
+
end
|
651
|
+
|
652
|
+
=begin rdoc
|
653
|
+
Rotate an object by an angle theta (expressed in degrees). The object is
|
654
|
+
rotated about the point defined by the first pair of (x,y) coordinates.
|
655
|
+
=end
|
656
|
+
|
657
|
+
def Canvas.rotate(obj, theta)
|
658
|
+
theta = Canvas.radians(theta)
|
659
|
+
a = obj.coords
|
660
|
+
x0 = a[0]
|
661
|
+
y0 = a[1]
|
662
|
+
(0...a.length).step(2) do |i|
|
663
|
+
x = a[i] - x0
|
664
|
+
y = a[i+1] - y0
|
665
|
+
a[i] = x0 + x * Math.cos(theta) - y * Math.sin(theta)
|
666
|
+
a[i+1] = y0 + x * Math.sin(theta) + y * Math.cos(theta)
|
667
|
+
end
|
668
|
+
obj.coords = a
|
669
|
+
return a
|
670
|
+
end
|
671
|
+
|
672
|
+
def Canvas.radians(deg)
|
673
|
+
deg * Math::PI / 180
|
674
|
+
end
|
675
|
+
|
676
|
+
def Canvas.degrees(rad)
|
677
|
+
180 * rad / Math::PI
|
678
|
+
end
|
679
|
+
|
680
|
+
@@tkroot = nil
|
681
|
+
@@objects = Array.new
|
682
|
+
@@title = ""
|
683
|
+
@@height = 0
|
684
|
+
@@width = 0
|
685
|
+
@@map = lambda { |x,y| return x, y }
|
686
|
+
|
687
|
+
=begin rdoc
|
688
|
+
Make an array of n colors that vary from first to last.
|
689
|
+
=end
|
690
|
+
|
691
|
+
def Canvas.palette(first, last, n)
|
692
|
+
d = Array.new(3)
|
693
|
+
3.times { |i| d[i] = (first[i] - last[i]) / n }
|
694
|
+
a = [first]
|
695
|
+
(n-1).times do |i|
|
696
|
+
a << a.last.clone
|
697
|
+
3.times { |j| a.last[j] -= d[j] }
|
698
|
+
end
|
699
|
+
a << last
|
700
|
+
a.map { |c| sprintf("#%02X%02X%02X",c[0],c[1],c[2]) }
|
701
|
+
end
|
702
|
+
|
703
|
+
end # Canvas
|
704
|
+
|
481
705
|
=begin rdoc
|
482
706
|
Priority queue class -- simple wrapper for an array that can only be updated via
|
483
707
|
+<<+ and +shift+ operations. Also responds to +length+, +first+, and +last+,
|