پرونده:Sphere wireframe.svg

Page contents not supported in other languages.
از ویکی‌پدیا، دانشنامهٔ آزاد

پروندهٔ اصلی(پروندهٔ اس‌وی‌جی، با ابعاد ۴۰۰ × ۴۰۰ پیکسل، اندازهٔ پرونده: ۸ کیلوبایت)

خلاصه

توضیح
English: Sphere wireframe - orthogonal projection of a sphere. The image shows lines, which are drawn as they were painted onto the surface of a sphere. The angular distance between two lines is 10°. The SVG file is created by the below C++-program, which calculates each edge of a line as an ellipse-bow. The backside of the sphere has an opacity of 0.25. The axis tilt is 52.5°.
تاریخ
منبع اثر شخصی
پدیدآور Geek3
دیگر نسخه‌ها

Sphere filled_blue.svg

Sphere wireframe 10deg 10r.svg
 
W3C-validity not checked.

Source Code

This image can be completely generated by the following source code. If you have the gnu compiler collection installed, the programm can be compiled by the following commands:

g++ sphere_wireframe.cpp -o sphere_wireframe

and run :

./sphere_wireframe > Sphere_wireframe.svg

It creates file Sphere_wireframe.svg in working directory. This file can be viewed using rsvg-view program :

rsvg-view Sphere_wireframe.svg


Here is cpp code in file : sphere_wireframe.cpp

/* sphere - creates a svg vector-graphics file which depicts a wireframe sphere
 *
 * Copyright (C) 2008 Wikimedia foundation
 *
 * 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 2, 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, you can either send email to this
 * program's author (see below) or write to:
 *   The Free Software Foundation, Inc.
 *   51 Franklin Street, Fifth Floor
 *   Boston, MA 02110-1301  USA
 */

/* The expressions in this code are not proven to be correct.
 * Hence this code probably contains lots of bugs. Be aware! */

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstring>

using namespace std;

const double PI = 3.1415926535897932;
const double DEG = PI / 180.0;

/********************************* settings **********************************/
int n_lon = 18; 			// number of latitude fields (18 => 10° each)
int n_lat = 18; 			// half number of longitude fields (18 => 10° each)
double lon_offset = 2.5 * DEG; 	// offset of the meridians
double w = 52.5 * DEG; 		// axial tilt (0° => axis is perpendicular to image plane)
double stripe_grad = 0.5 * DEG;	// width of each line
int image_size = 400;			// width and height of the image in pixels
double back_opacity = 0.25;		// opacity of the sphere's backside
char color[] = "#334070";		// color of lines
int istep = 2; 			// svg code indentation step
/*****************************************************************************/

double sqr(double x)
{
	return(x * x);
}

// commands for svg-code:
void indent(int n, bool in_tag = false)
{
	n *= istep;
	if (in_tag) n += istep + 1;
	for (int i = 0; i < n; i++) cout << " ";
}
void M()
{
	cout << "M ";
}
void Z()
{
	cout << "Z ";
}
void xy(double x, double y)
{
	cout << x << ",";
	cout << y << " ";
}
void arc(double a, double b, double x_axis_rot, bool large_arc, bool sweep)
{	// draws an elliptic arc
	if (b < 0.5E-6)
	{	// flat ellipses are not rendered properly => use line
		cout << "L ";
	}
	else
	{
		cout << "A ";
		cout << a << ",";	// semi-major axis
		cout << b << " ";	// semi-minor axis
		cout << x_axis_rot << " ";
		cout << large_arc << " ";
		cout << sweep << " ";
	}
}
void circle(bool clockwise)
{
	M();
	xy(-1, 0);
	arc(1, 1, 0, 0, !clockwise);
	xy(1, 0);
	arc(1, 1, 0, 0, !clockwise);
	xy(-1, 0);
	Z();
}

void start_svg_file()
{
	cout << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
	cout << "<svg id=\"Sphere_wireframe\"\n";
	cout << "  version=\"1.1\"\n";
	cout << "  baseProfile=\"full\"\n";
	cout << "  xmlns=\"http://www.w3.org/2000/svg\"\n";
	cout << "  xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n";
	cout << "  width=\"" << image_size << "\"\n";
	cout << "  height=\"" << image_size << "\">\n\n";
	cout << "  <title>Sphere wireframe</title>\n\n";
	cout << "  <desc>\n";
	cout << "     about: http://commons.wikimedia.org/wiki/Image:Sphere_wireframe.svg\n";
	cout << "     rights: GNU Free Documentation license,\n";
	cout << "             Creative Commons Attribution ShareAlike license\n";
	cout << "  </desc>\n\n";
	cout << "  <g id=\"sphere\" transform=\"scale(" << 0.5 * image_size;
	cout << ", " << -0.5 * image_size << ") translate(1, -1)\">\n";
}

void end_svg_file()
{
	cout << "  </g>\n</svg>\n";
}



int main (int argc, char *argv[])
{
	// accept -lat and -lon as parameter
	for (int i = 2; i < argc; i++)
	{
		if (isdigit(argv[i][0]) || (sizeof(argv[i]) > sizeof(char)
			&& isdigit(argv[i][1])
			&& (argv[i][0] == '.' || argv[i][0] == '-')))
		{
			if (strcmp(argv[i - 1], "-lon") == 0)
			{
				lon_offset = atof(argv[i]) * DEG;
			}
			if (strcmp(argv[i - 1], "-lat") == 0)
			{
				w = atof(argv[i]) * DEG;
			}
		}
	}
	double cosw = cos(w), sinw = sin(w);
	double d = 0.5 * stripe_grad;

	start_svg_file();
	int ind = 2; // initial indentation level
	indent(ind);
	cout << "<g id=\"sphere_back\" transform=\"rotate(180)\" ";
	cout << "opacity=\"" << back_opacity << "\">\n";
	indent(++ind);
	cout << "<g id=\"sphere_half\">\n";

	// meridians
	indent(++ind); cout << "<g id=\"meridians\"\n";
	indent(ind++, true);
	cout << "style=\"stroke:none; fill:" << color << "; fill_rule:evenodd\">\n";
	double a = abs(cos(d));
	for (int i_lon = 0; i_lon < n_lat; i_lon++)
	{	// draw one meridian
		double longitude = lon_offset + (i_lon * 180.0 / n_lat) * DEG;
		double lon[2];
		lon[0] = longitude + d;
		lon[1] = longitude - d;
		
		indent(ind);
		cout << "<path id=\"meridian";
		cout << i_lon << "\"\n";
		indent(ind, true);
		cout << "d=\"";

		double axis_rot = atan2(-1.0 / tan(longitude), cosw);
		if (sinw < 0)
			axis_rot += PI;
		double w2 = sin(longitude) * sinw;
		double b = abs(w2 * cos(d));

		double sinw1 = sin(d) / sqrt(1.0 - sqr(sin(longitude) * sinw));

		if (abs(sinw1) >= 1.0)
		{	// stripe covers edge of the circle
			double w3 = sqrt(1.0 - sqr(w2)) * sin(d);
			circle(false);
			// ellipse
			M();
			xy(sin(axis_rot) * w3 - cos(axis_rot) * a,
				-cos(axis_rot) * w3 - sin(axis_rot) * a);
			arc(a, b, axis_rot / DEG, 0, 0);
			xy(sin(axis_rot) * w3 + cos(axis_rot) * a,
				-cos(axis_rot) * w3 + sin(axis_rot) * a);
			arc(a, b, axis_rot / DEG, 0, 0);
			xy(sin(axis_rot) * w3 - cos(axis_rot) * a,
				-cos(axis_rot) * w3 - sin(axis_rot) * a);
			Z();
		}
		else
		{	// draw a disrupted ellipse bow
			double w1 = asin(sinw1);
			M();
			xy(-cos(axis_rot + w1), -sin(axis_rot + w1));
			arc(a, b, axis_rot / DEG, 1, 0);
			xy(cos(axis_rot - w1), sin(axis_rot - w1));
			arc(1, 1, 0, 0, 1);
			xy(cos(axis_rot + w1), sin(axis_rot + w1));
			arc(a, b, axis_rot / DEG, 0, 1);
			xy(-cos(axis_rot - w1), -sin(axis_rot - w1));
			arc(1, 1, 0, 0, 1);
			xy(-cos(axis_rot + w1), -sin(axis_rot + w1));
		}
		Z();
		cout << "\" />\n";
	}
	indent(--ind); cout << "</g>\n";

	cout << endl;

	// circles of latitude
	indent(ind); cout << "<g id=\"circles_of_latitude\"\n";
	indent(ind, true);
	cout << "style=\"stroke:none; fill:" << color << "; fill_rule:evenodd\">\n";
	ind++;
	for (int i_lat = 1; i_lat < n_lon; i_lat++)
	{	// draw one circle of latitude
		double latitude = (i_lat * 180.0 / n_lon - 90.0) * DEG;
		double lat[2];
		lat[0] = latitude + d;
		lat[1] = latitude - d;
		double x[2], yd[2], ym[2];
		for (int i = 0; i < 2; i++)
		{
			x[i] = abs(cos(lat[i]));
			yd[i] = abs(cosw * cos(lat[i]));
			ym[i] = sinw * sin(lat[i]);
		}
		double h[4];	// height of each point above image plane
		h[0] = sin(lat[0] + w);
		h[1] = sin(lat[0] - w);
		h[2] = sin(lat[1] + w);
		h[3] = sin(lat[1] - w);
		
		if (h[0] > 0 || h[1] > 0 || h[2] > 0 || h[3] > 0)
		{	// at least any part visible
			indent(ind);
			cout << "<path id=\"circle_of_latitude";
			cout << i_lat << "\"\n";
			indent(ind, true);
			cout << "d=\"";
			for (int i = 0; i < 2; i++)
			{
				if ((h[2*i] >= 0 && h[2*i+1] >= 0)
					&& (h[2*i] > 0 || h[2*i+1] > 0))
				{	// complete ellipse
					M();
					xy(-x[i], ym[i]); // startpoint
					for (int z = 1; z > -2; z -= 2)
					{
						arc(x[i], yd[i], 0, 1, i);
						xy(z * x[i], ym[i]);
					}
					Z();
					if (h[2-2*i] * h[3-2*i] < 0)
					{	// partly ellipse + partly circle
						double yp = sin(lat[1-i]) / sinw;
						double xp = sqrt(1.0 - sqr(yp));
						if (sinw < 0)
						{
							xp = -xp;
						}
						M();
						xy(-xp, yp);
						arc(x[1-i], yd[1-i], 0,
							sin(lat[1-i]) * cosw > 0, cosw >= 0);
						xy(xp, yp);
						arc(1, 1, 0, 0, cosw >= 0);
						xy(-xp, yp);
						Z();
					}
					else if (h[2-2*i] <= 0 && h[3-2*i] <= 0)
					{	// stripe covers edge of the circle
						circle(cosw < 0);
					}
				}
			}
			
			if ((h[0] * h[1] < 0 && h[2] <= 0 && h[3] <= 0)
				|| (h[0] <= 0 && h[1] <= 0 && h[2] * h[3] < 0))
			{
				// one slice visible
				int i = h[0] <= 0 && h[1] <= 0;
				double yp = sin(lat[i]) / sinw;
				double xp = sqrt(1.0 - yp * yp);
				M();
				xy(-xp, yp);
				arc(x[i], yd[i], 0, sin(lat[i]) * cosw > 0, cosw * sinw >= 0);
				xy(xp, yp);
				arc(1, 1, 0, 0, cosw * sinw < 0);
				xy(-xp, yp);
				Z();
			}
			else if (h[0] * h[1] < 0 && h[2] * h[3] < 0)
			{
				// disrupted ellipse bow
				double xp[2], yp[2];
				for (int i = 0; i < 2; i++)
				{
					yp[i] = sin(lat[i]) / sinw;
					xp[i] = sqrt(1.0 - sqr(yp[i]));
					if (sinw < 0) xp[i] = -xp[i];
				}
				M();
				xy(-xp[0], yp[0]);
				arc(x[0], yd[0], 0, sin(lat[0]) * cosw > 0, cosw >= 0);
				xy(xp[0], yp[0]);
				arc(1, 1, 0, 0, 0);
				xy(xp[1], yp[1]);
				arc(x[1], yd[1], 0, sin(lat[1]) * cosw > 0, cosw < 0);
				xy(-xp[1], yp[1]);
				arc(1, 1, 0, 0, 0);
				xy(-xp[0], yp[0]);
				Z();
			}
			cout << "\" />\n";
		}
	}
	for (int i = 0; i < 3; i++)
	{
		indent(--ind);
		cout << "</g>\n";
	}
	indent(ind--);
	cout << "<use id=\"sphere_front\" xlink:href=\"#sphere_half\" />\n";
	end_svg_file();
}

اجازه‌نامه

من، صاحب حقوق قانونی این اثر، به این وسیله این اثر را تحث اجازه‌نامه‌های ذیل منتشر می‌کنم:
GNU head اجازهٔ کپی، پخش و/یا تغییر این سند تحت شرایط مجوز مستندات آزاد گنو، نسخهٔ ۱٫۲ یا هر نسخهٔ بعدتری که توسط بنیاد نرم‌افزار آزاد منتشر شده؛ بدون بخش‌های ناوردا (نامتغیر)، متون روی جلد، و متون پشت جلد، اعطا می‌شود. یک کپی از مجوز در بخشی تحت عنوان مجوز مستندات آزاد گنو ضمیمه شده است.
w:fa:کرییتیو کامنز
انتساب انتشار مشابه
این پرونده با اجازه‌نامهٔ کریتیو کامانز Attribution-Share Alike 3.0 سازگار نشده، 2.5 عمومی، 2.0 عمومی و 1.0 عمومی منتشر شده است.
شما اجازه دارید:
  • برای به اشتراک گذاشتن – برای کپی، توزیع و انتقال اثر
  • تلفیق کردن – برای انطباق اثر
تحت شرایط زیر:
  • انتساب – شما باید اعتبار مربوطه را به دست آورید، پیوندی به مجوز ارائه دهید و نشان دهید که آیا تغییرات ایجاد شده‌اند یا خیر. شما ممکن است این کار را به هر روش منطقی انجام دهید، اما نه به هر شیوه‌ای که پیشنهاد می‌کند که مجوزدهنده از شما یا استفاده‌تان حمایت کند.
  • انتشار مشابه – اگر این اثر را تلفیق یا تبدیل می‌کنید، یا بر پایه‌ آن اثری دیگر خلق می‌کنید، می‌‌بایست مشارکت‌های خود را تحت مجوز یکسان یا مشابه با ا اصل آن توزیع کنید.
می‌توانید مجوز دلخواه خود را برگزینید.

عنوان

شرحی یک‌خطی از محتوای این فایل اضافه کنید

آیتم‌هایی که در این پرونده نمایش داده شده‌اند

توصیف‌ها

این خصوصیت مقداری دارد اما نامشخص است.

source of file انگلیسی

تاریخچهٔ پرونده

روی تاریخ/زمان‌ها کلیک کنید تا نسخهٔ مربوط به آن هنگام را ببینید.

تاریخ/زمانبندانگشتیابعادکاربرتوضیح
کنونی‏۲۳ نوامبر ۲۰۰۸، ساعت ۱۶:۱۰تصویر بندانگشتی از نسخهٔ مورخ ‏۲۳ نوامبر ۲۰۰۸، ساعت ۱۶:۱۰۴۰۰ در ۴۰۰ (۸ کیلوبایت)Geek3{{Information |Description={{en|1=Sphere wireframe - the image shows lines, which are drawn as they were painted onto the surface of a sphere. The distance between two lines is 10°. The svg file is created by the below c++-program, which calculates each

صفحهٔ زیر از این تصویر استفاده می‌کند:

کاربرد سراسری پرونده

ویکی‌های دیگر زیر از این پرونده استفاده می‌کنند:

نمایش استفاده‌های سراسری از این پرونده.

فراداده