rubylabs 0.6.4 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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+,
|