Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

Подписываем
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Предоплата всего
Подписываем
Построение графиков. Преобразование координат от логических к экранным.
При построении графиков будем использовать линейное преобразование логических координат к экранным (физическим координатам). Логические координаты имеют вещественный тип данных. Действительно, аргумент вещественной функции также вещественное число и может изменяться, например от -1,5 до 1,5 с шагом 0,01. Физические координаты - экранные или координаты графического массива изображения - координаты для растровой графики, имеют целый тип. Физические координаты по горизонтальной оси могут изменяться, например, от 0 до 600, а вертикальной оси - от 800 (в нижней точке) до 0 (в верхней точке). Таким образом, вертикальная ось в физических координатах направлена сверху вниз, значения координат целые и неотрицательные.
Построим функции преобразования от логических координат к физическим. Линейное преобразование в общем виде имеет вид: y = a*x+b. В нашем случае будет два таких преобразования одно для X, другое для Y:
xF = a1*xL+b1
yF = a2*yL+b2
Коэффициенты a1, b1, a2, b2 зависят от размеров логической и физической прямоугольных областей.
Координаты левой нижней и правой верхней точек логической и физической областей являются общими (глобальными, публичными) для всей программы. Такие глобальные переменные в консольных приложениях, как правило, задают как свойства базового класса. Для консольных приложений такие переменные обязательно должны быть статическими (static), так как в консольных приложениях метод main является статическим и глобальными (public) для того, чтобы они были видны во всех методах (функциях) базового класса (кстати, public писать не обязательно, по умолчанию статические свойства являются публичными).
static public double xL1, xL2, yL1, yL2;
static public int xF1, xF2, yF1, yF2;
Теперь в теле метода main (и в других методах нашего класса) эти переменные будут видны и к ним можно обращаться как к свойствам класса Program Program.xL1 и т.п.
Например, им можно задать такие значения
Program.xL1 = -5.0;
Program.yL1 = -10.0;
Program.xL2 = 5.0;
Program.yL2 = 10.0;
Логическая область имеет размеры от -5 до 5 по горизоньальной оси и от -10 до 10 по вертикальной.
Program.xF1 = 0;
Program.xF2 = 600;
Program.yF1 = 800;
Program.yF2 = 0;
Физическая область имеет размеры от 0 до 600 по горизонтали и от 800 до 0 по вертикали.
Для преобразования от логических координат x к физическим координатам xF создадим функцию статический целочисленный метод xF, который принимает вещественный параметр логическую координату x.
static int xF(double x)
{
double a, b;
a=(Program.xF1 - Program.xF2 )/(Program.xL1 -Program.xL2 );
b = Program.xF1 - a * Program.xL1;
return (int)(a*x+b);
}
Аналогичную функцию метод создадим для преобразования y
static int yF(double y)
{
double a, b;
a = (Program.yF1 - Program.yF2) / (Program.yL1 - Program.yL2);
b = Program.yF1 - a * Program.yL1;
return (int)(a * y + b);
}
Теперь, когда у нас есть функции преобразования от логических координат к физическим, можно в основной программе методе main получать по ряду логических координат соответствующие значения физических координат.
double dx = 0.2;
for (double x = -3.0; x <= 3.0; x = x + dx)
{
System.Console.WriteLine(" xL={0:0.0} xF={1} ",x,Program.xF(x) );
}
System.Console.ReadLine();
Полный текст программы приведен в листинге №1.
// Листинг 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Графика2
{
class Program
{
static public double xL1, xL2, yL1, yL2;
static public int xF1, xF2, yF1, yF2;
static int xF(double x)
{
double a, b;
a=(Program.xF1 - Program.xF2 )/(Program.xL1 -Program.xL2 );
b = Program.xF1 - a * Program.xL1;
return (int)(a*x+b);
}
static int yF(double y)
{
double a, b;
a = (Program.yF1 - Program.yF2) / (Program.yL1 - Program.yL2);
b = Program.yF1 - a * Program.yL1;
return (int)(a * y + b);
}
static void Main(string[] args)
{
Program.xF1 = 0;
Program.xF2 = 600;
Program.yF1 = 800;
Program.yF2 = 0;
Program.xL1 = -5.0;
Program.yL1 = -10.0;
Program.xL2 = 5.0;
Program.yL2 = 10.0;
double dx = 0.2;
for (double x = -3.0; x <= 3.0; x = x + dx)
{
System.Console.WriteLine(" xL={0:0.0} xF={1} ",x,Program.xF(x) );
}
System.Console.ReadLine();
}
}
}
// Конец Листинга 1
Результат работы программы:
Задайте свои размеры логического и физического прямоугольников и получите по логическим координатам x и y соответствующие физические координаты.
Усовершенствуем нашу программу. Используем класс System.Drawing.Point. Класс System.Drawing.Point специально предназначен для хранения информации и работы с точками графического массива, экрана и т.п. У экземпляров данного класса объектов есть свойства X и Y, которые, собственно и определяют координаты точки. Тогда наша программа примет вид:
// Листинг 2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Графика2
{
class Program
{
static double xL1, xL2, yL1, yL2;
static System.Drawing.Point pF1,pF2;
static int xF(double x)
{
double a, b;
a=(Program.pF1.X - Program.pF2.X )/(Program.xL1 -Program.xL2 );
b = Program.pF1.X - a * Program.xL1;
return (int)(a*x+b);
}
static int yF(double y)
{
double a, b;
a = (Program.pF1.Y - Program.pF2.Y) / (Program.yL1 - Program.yL2);
b = Program.pF1.Y - a * Program.yL1;
return (int)(a * y + b);
}
static void Main(string[] args)
{
Program.pF1= new System.Drawing.Point(0,800);
Program.pF2= new System.Drawing.Point(600,0);
Program.xL1 = -5.0;
Program.yL1 = -10.0;
Program.xL2 = 5.0;
Program.yL2 = 10.0;
double dx = 0.2;
for (double x = -3.0; x <= 3.0; x = x + dx)
{
System.Console.WriteLine(" xL={0:0.0} xF={1} ",x,Program.xF(x) );
}
System.Console.ReadLine();
}
}
}
// Конец листинга №2
В вышеприведенном листинге №2 чувствуется некоторая недоработка, действительно, для физических точек используется класс Point, а логические точки задаются по-прежнему через две вещественные переменные. Можно более изящно написать нашу программу, если создать класс для вещественных точек. Назовем его DPoint.
class DPoint
{
public double X;
public double Y;
public DPoint(double x, double y)
{
this.X = x;
this.Y = y;
}
public DPoint()
{
this.X = 0;
this.Y = 0;
}
}
Обратите внимание на то, что в нашем классе есть два перегруженных конструктора методы DPoint() и DPoint(double x, double y). Конструктор это специальный метод класса, который автоматически вызывается при создании экземпляра этого класса командой new. Экземпляры нашего класса можно создавать двумя способами:
DPoint p = new DPoint();
В этом случае в конструктор не передаются аргументы и свойства X и Y нашего экземпляра принимают значения ноль.
DPoint p = new DPoint(3.0, 8.2);
В этом случае в конструктор передаются аргументы 3.0 и 8.2 и свойства X и Y нашего экземпляра принимают, соответственно значения 3.0 и 8.2.
Если пространство имен нашей программы называется «Графика2», то новый класс принадлежит этому пространству и к нему можно обращаться как Графика2.DPoint
Теперь в классе Program можно ввести по два свойства типа Point и DPoint для физических (целочисленных) точек и логических (вещественных) точек.
static Графика2.DPoint pL1, pL2;
static System.Drawing.Point pF1,pF2;
Начальные значения координатам наших опорных точек задаются в методе main основной программы
Program.pF1= new System.Drawing.Point(0,800);
Program.pF2= new System.Drawing.Point(600,0);
Program.pL1 = new DPoint( -5.0,-10.0);
Program.pL2 = new DPoint( 5.0,10.0);
А вместо двух дополнительных методов преобразования для X и Y компонент можно ввести один метод для преобразования точек
static System.Drawing.Point pF(DPoint p)
Этот метод получает в качестве аргумента вещественную точку p класса DPoint, а возвращает целочисленную точку класса Point
static System.Drawing.Point pF(DPoint p)
{
double a1, b1;
a1=(Program.pF1.X - Program.pF2.X )/(Program.pL1.X -Program.pL2.X );
b1 = Program.pF1.X - a1 * Program.pL1.X;
double a2, b2;
a2 = (Program.pF1.Y - Program.pF2.Y) / (Program.pL1.Y - Program.pL2.Y);
b2 = Program.pF1.Y - a2 * Program.pL1.Y;
System.Drawing.Point pF= new System.Drawing.Point((int)(a1*p.X+b1),(int)(a2*p.Y+b2)) ;
return pF;
}
Текст всей программы приведен в листинге №3
// Листинг №3
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Графика2
{
class DPoint
{
public double X;
public double Y;
public DPoint(double x, double y)
{
this.X = x;
this.Y = y;
}
public DPoint()
{
this.X = 0;
this.Y = 0;
}
}
class Program
{
static Графика2.DPoint pL1, pL2;
static System.Drawing.Point pF1,pF2;
static System.Drawing.Point pF(DPoint p)
{
double a1, b1;
a1=(Program.pF1.X - Program.pF2.X )/(Program.pL1.X -Program.pL2.X );
b1 = Program.pF1.X - a1 * Program.pL1.X;
double a2, b2;
a2 = (Program.pF1.Y - Program.pF2.Y) / (Program.pL1.Y - Program.pL2.Y);
b2 = Program.pF1.Y - a2 * Program.pL1.Y;
System.Drawing.Point pF= new System.Drawing.Point((int)(a1*p.X+b1),(int)(a2*p.Y+b2)) ;
return pF;
}
static void Main(string[] args)
{
Program.pF1= new System.Drawing.Point(0,800);
Program.pF2= new System.Drawing.Point(600,0);
Program.pL1 = new DPoint( -5.0,-10.0);
Program.pL2 = new DPoint( 5.0,10.0);
double dx = 0.2;
for (double x = -3.0; x <= 3.0; x = x + dx)
{
double y = (x - 5) * (x + 3);
DPoint pL = new DPoint (x, y);
System.Console.WriteLine(" xL={0:0.0} xF={1} ",x,pL.X );
}
System.Console.ReadLine();
}
}
}
// Конец листинга №3