Original file (SVG file, nominally 495 × 526 pixels, file size: 7 KB)

Summary

Description
English: Version of CIE1931xy blank.svg with sRGB primaries and white point. Similar to CIExy1931 sRGB.svg, but see the description of CIE1931xy blank.svg for differences. I used open circles instead of bullseyes to show the colors, but maybe the bullseyes looked better.
Source Own work based on: CIExy1931.png by PAR
Author BenRG
SVG development
InfoField
 The SVG code is valid.
 This diagram was created with an unknown SVG tool.
  This diagram uses embedded text that can be easily translated using a text editor.

Licensing

Public domain This work has been released into the public domain by its author, BenRG. This applies worldwide.
In some countries this may not be legally possible; if so:
BenRG grants anyone the right to use this work for any purpose, without any conditions, unless such conditions are required by law.

Perl code

use strict;
use Svg;
use List::Util qw(min);

my @primaries;
my $whitepoint = '';
my $filename;

if (1) {
	$filename = 'CIE1931xy_blank.svg';
} elsif (0) {
	$filename = 'CIE1931xy_sRGB.svg';
	@primaries = ([0.64,0.33],[0.30,0.60],[0.15,0.06]);
	$whitepoint = [0.3127,0.3290,'D65'];
} elsif (0) {
	$filename = 'CIE1931xy_AdobeRGB.svg';
	@primaries = ([0.64,0.33],[0.21,0.71],[0.15,0.06]);
	$whitepoint = [0.3127,0.3290,'D65'];
} elsif (0) {
	@primaries = ([0.7347,0.2653],[0.2738,0.7174],[0.1666,0.0089]);
	$whitepoint = [1/3, 1/3, 'E'];
	$filename = 'CIE1931xy_CIERGB.svg';
}

# in 5 nm steps from 360 to 830 nm, from http://www-cvrl.ucsd.edu/database/data/cmfs/ciexyz31.txt
my @xcmf = (
	0.0001299,0.0002321,0.0004149,0.0007416,0.001368,
	0.002236,0.004243,0.00765,0.01431,0.02319,
	0.04351,0.07763,0.13438,0.21477,0.2839,
	0.3285,0.34828,0.34806,0.3362,0.3187,
	0.2908,0.2511,0.19536,0.1421,0.09564,
	0.05795001,0.03201,0.0147,0.0049,0.0024,
	0.0093,0.0291,0.06327,0.1096,0.1655,
	0.2257499,0.2904,0.3597,0.4334499,0.5120501,
	0.5945,0.6784,0.7621,0.8425,0.9163,
	0.9786,1.0263,1.0567,1.0622,1.0456,
	1.0026,0.9384,0.8544499,0.7514,0.6424,
	0.5419,0.4479,0.3608,0.2835,0.2187,
	0.1649,0.1212,0.0874,0.0636,0.04677,
	0.0329,0.0227,0.01584,0.01135916,0.008110916,
	0.005790346,0.004109457,0.002899327,0.00204919,0.001439971,
	0.0009999493,0.0006900786,0.0004760213,0.0003323011,0.0002348261,
	0.0001661505,0.000117413,0.00008307527,0.00005870652,0.00004150994,
	0.00002935326,0.00002067383,0.00001455977,0.00001025398,0.000007221456,
	0.000005085868,0.000003581652,0.000002522525,0.000001776509,0.000001251141);
my @ycmf = (
	0.000003917,0.000006965,0.00001239,0.00002202,0.000039,
	0.000064,0.00012,0.000217,0.000396,0.00064,
	0.00121,0.00218,0.004,0.0073,0.0116,
	0.01684,0.023,0.0298,0.038,0.048,
	0.06,0.0739,0.09098,0.1126,0.13902,
	0.1693,0.20802,0.2586,0.323,0.4073,
	0.503,0.6082,0.71,0.7932,0.862,
	0.9148501,0.954,0.9803,0.9949501,1,
	0.995,0.9786,0.952,0.9154,0.87,
	0.8163,0.757,0.6949,0.631,0.5668,
	0.503,0.4412,0.381,0.321,0.265,
	0.217,0.175,0.1382,0.107,0.0816,
	0.061,0.04458,0.032,0.0232,0.017,
	0.01192,0.00821,0.005723,0.004102,0.002929,
	0.002091,0.001484,0.001047,0.00074,0.00052,
	0.0003611,0.0002492,0.0001719,0.00012,0.0000848,
	0.00006,0.0000424,0.00003,0.0000212,0.00001499,
	0.0000106,0.0000074657,0.0000052578,0.0000037029,0.0000026078,
	0.0000018366,0.0000012934,0.00000091093,0.00000064153,0.00000045181);
my @zcmf = (
	0.0006061,0.001086,0.001946,0.003486,0.006450001,
	0.01054999,0.02005001,0.03621,0.06785001,0.1102,
	0.2074,0.3713,0.6456,1.0390501,1.3856,
	1.62296,1.74706,1.7826,1.77211,1.7441,
	1.6692,1.5281,1.28764,1.0419,0.8129501,
	0.6162,0.46518,0.3533,0.272,0.2123,
	0.1582,0.1117,0.07824999,0.05725001,0.04216,
	0.02984,0.0203,0.0134,0.008749999,0.005749999,
	0.0039,0.002749999,0.0021,0.0018,0.001650001,
	0.0014,0.0011,0.001,0.0008,0.0006,
	0.00034,0.00024,0.00019,0.0001,0.00004999999,
	0.00003,0.00002,0.00001,0,0,
	0,0,0,0,0,
	0,0,0,0,0,
	0,0,0,0,0,
	0,0,0,0,0,
	0,0,0,0,0,
	0,0,0,0,0,
	0,0,0,0,0);

my @x = map { $xcmf[$_]/($xcmf[$_]+$ycmf[$_]+$zcmf[$_]) } 0..$#xcmf;
my @y = map { $ycmf[$_]/($xcmf[$_]+$ycmf[$_]+$zcmf[$_]) } 0..$#xcmf;

sub Normalize {
	my @a = @_;
	my $n = 0;
	for my $i (@a) { $n += $i*$i }
	$n = 1/sqrt($n); 
	for my $i (@a) { $i *= $n }
	@a
}
sub Tick {
	my $i = ($_[0] - 360) / 5;
	my ($px,$py) = Normalize($x[$i]-$x[$i-1], $y[$i]-$y[$i-1]);
	my ($qx,$qy) = Normalize($x[$i+1]-$x[$i], $y[$i+1]-$y[$i]);
	my ($tx,$ty) = Normalize($px+$qx, $py+$qy);
	return (X($x[$i]), Y($y[$i]), $ty * -$_[1], $tx * -$_[1]);
}

our $scale = 512;
our ($padleft,$padtop,$padright,$padbot) = (60,15,25,50);
our ($maxx, $maxy) = (0.8,0.9);
our ($origin_x, $origin_y) = ($padleft, $padtop + $maxy * $scale);
our ($imgwidth, $imgheight) = ($origin_x + $maxx * $scale + $padright, $origin_y + $padbot);

sub X { $origin_x + $scale * $_[0] }
sub Y { $origin_y - $scale * $_[0] }

my $svg = new Svg(width => $imgwidth, height => $imgheight);
#$svg->rect(width => $imgwidth, height => $imgheight, fill => 'gray');

# semitransparent grid
my $grid = new Svg::PathString;
for my $xx (1..$maxx*20) {
	my $x = $xx * 0.05;
	my $y = min($maxy, 1-$x);
	$grid->M(halfpixel(X($x)), halfpixel(Y(0)))->l(0, -$scale*$y);
}
for my $yy (1..$maxy*20) {
	my $y = $yy * 0.05;
	my $x = min($maxx, 1-$y);
	$grid->M(halfpixel(X(0)), halfpixel(Y($y)))->l($scale*$x, 0);
}
$grid->M(halfpixel(X(1-$maxy)), halfpixel(Y($maxy)))->L(halfpixel(X($maxx)), halfpixel(Y(1-$maxx)));
$svg->path(opacity => 1/8, stroke => 'black', 'stroke-width' => 1, fill => 'none', d => $grid->get());

$svg->defs->path(id => 'border', d => MakePath(\@x, \@y, $scale, -$scale, $origin_x, $origin_y, 1));
$svg->clipPath(id => 'clipborder')->use('border');

# black stroke on the monochromatic locus (the inner half of the stroke gets overwritten by the image)
$svg->use('border', stroke => 'black', 'stroke-width' => 4, fill => 'none');

# frequency tick marks on the monochromatic locus
my $ticks = '';
for (my $i = 410; $i <= 695; $i += 5) {
	my ($x,$y,$tx,$ty) = Tick($i, $i % 20 ? 6 : 10);
	$ticks .= 'M' . tenth($x) . ',' . tenth($y) . 'l' . tenth($tx) . ',' . tenth($ty);
}
$svg->path(d => $ticks, stroke => 'black', 'stroke-width' => 1);

# color PNG
my $pnggroup = $svg->group('clip-path' => 'url(#clipborder)');
$pnggroup->filter(id => 'blur')->feGaussianBlur(stdDeviation => 0.5);
$pnggroup->image('chromaticity1.png', width => 27, height => 28, filter => 'url(#blur)')->scale(1/32 * $scale)->translate($origin_x - 3/64 * $scale, $origin_y - 27.5/32 * $scale);

# coordinate axes
my $axes = new Svg::PathString;
$axes->M(round(X(0)), round(Y($maxy)))->l(0,round($scale*$maxy))->l(round($scale*$maxx),0);
for my $xx (0..$maxx*20) {
	$axes->M(round(X($xx*0.05)), round(Y(0)))->l(0,4);
}
for my $yy (0..$maxy*20) {
	$axes->M(round(X(0)), round(Y($yy*0.05)))->l(-4,0);
}
$svg->path(stroke => 'black', 'stroke-width' => 2, 'stroke-linecap' => 'square', fill => 'none', d => $axes->get());

my $alltext = $svg->group('font-family' => 'Nimbus Roman No9 L, Times, serif', 'font-size' => 19, stroke => 'none');
my $halfdigit = 6; # half the height of a digit, since Opera doesn't support dominant-baseline

# labels for frequency tick marks
my $freqs = $alltext->group(fill => 'blue');
for (my $i = 460; $i <= 620; $i += 20) {
	my ($x,$y,$tx,$ty) = Tick($i,12);
	my $xanchor = $ty < -2*abs($tx) ? 'middle' : $tx > 0 ? 'start' : 'end';
	my $yshift = $tx < -2*abs($ty) || $ty > 0 ? $halfdigit : 0;
	$freqs->text(x => tenth($x+$tx), y => tenth($y+$ty+$yshift), 'text-anchor' => $xanchor)->add($i);
}

# x,y axis labels
my $coords = $alltext->group(fill => 'black');
my $xcoords = $coords->group('text-anchor' => 'middle');
$xcoords->text(x => X($maxx/2), y => $origin_y + 40, 'font-style' => 'italic')->add('x');
for my $x (0..$maxx*10) {
	$xcoords->text(x => X($x * 0.1), y => $origin_y + 20)->add("0.$x");
}
my $ycoords = $coords->group('text-anchor' => 'end');
$ycoords->text(x => $origin_x - 40, y => Y($maxy/2)+$halfdigit, 'font-style' => 'italic')->add('y');
for my $y (0..$maxy*10) {
	$ycoords->text(x => $origin_x - 8, y => Y($y * 0.1)+$halfdigit)->add("0.$y");
}

# gamut polygon and whitepoint
if (@primaries || $whitepoint) {
	my $primary_polygon = $svg->group(stroke => 'black', 'stroke-width' => 2, fill => 'none');
	my $primary_polygon_circle_radius = 5;
	for my $p (0..$#primaries) {
		my ($a,$b) = @primaries[$p, $p == $#primaries ? 0 : $p+1];
		$primary_polygon->circle(cx => X($$a[0]), cy => Y($$a[1]), r => $primary_polygon_circle_radius);
		my ($dx,$dy) = ($scale * ($$a[0]-$$b[0]), -$scale * ($$a[1]-$$b[1]));
		my $nudge = $primary_polygon_circle_radius / sqrt($dx*$dx + $dy*$dy);
		my ($nudgex,$nudgey) = ($nudge * $dx, $nudge * $dy);
		$primary_polygon->line(x1 => round(X($$a[0])-$nudgex), y1 => round(Y($$a[1])-$nudgey), x2 => round(X($$b[0])+$nudgex), y2 => round(Y($$b[1])+$nudgey));
	}
	if ($whitepoint) {
		$primary_polygon->circle(cx => X($$whitepoint[0]), cy => Y($$whitepoint[1]), r => $primary_polygon_circle_radius);
		if (defined $$whitepoint[2]) {
			$alltext->text(x => X($$whitepoint[0]) + 8, y => Y($$whitepoint[1]) + 16, fill => 'black')->add($$whitepoint[2]);
		}
	}
}

$svg->write($filename);

Captions

Add a one-line explanation of what this file represents

Items portrayed in this file

depicts

image/svg+xml

d1b7a226bd069b2adf87e322e150d382b7a6e043

6,758 byte

526 pixel

495 pixel

File history

Click on a date/time to view the file as it appeared at that time.

Date/TimeThumbnailDimensionsUserComment
current01:09, 25 September 2009Thumbnail for version as of 01:09, 25 September 2009495 × 526 (7 KB)BenRG{{Information |Description=Version of File:CIE1931xy_blank.svg with sRGB primaries and white point. Similar to File:CIExy1931_sRGB.svg, but see the description of File:CIE1931xy_blank.svg for differences. I used open circles instead of bull
No pages on the English Wikipedia use this file (pages on other projects are not listed).

Global file usage

The following other wikis use this file: