Курсовые
Черчение

Теплоэнергетика

Электротехника
Карта

Компьютерная алгебра

Поиск минимумов и максимумов аналитических функций

Часто нужно найти минимум или максимум заданной функции. Для поиска минимумов и максимумов выражений (функций) ехрr служат функции стандартной библиотеки:

minimize(expr, optl, opt2, .... optn)

  maximize(expr, optl. opt2. .... optn)

Эти функции могут разыскивать максимумы и минимумы для функций как одной, так и нескольких переменных. С помощью опций optl, opt2,..., optn можно указывать дополнительные данные для поиска. Например, параметр `infinity` означает, что поиск минимума или максимума выполняется по всей числовой оси, а параметр location (или locatiorrtrue) дает расширенный вывод результатов поиска — выдается не только значение минимума (или максимума), но и значения переменных в этой точке.

Примеры применения функции minimize приведены ниже:

Приведем подобные примеры и для функции поиска максимума — maximize:

Обратите внимание на то, что в предпоследнем примере Maple 7 явно «оскандалилась» и вместо максимума функции sin(x)/x, равного 1 при х=0, выдал результат в виде бесконечности. Другими словами, система обнаружила, что в данном случае ей незнакомо понятие предела sin(x)/x  при х—>0. Эта ситуация кажется более чем странной, если учесть, что в этом примере Maple 6 давал правильный результат.

Применим функцию minimize для поиска минимума функции Розенброка. Рисунок 9.1 показывает, что minimize прекрасно справляется с данной задачей. На рис. 9.1 представлено также построение функции Розенброка, хорошо иллюстрирующее ее особенности.

Рис. 9.1. Поиск минимума функции Розенброка и построение ее графика

Трудность поиска минимума функции Розенброка связана с ее характерными особенностями. Из рис. 9.1 видно, что эта функция представляет собой поверхность типа «глубокого оврага с почти плоским дном», в котором и расположена точка минимума. Такая особенность этой функции существенно затрудняет поиск минимума. То, что система Maple 7 справляется с данной тестовой функцией, вовсе не означает, что трудности в поиске минимума или максимума других функций остаются позади.

Закраска области, заданной цветом границы

 Рассмотрим область, ограниченную набором пикселей заданного цвета, и точку (x, y), лежащую внутри этой области.

  Задача заполнения области заданным цветом в случае, когда область не является выпуклой, может оказаться довольно сложной.

//File fill1.cpp

void PixelFill(int x, int y, int BorderColor, int color)

{

 int c=getpixel(x,y);

  if((c!=BorderColor) && (c!=color))

 {

 putpixel(x,y,color);

  PixelFill(x-1,y,BorderColor,color);

 PixelFill(x+1,y,BorderColor,color);

  PixelFill(x,y-1,BorderColor,color);

 PixelFill(x,y+1,BorderColor,color);

}

}

  Простейший алгоритм, показанный выше, хотя и абсолютно корректно заполняющий даже самые сложные области, является слишком неэффективным, так как уже для отрисованного пикселя функция вызывается еще три раза, и, кроме того, требует слишком большого стека из-за большой глубины рекурсии.

 Поэтому для решения задачи закраски области предпочтительнее алгоритмы, способные обрабатывать сразу целые группы пикселей.

 Рассмотрим версию одного из самых популярных алгоритмов подобного типа, когда для заданной точки (x, y) определяется и заполняется максимальный отрезок , содержащий эту точку и лежащий внутри области. После этого в поисках еще не заполненных пикселей проверяются отрезки, лежащие выше и ниже. Если такие пиксели находятся, то функция рекурсивно вызывается для их обработки.

 Этот алгоритм эффективно работает даже для областей с дырками (рисунок 4.4.1).

//File fill2.cpp

#include <conio.h>

#include <graphics.h>

#include <process.h>

#include <stdio.h>

#include <stdlib.h>

int BorderColor = WHITE;

int Color = GREEN;

int LineFill(int x, int y, int dir, int PrevX1, int PrevXr)

{

 int x1=x;

  int xr=x;

 int c;

 do

 c=getpixel(--x1,y);

 while((c!=BorderColor)&&(c!=Color));

  do

 c=getpixel(++xr,y);

 while((c!=BorderColor)&&(c!=Color));

  x1++;

 xr++;

 line(x1,y,xr,y);

 for(x=x1;x<=xr;x++)

  {

 c=getpixel(x,y+dir);

 if((c!=BorderColor) &&(c!=Color))

  x=LineFill(x,y+dir,dir,x1,xr);

}

 for(x=x1;x<PrevX1;x++)

  {

 c=getpixel(x,y-dir);

 if((c!=BorderColor) &&(c!=Color))

  x=LineFill(x,y-dir,-dir,x1,xr);

}

 for(x=PrevXr;x<xr;x++)

  {

 c=getpixel(x,y-dir);

 if((c!=BorderColor) &&(c!=Color))

  x=LineFill(x,y-dir,-dir,x1,xr);

}

return xr;

}

void Fill(int x,int y);

{

 LineFill(x, y, 1, x, x);

}

main()

{

  int driver=DETECT;

 int mode;

 int res;

 initgraph(&driver, &mode, “”);

 if((res=graphresult())!=grOk)

 {

 printf(“\nGraphics error: %s\n”, grapherrormsg(res));

 exit(1);

}

circle(320,200,140);

circle(260,200,40);

circle(380,200,40);

getch();

setcolor(Color);

Fill(320,300);

getch();

closegraph();

}

Закраска методом Фонга

 Как и описанный выше метод закраски Гуро, закраска Фонга при расчете интенсивности также опирается на интерполирование. Однако в отличие от метода Гуро здесь интерполируется не значение интенсивности по уже известным ее значениям в опорных точках, а значение вектора внешней нормали, которое затем используется для вычисления интенсивности пикселя. Поэтому закраска Фонга требует заметно большего объема вычислений. Правда, при этом и изображение получается более близким к реалистичному (в частности, при закраске Фонга зеркальные блики выглядят довольно правдоподобно).

Инженерная графика

 

Сопромат