Diary SiteMap RecentChanges About Contact Calendar

Search:

Matching Pages:

SVG

Wikipedia:SVG – Scalable Vector Graphics. Images that consist of lines and shapes and text and fonts, and not pixels. They look the same, but vector graphics can be scaled effortlessly, and could potentially be rearranged without necessarily loosing any information.

I recommend InkScape to edit SVG files. Inkscape used to crash often, but these days I’m very happy with it.

2013-03-04 Text Mapper With Lines

SVG Mapper now knows how to draw lines. These lines try to flow from hex to hex…

Example input:

2114 hill
2115 hill
2213 forest
2214 forest "Delan"
2215 hill
2314 forest
2315 forest
2414 hill "Forest Bight Fortress"
2415 forest
2515 forest "Boghra Little"

2214-2615 river
river path attributes fill-opacity="0" stroke="black" stroke-width="5"

include http://alexschroeder.ch/contrib/default.txt

Result:

Dangerous Forest

I think that I’m not quite understanding how the viewBox is supposed to work. But anyway: these lines can be used for roads, rivers, borders, cliffs, and the like. If they’re very straight, they don’t look too good. There’s no random waviness. One feature I definitely have to add is providing more intermediary points such that the user can guide rivers around the hills or to allow rivers to merge.

Tags: RSS RSS RSS

Add Comment

2013-03-01 Text Mapper Progress

I’m a big fan of the Forgotten Depths. I wanted to use its map as the goal for my Text Mapper. As the mapper now allows the inclusion of other files, I’ve saved my library of colors and icons as default.txt and I’ve saved the map as forgotten-depths.txt. That’s why all you need to do now is include the map:

Forgotten Depths SVG

If you see white hexes, then I haven’t added any definitions for them, yet.

Tags: RSS RSS RSS RSS

Comments on 2013-03-01 Text Mapper Progress

Wow, this looks great! I think I’ll need to re-map parts of the Mystara campaign … I may have some time on Sunday.

– Harald 2013-03-01 10:56 UTC



AlexSchroeder
Too bad creating new icons takes so damn long. Also, two line labels would be nice. And big, diagonal labels to label areas. “Mirkwood” or something like it. Nice coastlines, roads, rivers…

Regarding roads and rivers: I’m discovering that Bézier curves need a bit more effort since simply doing a quadratic curveto (’T’ in the SVG spec) the hex midpoints isn’t working very well. I will need to rediscover my trigonometry basics!

AlexSchroeder 2013-03-01 12:00 UTC

Add Comment

2013-02-27 SVG Filters

I need help with SVG filters. This question is also on StackOverflow.

This is what I want to achieve:

https://farm9.staticflickr.com/8507/8511938807_5a793d726a.jpg

Previously, I’d duplicate the text element, make the background white, and blur it:

  <defs>
    <filter id="label-glow">
      <feGaussianBlur stdDeviation="1" />
    </filter>
  </defs>
  <text stroke="white" stroke-width="5" filter="url(#label-glow)">Harald's Repose</text>
  <text>Harald's Repose</text>

I’m trying not to duplicate the text element. Here’s how to do it using filters:

  <defs>
    <filter id="label-glow">
      <feFlood flood-color="white"/>
      <feComposite in2="SourceGraphic" operator="in"/>
      <feGaussianBlur stdDeviation="2"/>
      <feComposite operator="over"/>
      <feComposite operator="over"/>
      <feComposite operator="over"/>
      <feComposite operator="over"/>
      <feComposite in="SourceGraphic"/>
    </filter>
  </defs>
  <text filter="url(#label-glow)">Harald's Repose</text>

Unfortunately the output of the Gaussian blur is very weak which is why I need to overlay it multiple times. What am I missing?

Update: As I’ve been experimenting with it, I’ve decided to drop filters altogether. When using Firefox and printing the map to PDF, the filters all result in bitmap elements that don’t scale well.

Tags: RSS RSS

Add Comment

2013-02-27 New Text Mapper Shapes

How to create new shapes for Text Mapper?

First, start with an empty SVG file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
     height="200px"
     width="200px">
</svg>

I like to draw stuff using the calligraphy tool (c). I usually simplify the nodes a lot (Ctrl+L), unify the shapes (Ctrl++), edit the nodes by hand (n) until you’re happy with the fewest number of nodes you can manage.

Now move the entire shape such that it is centered on the top left corner. This is (0,0) as far as SVG is concerned. Save it.

https://farm9.staticflickr.com/8240/8512911746_4f1c405dba_o.png

Look at the SVG file and notice something like this:

    <path
       style="fill:#000000;fill-opacity:1;stroke:none"
       d="m 7.647323,-20.341905 c -5.784973,-11.791839
       -36.204242,-5.139394 -43.951039,7.112364 8.922877,-5.977096
       34.793258,-11.641806 37.046343,-5.498373 -17.505656,0.485788
       -29.019956,5.940662 -33.027811,23.8472764 C
       -21.859546,-12.603312 -7.5022983,-14.191144 2.47485,-12.984161
       -8.2112223,6.06712 -19.987316,13.477858 -15.788864,50.225619 c
       3.988368,3.362713 8.6116517,-5.097214 4.510279,-7.531518
       -0.559084,-6.64895 -0.875559,-13.360661 -0.08632,-20.004922 C
       -9.6892813,9.718021 1.072969,-6.510207 8.835372,-12.256094
       26.823805,-7.758432 35.550312,0.1756144 34.450001,15.351883
       44.387089,3.7916614 29.882349,-11.701263 14.406587,-15.219388
       28.287217,-15.939127 40.549839,-6.589098 45.412784,1.4541824
       47.026796,-8.361333 28.866764,-19.205208 16.79733,-20.277164 c
       10.765708,-6.95198 25.316253,-3.074379 29.792108,3.226712
       -4.893545,-14.115874 -36.158133,-10.60357 -38.942114,-3.291453
       z"
       id="path3007"
       inkscape:connector-curvature="0"
       sodipodi:nodetypes="ccccccccccccccc" />

You can already extract this path and use it! Usually it takes several attempts to get the placement right. Once I’m happy, I turn all these floating point numbers into integers in order to save space. Personally, I use Emacs to do it (EmacsWiki:RoundFloatingPoints).

This is what I want:

m 8,-20 c -6,-12 -36,-5 -44,7 9,-6 35,-12 37,-5 -18,0 -29,6 -33,24 C -22,-13
-8,-14 2,-13 -8,6 -20,13 -16,50 c 4,3 9,-5 5,-8 -1,-7 -1,-13 0,-20 C -10,10 1,-7
9,-12 27,-8 36,0 34,15 44,4 30,-12 14,-15 28,-16 41,-7 45,1 47,-8 29,-19 17,-20
c 11,-7 25,-3 30,3 -5,-14 -36,-11 -39,-3 z

Example input:

0202 jungle
jungle attributes fill="white" stroke="#b3b3ff" stroke-width="3"
jungle path m 8,-20 c -6,-12 -36,-5 -44,7 9,-6 35,-12 37,-5 -18,0 -29,6 -33,24 C -22,-13 -8,-14 2,-13 -8,6 -20,13 -16,50 c 4,3 9,-5 5,-8 -1,-7 -1,-13 0,-20 C -10,10 1,-7 9,-12 27,-8 36,0 34,15 44,4 30,-12 14,-15 28,-16 41,-7 45,1 47,-8 29,-19 17,-20 c 11,-7 25,-3 30,3 -5,-14 -36,-11 -39,-3 z

Output:

Jungle Hex

Example input:

0101 jungle
jungle attributes fill="#9acd32" stroke="black" stroke-width="3"
jungle path attributes fill="#228b22"
jungle path m 8,-20 c -6,-12 -36,-5 -44,7 9,-6 35,-12 37,-5 -18,0 -29,6 -33,24 C -22,-13 -8,-14 2,-13 -8,6 -20,13 -16,50 c 4,3 9,-5 5,-8 -1,-7 -1,-13 0,-20 C -10,10 1,-7 9,-12 27,-8 36,0 34,15 44,4 30,-12 14,-15 28,-16 41,-7 45,1 47,-8 29,-19 17,-20 c 11,-7 25,-3 30,3 -5,-14 -36,-11 -39,-3 z
text font-size="20pt" dy="15px"

Output:

Green Jungle Hex

Tags: RSS RSS RSS RSS

Comments on 2013-02-27 New Text Mapper Shapes

Not enough trees for a jungle (-: At a watering hole and you have a decent oasis …

– Harald 2013-02-27 11:17 UTC



AlexSchroeder
There you go!

Oasis

I think I like how easy it turns out to be.

AlexSchroeder 2013-02-27 11:29 UTC



AlexSchroeder
I’m still pondering how to do labels.

https://farm9.staticflickr.com/8507/8511938807_5a793d726a.jpg

AlexSchroeder 2013-02-27 12:01 UTC


Very nice and readable!

– Harald 2013-02-27 12:37 UTC



AlexSchroeder
Thank you for the feedback. Added. :)

Harald's Repose

AlexSchroeder 2013-02-27 14:10 UTC

Add Comment

