June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
13
Task/Voronoi-diagram/Julia/voronoi-diagram-1.julia
Normal file
13
Task/Voronoi-diagram/Julia/voronoi-diagram-1.julia
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using Images
|
||||
function voronoi(w, h, n_centroids)
|
||||
dist = (point,vector) -> sqrt.((point[1].-vector[:,1]).^2 .+ (point[2].-vector[:,2]).^2)
|
||||
dots = [rand(1:h, n_centroids) rand(1:w, n_centroids) rand(RGB{N0f8}, n_centroids)]
|
||||
img = zeros(RGB{N0f8}, h, w)
|
||||
for x in 1:h, y in 1:w
|
||||
distances = dist([x,y],dots) # distance
|
||||
nn = findmin(distances)[2]
|
||||
img[x,y] = dots[nn,:][3]
|
||||
end
|
||||
return img
|
||||
end
|
||||
img = voronoi(800, 600, 200)
|
||||
21
Task/Voronoi-diagram/Julia/voronoi-diagram-2.julia
Normal file
21
Task/Voronoi-diagram/Julia/voronoi-diagram-2.julia
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using TestImages, Images
|
||||
function voronoi_img!(img, n_centroids)
|
||||
n,m = size(img)
|
||||
w = minimum([n,m])
|
||||
dist = (point,vector) -> sqrt.((point[1].-vector[:,1]).^2 .+ (point[2].-vector[:,2]).^2)
|
||||
dots = [rand(1:n, n_centroids) rand(1:m, n_centroids)]
|
||||
c = []
|
||||
for i in 1:size(dots,1)
|
||||
p = dots[i,:]
|
||||
append!(c, [img[p[1],p[2]]])
|
||||
end
|
||||
dots = [dots c]
|
||||
|
||||
for x in 1:n, y in 1:m
|
||||
distances = dist([x,y],dots) # distance
|
||||
nn = findmin(distances)[2]
|
||||
img[x,y] = dots[nn,:][3]
|
||||
end
|
||||
end
|
||||
img = testimage("mandrill")
|
||||
voronoi_img!(img, 300)
|
||||
46
Task/Voronoi-diagram/Perl-6/voronoi-diagram.pl6
Normal file
46
Task/Voronoi-diagram/Perl-6/voronoi-diagram.pl6
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
use Image::PNG::Portable;
|
||||
|
||||
my @bars = '▁▂▃▄▅▆▇█▇▆▅▄▃▂▁'.comb;
|
||||
|
||||
my %type = ( # Voronoi diagram type distance calculation
|
||||
'Taxicab' => sub ($px, $py, $x, $y) { ($px - $x).abs + ($py - $y).abs },
|
||||
'Euclidean' => sub ($px, $py, $x, $y) { ($px - $x)² + ($py - $y)² },
|
||||
'Minkowski' => sub ($px, $py, $x, $y) { ($px - $x)³.abs + ($py - $y)³.abs },
|
||||
);
|
||||
|
||||
my $width = 400;
|
||||
my $height = 400;
|
||||
my $dots = 30;
|
||||
|
||||
my @domains = map { Hash.new(
|
||||
'x' => (5..$width-5).roll,
|
||||
'y' => (5..$height-5).roll,
|
||||
'rgb' => [(64..255).roll xx 3]
|
||||
) }, ^$dots;
|
||||
|
||||
for %type.keys -> $type {
|
||||
print "\nGenerating $type diagram... ", ' ' x @bars;
|
||||
my $img = voronoi(@domains, :w($width), :h($height), :$type);
|
||||
@domains.map: *.&dot($img);
|
||||
$img.write: "Voronoi-{$type}-perl6.png";
|
||||
}
|
||||
|
||||
sub voronoi (@domains, :$w, :$h, :$type) {
|
||||
my $png = Image::PNG::Portable.new: :width($w), :height($h);
|
||||
for ^$w -> $x {
|
||||
print "\b" x 2+@bars, @bars.=rotate(1).join , ' ';
|
||||
for ^$h -> $y {
|
||||
my ($, $i) = min @domains.map: { %type{$type}(%($_)<x>, %($_)<y>, $x, $y), $++ };
|
||||
$png.set: $x, $y, |@domains[$i]<rgb>
|
||||
}
|
||||
}
|
||||
$png
|
||||
}
|
||||
|
||||
sub dot (%h, $png, $radius = 3) {
|
||||
for %h<x> - $radius .. %h<x> + $radius -> $x {
|
||||
for %h<y> - $radius .. %h<y> + $radius -> $y {
|
||||
$png.set($x, $y, 0, 0, 0) if ( %h<x> - $x + (%h<y> - $y) * i ).abs <= $radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
124
Task/Voronoi-diagram/Ring/voronoi-diagram.ring
Normal file
124
Task/Voronoi-diagram/Ring/voronoi-diagram.ring
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
# Project : Voronoi diagram
|
||||
# Date : 2018/03/30
|
||||
# Author : Gal Zsolt [~ CalmoSoft ~]
|
||||
# Email : <calmosoft@gmail.com>
|
||||
|
||||
load "guilib.ring"
|
||||
load "stdlib.ring"
|
||||
paint = null
|
||||
|
||||
new qapp
|
||||
{
|
||||
spots = 100
|
||||
leftside = 400
|
||||
rightside = 400
|
||||
|
||||
locx = list(spots)
|
||||
locy = list(spots)
|
||||
rgb = newlist(spots,3)
|
||||
seal = newlist(leftside, rightside)
|
||||
reach = newlist(leftside, rightside)
|
||||
|
||||
win1 = new qwidget() {
|
||||
setwindowtitle("Voronoi diagram")
|
||||
setgeometry(100,100,800,600)
|
||||
label1 = new qlabel(win1) {
|
||||
setgeometry(10,10,800,600)
|
||||
settext("")
|
||||
}
|
||||
new qpushbutton(win1) {
|
||||
setgeometry(150,550,100,30)
|
||||
settext("draw")
|
||||
setclickevent("draw()")
|
||||
}
|
||||
show()
|
||||
}
|
||||
exec()
|
||||
}
|
||||
|
||||
func draw
|
||||
p1 = new qpicture()
|
||||
color = new qcolor() {
|
||||
setrgb(0,0,255,255)
|
||||
}
|
||||
pen = new qpen() {
|
||||
setcolor(color)
|
||||
setwidth(1)
|
||||
}
|
||||
paint = new qpainter() {
|
||||
begin(p1)
|
||||
setpen(pen)
|
||||
|
||||
for i =1 to spots
|
||||
locx[i] = floor(leftside * randomf())
|
||||
locy[i] = floor(rightside * randomf())
|
||||
rgb[i][1] = floor(256 * randomf())
|
||||
rgb[i][2] = floor(256 * randomf())
|
||||
rgb[i][3] = floor(256 * randomf())
|
||||
next
|
||||
for x = 1 to leftside
|
||||
for y = 1 to rightside
|
||||
reach[x][y] = pow((locx[1] - x),2) + pow((locy[1] - y),2)
|
||||
seal[x][y] = 1
|
||||
next
|
||||
next
|
||||
for i = 2 to spots
|
||||
for x = locx[i] to 0 step -1
|
||||
if not (chkpos(i,x,1, rightside-1))
|
||||
exit
|
||||
ok
|
||||
next
|
||||
for x = locx[i] + 1 to leftside - 1
|
||||
if not (chkpos(i, x, 1, rightside-1))
|
||||
exit
|
||||
ok
|
||||
next
|
||||
next
|
||||
for x = 1 to leftside
|
||||
for y = 1 to rightside
|
||||
c1 = rgb[seal[x][y]][1]
|
||||
c2 = rgb[seal[x][y]][2]
|
||||
c3 = rgb[seal[x][y]][3]
|
||||
color = new qcolor() { setrgb(c1,c2,c3,255) }
|
||||
pen = new qpen() { setcolor(color) setwidth(10) }
|
||||
setpen(pen)
|
||||
starty = y
|
||||
nearest = seal[x][y]
|
||||
for y = (y + 1) to rightside
|
||||
if seal[x][y] != nearest
|
||||
y = y - 1
|
||||
exit
|
||||
ok
|
||||
next
|
||||
paint.drawline(x,starty,x,y + 1)
|
||||
next
|
||||
next
|
||||
endpaint()
|
||||
}
|
||||
label1 { setpicture(p1) show() }
|
||||
return
|
||||
|
||||
func chkpos(site,x,starty,endy)
|
||||
chkpos = 0
|
||||
dxsqr = 0
|
||||
dxsqr = pow((locx[site]- x),2)
|
||||
for y = starty to endy
|
||||
dsqr = pow((locy[site] - y),2) + dxsqr
|
||||
if x <= leftside and y <= leftside and x > 0 and y > 0
|
||||
if dsqr <= reach[x][y]
|
||||
reach[x][y] = dsqr
|
||||
seal[x][y] = site
|
||||
chkpos = 1
|
||||
ok
|
||||
ok
|
||||
next
|
||||
return chkpos
|
||||
|
||||
func randomf()
|
||||
decimals(10)
|
||||
str = "0."
|
||||
for i = 1 to 10
|
||||
nr = random(9)
|
||||
str = str + string(nr)
|
||||
next
|
||||
return number(str)
|
||||
180
Task/Voronoi-diagram/Rust/voronoi-diagram.rust
Normal file
180
Task/Voronoi-diagram/Rust/voronoi-diagram.rust
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
extern crate piston;
|
||||
extern crate opengl_graphics;
|
||||
extern crate graphics;
|
||||
extern crate touch_visualizer;
|
||||
|
||||
#[cfg(feature = "include_sdl2")]
|
||||
extern crate sdl2_window;
|
||||
|
||||
extern crate getopts;
|
||||
extern crate voronoi;
|
||||
extern crate rand;
|
||||
|
||||
use touch_visualizer::TouchVisualizer;
|
||||
use opengl_graphics::{ GlGraphics, OpenGL };
|
||||
use graphics::{ Context, Graphics };
|
||||
use piston::window::{ Window, WindowSettings };
|
||||
use piston::input::*;
|
||||
use piston::event_loop::*;
|
||||
#[cfg(feature = "include_sdl2")]
|
||||
use sdl2_window::Sdl2Window as AppWindow;
|
||||
use voronoi::{voronoi, Point, make_polygons};
|
||||
use rand::Rng;
|
||||
|
||||
static DEFAULT_WINDOW_HEIGHT: u32 = 600;
|
||||
static DEFAULT_WINDOW_WIDTH: u32 = 600;
|
||||
|
||||
struct Settings {
|
||||
lines_only: bool,
|
||||
random_count: usize
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let mut opts = getopts::Options::new();
|
||||
opts.optflag("l", "lines_only", "Don't color polygons, just outline them");
|
||||
opts.optopt("r", "random_count", "On keypress \"R\", put this many random points on-screen", "RANDOMCOUNT");
|
||||
let matches = opts.parse(&args[1..]).expect("Failed to parse args");
|
||||
|
||||
let settings = Settings{
|
||||
lines_only: matches.opt_present("l"),
|
||||
random_count: match matches.opt_str("r") {
|
||||
None => { 50 },
|
||||
Some(s) => { s.parse().expect("Random count of bad format") }
|
||||
}
|
||||
};
|
||||
|
||||
event_loop(&settings);
|
||||
|
||||
}
|
||||
|
||||
fn random_point() -> [f64; 2] {
|
||||
[rand::thread_rng().gen_range(0., DEFAULT_WINDOW_HEIGHT as f64), rand::thread_rng().gen_range(0., DEFAULT_WINDOW_WIDTH as f64)]
|
||||
}
|
||||
|
||||
fn random_color() -> [f32; 4] {
|
||||
[rand::random::<f32>(), rand::random::<f32>(), rand::random::<f32>(), 1.0]
|
||||
}
|
||||
|
||||
fn random_voronoi(dots: &mut Vec<[f64;2]>, colors: &mut Vec<[f32;4]>, num: usize) {
|
||||
dots.clear();
|
||||
colors.clear();
|
||||
|
||||
for _ in 0..num {
|
||||
dots.push(random_point());
|
||||
colors.push(random_color());
|
||||
}
|
||||
}
|
||||
|
||||
fn event_loop(settings: &Settings) {
|
||||
let opengl = OpenGL::V3_2;
|
||||
let mut window: AppWindow = WindowSettings::new("Interactive Voronoi", [DEFAULT_WINDOW_HEIGHT, DEFAULT_WINDOW_WIDTH])
|
||||
.exit_on_esc(true).opengl(opengl).build().unwrap();
|
||||
|
||||
let ref mut gl = GlGraphics::new(opengl);
|
||||
let mut touch_visualizer = TouchVisualizer::new();
|
||||
let mut events = Events::new(EventSettings::new().lazy(true));
|
||||
let mut dots = Vec::new();
|
||||
let mut colors = Vec::new();
|
||||
|
||||
let mut mx = 0.0;
|
||||
let mut my = 0.0;
|
||||
|
||||
while let Some(e) = events.next(&mut window) {
|
||||
touch_visualizer.event(window.size(), &e);
|
||||
if let Some(button) = e.release_args() {
|
||||
match button {
|
||||
Button::Keyboard(key) => {
|
||||
if key == piston::input::keyboard::Key::N { dots.clear(); colors.clear(); }
|
||||
if key == piston::input::keyboard::Key::R { random_voronoi(&mut dots, &mut colors, settings.random_count); }
|
||||
}
|
||||
Button::Mouse(_) => {
|
||||
dots.push([mx, my]);
|
||||
colors.push(random_color());
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
};
|
||||
e.mouse_cursor(|x, y| {
|
||||
mx = x;
|
||||
my = y;
|
||||
});
|
||||
if let Some(args) = e.render_args() {
|
||||
gl.draw(args.viewport(), |c, g| {
|
||||
graphics::clear([1.0; 4], g);
|
||||
let mut vor_pts = Vec::new();
|
||||
for d in &dots {
|
||||
vor_pts.push(Point::new(d[0], d[1]));
|
||||
}
|
||||
if vor_pts.len() > 0 {
|
||||
let vor_diagram = voronoi(vor_pts, DEFAULT_WINDOW_WIDTH as f64);
|
||||
let vor_polys = make_polygons(&vor_diagram);
|
||||
for (i, poly) in vor_polys.iter().enumerate() {
|
||||
if settings.lines_only {
|
||||
draw_lines_in_polygon(poly, &c, g);
|
||||
} else {
|
||||
draw_polygon(poly, &c, g, colors[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for d in &dots {
|
||||
draw_ellipse(&d, &c, g);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn draw_lines_in_polygon<G: Graphics>(
|
||||
poly: &Vec<Point>,
|
||||
c: &Context,
|
||||
g: &mut G,
|
||||
)
|
||||
{
|
||||
let color = [0.0, 0.0, 1.0, 1.0];
|
||||
|
||||
for i in 0..poly.len()-1 {
|
||||
graphics::line(
|
||||
color,
|
||||
2.0,
|
||||
[poly[i].x.into(), poly[i].y.into(), poly[i+1].x.into(), poly[i+1].y.into()],
|
||||
c.transform,
|
||||
g
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_polygon<G: Graphics>(
|
||||
poly: &Vec<Point>,
|
||||
c: &Context,
|
||||
g: &mut G,
|
||||
color: [f32; 4]
|
||||
) {
|
||||
let mut polygon_points: Vec<[f64; 2]> = Vec::new();
|
||||
|
||||
for p in poly {
|
||||
polygon_points.push([p.x.into(), p.y.into()]);
|
||||
}
|
||||
|
||||
graphics::polygon(
|
||||
color,
|
||||
polygon_points.as_slice(),
|
||||
c.transform,
|
||||
g
|
||||
)
|
||||
}
|
||||
|
||||
fn draw_ellipse<G: Graphics>(
|
||||
cursor: &[f64; 2],
|
||||
c: &Context,
|
||||
g: &mut G,
|
||||
) {
|
||||
let color = [0.0, 0.0, 0.0, 1.0];
|
||||
graphics::ellipse(
|
||||
color,
|
||||
graphics::ellipse::circle(cursor[0], cursor[1], 4.0),
|
||||
c.transform,
|
||||
g
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue