🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: net.micro.atari16
Article #1983

A simple VDI interface for XY plotting

#1983
From: braner
Date: Thu, 25 Sep 1986 03:11
210 lines
5011 bytes
[]

For a long time I wanted to create a very simple, easy-to-use system
for plotting functions, data, etc from a C program.  I am thinking of
scientific/engineering applications, where quick, one-shot plots are
wanted, not fancy, perfect, art pieces.

Well, I did it after all - it wasn't as hard as I thought, since I have
already done it before in Applesoft BASIC.  Happy plotting!

- Moshe Braner

---------- cut here ----------------

/*
 * Simple VDI Interface for X-Y Plotting
 *
 *      by Moshe Braner,   860924
 *
 * #include "plotxyz.c" (this file) in your program.
 *
 */

/* globally define arrays to be used by VDI: */

int contrl[12], intin[128], ptsin[128], intout[128], ptsout[128];

/* our own globals */

static	int	work_in[11], work_out[57];	
static	int	xlog, ylog, curx, cury, curvalid;
static	int	plothand=0;
static	double	p, q, r, s;

/*
 * Subroutine to set up graphics
 *
 * Parameters:
 *
 *    xmin = lowest X-value
 *    xmax = highest X-value
 *    xtik = tick interval for X (ratio if log)
 *    ymin = lowest Y-value
 *    ymax = highest Y-value
 *    ytik = tick interval for Y (ratio if log)
 *    xorg, yorg = position of origion
 *    xmode, ymode = 0 for linear, 1 for log-scale
 */
initplot(xmin,xmax,xtik,ymin,ymax,ytik,xorg,yorg,xmode,ymode)
	double	xmin,xmax,xtik,ymin,ymax,ytik,xorg,yorg;
	int	xmode, ymode;
{
	int	i, pxy[4];
	double	w;

	puts("\033E");			/* clear screen			*/
	puts("\033f");			/* cursor invisible		*/

	/* initialize VDI */

	for(i=0; i<10; i++)		/* init workstation params	*/
		work_in[i]=1;
	work_in[10]= 2;			/* use raster coords		*/
	v_opnvwk( work_in, &plothand, work_out );
	vsf_color(plothand, 1);		/* black			*/
	vswr_mode(plothand, 1);		/* "Replace" mode		*/

	/* initialize our params */

	xlog = xmode;
	ylog = ymode;
	if (xlog) {
		xmin = log(xmin);
		xmax = log(xmax);
		xtik = log(xtik);
		xorg = log(xorg);
	}
	if (ylog) {
		ymin = log(ymin);
		ymax = log(ymax);
		ytik = log(ytik);
		yorg = log(yorg);
	}

	r = 599.0/(xmax-xmin);
	s = 399.0/(ymax-ymin);
	p = xmin;
	q = ymin;

	/* draw X-axis */

	pxy[0] = (int)(r * (xmin-p)) + 40;
	pxy[1] = (int)(s * (q-yorg)) + 399;
	pxy[2] = (int)(r * (xmax-p)) + 40;
	pxy[3] = pxy[1];
	v_pline(plothand, 2, pxy);
	w = xorg;
	while (w >= xmin)  w -= xtik;
	pxy[1] = (int)(s * (q-yorg)) + 395;
	pxy[3] = pxy[1] + 3;
	while ((w+=xtik) <= xmax) {
		pxy[0] = (int)(r * (w-p)) + 40;
		pxy[2] = pxy[0];
		v_pline(plothand, 2, pxy);
	}

	/* draw y-axis */

	pxy[0] = (int)(r * (xorg-p)) + 40;
	pxy[1] = (int)(s * (q-ymin)) + 399;
	pxy[2] = pxy[0];
	pxy[3] = (int)(s * (q-ymax)) + 399;
	v_pline(plothand, 2, pxy);
	w = yorg;
	while (w >= ymin)  w -= ytik;
	pxy[0] = (int)(r * (xorg-p)) + 41;
	pxy[2] = pxy[0] + 3;
	while ((w+=ytik) <= ymax) {
		pxy[1] = (int)(s * (q-w)) + 399;
		pxy[3] = pxy[1];
		v_pline(plothand, 2, pxy);
	}

	curvalid = 0;
}

/*
 * Subroutine to plot a point
 *
 *   (First call initplot() for setup.)
 *
 * Plots with the pen up if z==0, else pen down.
 * Uses the preset p, q, r, s, xlog, ylog for rescaling.
 * Uses the remembered curx, cury if pen down.
 */
plot(x, y, z)
	double	x, y;
	int	z;
{
	int	xi, yi, pxy[4];

	if (plothand == 0) {
		puts("Must call initplot() before plot()!");
		exit(0);
	}
	if (xlog)  x = log(x);
	if (ylog)  y = log(y);
	xi = (int)(r * (x-p)) + 40;
	yi = (int)(s * (q-y)) + 399;
	if (xi<0 || xi>639) {
		/* puts("plot(): x out of range!"); */
		return;
	}
	if (yi<0 || yi>399) {
		/* puts("plot(): y out of range!"); */
		return;
	}
	if (z && curvalid) {
		pxy[0] = curx;
		pxy[1] = cury;
	} else {
		pxy[0] = xi;
		pxy[1] = yi;
	}
	curx = xi;
	cury = yi;
	curvalid = 1;
	pxy[2] = xi;
	pxy[3] = yi;
	v_pline(plothand, 2, pxy);	
}

/*
 * clean up when you're done, or else you'll get cherry bombs!
 */
cleanplot()
{
	v_clsvwk(plothand);
	plothand = 0;
}

------------- example program ------------------

#include <stdio.h>
#include <math.h>
#include "plotxyz.c"

main()
{
	double	x,y,xmin,xmax,xtik,ymin,ymax,ytik,xorg,yorg;

	xmin = -2.0;
	xmax = 6.0;
	ymin = -1.3;
	ymax = 1.3;
	xtik = 1.0;
	ytik = 0.25;
	xorg = 0.0;
	yorg = 0.0;

	initplot(xmin,xmax,xtik,ymin,ymax,ytik,xorg,yorg,0,0);

	for (x=xmin; x<xmax; x+=0.05) {
		y = sin(x);
		plot(x,y,1);
	}

	cleanplot();
	getchar();
}
Technical Details
Message-ID: <1098@batcomputer.TN.CORNELL.EDU>
Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!rochester!cornell!batcomputer!braner

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!rochester!cornell!batcomputer!braner
From: braner@batcomputer.TN.CORNELL.EDU (braner)
Newsgroups: net.micro.atari16
Subject: A simple VDI interface for XY plotting
Message-ID: <1098@batcomputer.TN.CORNELL.EDU>
Date: Wed, 24-Sep-86 23:11:34 EDT
Article-I.D.: batcompu.1098
Posted: Wed Sep 24 23:11:34 1986
Date-Received: Fri, 26-Sep-86 20:33:47 EDT
Reply-To: braner@batcomputer.UUCP (braner)
Organization: Theory Center, Cornell University, Ithaca NY
Lines: 210