2012-09-01 SVG Character Sheet

For a while now I’ve been using this German SVG character sheet for my Labyrinth Lord game (it uses the Purisa font):

I’ve now written a little Perl script that allows you to fill in some of these variables using parameters. (Source)

Here’s an example URL:

http://campaignwiki.org/halberdsnhelmets?name=Alex;class=Elf;level=1;xp=0;ac=5;str=8;dex=18;con=9;int=10;wis=14;cha=15;breath=11;petrify=12;poison=13;wands=15;spells=16;hp=10;thac0=20;property=one%5c%5ctwo;abilities=elvish%5c%5corcish

Result:

It needs more polishing and possibly the option of selecting different character sheets.

I’ve written a text formatting rule for my Campaign Wiki that makes it easy to put your character’s stats on a web page and have it render as a SVG character sheet.

Tags: RSS RSS RSS RSS

Comments on 2012-09-01 SVG Character Sheet

Do they attributes have different bonus tables? If not, why is the bonus for „Geschick“ only +1 and the bonus for „Weisheit“ +2?

Stefan 2012-09-03 06:11 UTC



AlexSchroeder
A bug that I had introduced while reshuffeling the code. Any value of 15+ resulted in a bonus of +1. :)

AlexSchroeder 2012-09-03 08:16 UTC



AlexSchroeder
The default character sheet now supports a parameter named “portrait” with the value being the URL of an image to use. Example.

Too bad this doesn’t work when displaying SVG files using an image tag as part of an XHTML document. Example.

The reason is that the img tag will only load the URL provided. It will not follow further URLs (such as the font or the embedded image). I could use data URLs and waste a lot of bandwidth, or I could use a different tag (frame or object). When I tried using other tags, however, there’s a different kind of problem: clicking on the link resulted in the script being run in special frame, still inside the original page. That’s very confusing for users.

Embedding the entire SVG document “works” – the validators choke on it, however. The declaration that all style elements will be using CSS is missing, the namespace declarations on the svg tag are not allowed, and so on. It looks ok in my browser, however. :)

AlexSchroeder 2012-12-11

Add Comment

2011-04-30 Map Drawing Using Polygons

I’m currently working on randomly generating islands using the ideas presented in Polygonal Map Generation by Amit. Check out his Flash demo! I am nowhere as far, yet. I’m writing my code in Perl and producing SVG output.

http://farm6.static.flickr.com/5303/5671163434_e3b86d4dde.jpg

See below for source code used. I’d install it on a public server, but unfortunately there are quite some dependencies…

Tags: RSS RSS RSS

#! /usr/bin/perl -w
# Copyright (C) 2011  Alex Schroeder <alex@gnu.org>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.

use strict;
use CGI qw(:standard);
use SVG;
use Math::Geometry::Voronoi;
use Class::Struct;
use Math::Fractal::Noisemaker;
use List::Util qw(min max);
use Data::Dumper;

my $points = 3000;
my $width  = 1000;
my $height =  550;
my $center_x = $width / 2;
my $center_y = $height / 2;
my $radius = 500;

my %color = (beach => '#a09077',
	     ocean => '#44447a',);

struct World => { points => '@',
		  centroids => '@',
		  voronoi => '$',
		  height => '@',
		};

sub add_random_points {
  my ($world) = @_;
  for (my $i = 0; $i < $points; $i++) {
    push(@{$world->points}, [rand($width), rand($height)]);
  };
  # print(join("\n", map {join(",", $_->[0], $_->[1])} @{$world->points}));
  return $world;
}

sub add_voronoi {
  my ($world) = @_;
  $world->voronoi(Math::Geometry::Voronoi->new(points => $world->points));
  $world->voronoi->compute;
}

sub add_centroids {
  my ($world) = @_;
  $world->centroids([]); # clear
  foreach my $polygon ($world->voronoi->polygons) {
    push(@{$world->centroids}, centroid($polygon));
  }
}

sub centroid {
  my ($cx, $cy) = (0, 0);
  my $A = 0;
  my $polygon = shift;
  my ($point_index, @points) = @$polygon; # see Math::Geometry::Voronoi
  my $point = $points[$#points];
  my ($x0, $y0) = ($point->[0], $point->[1]);
  for $point (@points) {
    my ($x1, $y1) = ($point->[0], $point->[1]);
    $cx += ($x0 + $x1) * ($x0 * $y1 - $x1 * $y0);
    $cy += ($y0 + $y1) * ($x0 * $y1 - $x1 * $y0);
    $A += ($x0 * $y1 - $x1 * $y0);
    ($x0, $y0) = ($x1, $y1);
  }
  $A /= 2;
  $cx /= 6 * $A;
  $cy /= 6 * $A;
  return [$cx, $cy, $point_index];
}

sub add_height {
  my $world = shift;
  $Math::Fractal::Noisemaker::QUIET = 1;
  my $grid = Math::Fractal::Noisemaker::square();
  $world->height([]); # clear
  my $scale = max($height, $width); # grid is a square
  foreach my $point (@{$world->points}) {
    my $x = int($point->[0]*255/$scale);
    my $y = int($point->[1]*255/$scale);
    my $h = 0; # we must not skip any points!
    $h = $grid->[$x]->get($y) / 255
      unless $x < 0 or $y < 0 or $x > 255 or $y > 255;
    push(@{$world->height}, $h);
  }
}

sub raise_point {
  my ($world, $x, $y, $radius) = @_;
  my $i = 0;
  foreach my $point (@{$world->points}) {
    my $dx = $point->[0] - $x;
    my $dy = $point->[1] - $y;
    my $d = sqrt($dx * $dx + $dy * $dy);
    my $v = max(0, $world->height->[$i] - $d / $radius);
    $world->height($i, $v);
    $i++;
  }
}

sub svg {
  my $world = shift;
  my $svg = new SVG(-width => $width,
		    -height => $height, );
  foreach my $polygon ($world->voronoi->polygons) {
    my ($point_index, @points) = @$polygon; # see Math::Geometry::Voronoi
    my $x = $world->points->[$point_index]->[0];
    my $y = $world->points->[$point_index]->[1];
    next if $x < 0 or $y < 0 or $x > $width or $y > $height;
    my $z = int($world->height->[$point_index] * 255);
    my $color = $z == 0 ? $color{ocean} : "rgb($z,$z,$z)";
    my $path = join(",", map { map { int } @$_ } @points);
    $svg->polygon(points => $path,
		  fill => $color,
		  style => { 'stroke-width' => 1,
			     'stroke' => 'black'});
  }
  return $svg->xmlify();
}

sub response {
  print header(-type=>'image/svg+xml');
  print shift;
}

sub main {
  if (path_info eq '/source') {
    seek DATA, 0, 0;
    print "Content-type: text/plain; charset=UTF-8\r\n\r\n", <DATA>;
  } else {
    srand(param('seed') || time);
    my $world = new World;
    add_random_points($world, $points);
    add_voronoi($world);
    for (my $i = 2; $i--; ) {
      # Lloyd Relaxation
      add_centroids($world);
      $world->points($world->centroids);
      add_voronoi($world);
    }
    # skip corner improvement
    # skip Delaunay triangulation
    add_height($world);
    raise_point($world, $center_x, $center_y, $radius);
    # draw
    response(svg($world));
  }
}

main ();

__DATA__

Add Comment

2010-05-10 Javascript

I still haven’t learnt Javascript. Right now I’m trying to integrate svg-edit and Oddmuse. This requires some Javascript voodoo that escapes me.

If you upload a SVG file to http://www.emacswiki.org/test/SVG_Test, you’ll be able to look at it. I’m using an iframe to do that.

If you then click on Edit this page and then on Edit image in the browser, you’ll get the SVG editor.

What I’m lacking is loading and saving the image!

If you look around the svg-edit project’s pages, you’ll note example code like the following:

    svgEditor.loadFromString('<svg>...</svg>');

What I don’t understand is where this code runs and how svgEditor is set.

If I simply add the following to the top of the page, inside the header, then Firebug will tell me that the svgEditor object does not exist.

    <script type="text/javascript">
      svgEditor.loadFromString('<svg>...</svg>');
    </script>

What now? Is this a variable “inside” the iframe? Is this something I need to initialize by calling a function? Which one?

Update: Perhaps I’m running into some cross-site scripting protection. The site runs on www.emacswiki.org, the SVG editor runs on svg-edit.googlecode.com. Using Firebug, I run document.getElementsByName('svgEditor')[0].getSVGDocument().setUserData('fd') and get an error message. warning

Tags: RSS RSS RSS

Comments on 2010-05-10 Javascript

This site is great!

– Kate 2010-05-13 10:38 UTC


It looks like you’re not including the javascript library that provides the SVG editing functions.

Harald 2010-05-13 12:32 UTC


Hah, I’m seeing the light. Copying the script over to localhost has fixed this. I’ve come a long way. Now I need MIME encoding in Javascript, and probably a cool Save dialog – or a little rewrite.

AlexSchroeder 2010-05-13 20:41 UTC


AlexSchroeder 2010-05-13 23:20 UTC

Add Comment

2009-09-19 SVG, CSS, and Inkscape

I have a problem with Inkscape and I think it’s related to the handling or loss of CSS information. I have a script that creates an SVG map which looks fine in Firefox – check it out and hit the submit button.

When I import that SVG into another SVG in order to add more layers, everything looks more or less ok. One thing that’s already wrong is that the hex coordinates are missing. When I save the file, close Inkscape, open Inkscape again, and reopen the new file, things are messed up:

  1. Coordinates are still missing
  2. Font sizes are wrong for the coordinates
  3. Symbols (text elements) around planets have some sort of white border

Do you think Inkscape will have an easier time handling the SVG if I don’t use CSS to specificy stroke width, opacity, and the like?

I’m using Inkscape 0.46 at the moment.

Tags:

Add Comment

2009-09-11 Traveller Map Based on UWP

There is an amazing Traveller Map API available out there. Specifically, there’s a service that will produce a PDF based on your UWP list. But you know how it is. I bet half the Traveller referees are trying to code up subsector generators and mappers. Me too!

Here’s my SVG Mapper for Traveller. It comes with example data so you can figure out what format it expects by looking at it. Just klick the Submit button! Remember, you need a browser that knows how to deal with SVG files – Firefox will do.

Source code is available. I got to reuse some of my abandoned Old School Hex Mapper. And figuring out the trigonometry stuff is fun. :) ok

Tags: RSS RSS RSS RSS RSS RSS

Comments on 2009-09-11 Traveller Map Based on UWP

Very nice! :-)

It looks very nice, and has a simple interface. This is a very good tool to quickly make a subsector.

You are very generous to release this with the GNU General Public License. This means that I might use it together with my random subsectror generator (that is also written in perl).

I have been thinking of doing my own mapper, (other than the ascii one I have made). My plan was to use GD or ImageMagick.

BeRKA 2009-09-11 05:51 UTC


Heh. I come from a FreeSoftware background. Sharing’s the ethical thing to do. ;)

Is your random subsector generator based on the Mongoose rules, or are they the same as for previous editions? I noticed that the generator I had used for my subsector produced strange trade codes and had to write a Perl script to fix them.

Also, Mongoose Traveller doesn’t say how UWP codes for the various based look like. They just provide Scout and Navy as examples. Do you know of a site that defines it?

AlexSchroeder 2009-09-11 07:21 UTC


My generator is based on previous editions? You can select to use book-3 or book-6 rules, that are slightly different when calculating hydrographics. My trade codes are from book-7.

Base codes can differ depending on the version you use. One common version is found on traveller map.

For Naval and Scout base “2” is also commonly used instead of “A”.

BeRKA 2009-09-11 08:25 UTC


Oh wow. Thanks for the link. This was new to me: “special codes deal with the presence of more than one type of base within the same system in order to maintain a single base code letter per system.”

I think I’m going to focus on the rules I have or I’ll go mad. :)

AlexSchroeder 2009-09-11 08:36 UTC


Excellent!

greywulf 2009-09-11 09:35 UTC

Add Comment

2008-09-12 Corporate Wikis

There was a lot of talk about corporate wikis, measuring corporate wiki participation, and some wikis “competing” for use in the corporate area.

Oddmuse is definitely not a “corporate wiki” in this respect. I think the problem is the process of decision making: Someone starts with a list of features and goes to collect more items for that list by talking to other “stakeholders” in the company. This is what you end up with:

Corporate wikis are a waste of time

Yeah, I’m being mean. :)

Damn, I forgot WYSIWYG, blog integration, CMS, mailing list integration, bug tracking system integration, calendar integration, … there’s so much out there!

Tags: RSS RSS RSS RSS RSS RSS RSS

Comments on 2008-09-12 Corporate Wikis

You’re clearly right. I experienced similar behaviour in the corporate world. They are coming with a monster (sometime needing a Java client or worst a Win32 fat client) to meet all the requirements from the “stakeholders”… and at the end, no one is using the system due its complexity. Contribution must be simple and easy. Why starting a Java/large application to update one single line in a documentation? That’s inefficient and frustrating (you contribute one time… and after you avoid to use the monster). It will take time before corporation fully understand that Internet-style and minimalist Wikis is the way to go.

A good Wiki is a Wiki where you forget about its user interface when you are using it.

Alexandre Dulaunoy 2008-09-13 09:28 UTC


All we need to figure out now is how to communicat our message to decision makers. :)

AlexSchroeder 2008-09-14 00:38 UTC


Maybe we could somehow adapt RITA for this purpose?

RadomirDopieralski 2008-09-21 22:30 UTC

Add Comment

Add Comment

Show Google +1

EditNearLinks: InkScape