Jump to content

Алгоритм Ляна – Барского

(Перенаправлено с Лян-Барского )

В компьютерной графике алгоритм Ляна-Барски (названный в честь Ю-Донг Ляна и Брайана А. Барски ) представляет собой алгоритм обрезки строк . Алгоритм Ляна-Барского использует параметрическое уравнение линии и неравенства, описывающие диапазон окна отсечения, для определения пересечений между линией и окном отсечения . Благодаря этим пересечениям он знает, какую часть линии следует нарисовать. Таким образом, этот алгоритм значительно более эффективен, чем Коэн-Сазерленд . Идея алгоритма отсечения Ляна – Барски состоит в том, чтобы провести как можно больше испытаний перед вычислением пересечений линий.

Алгоритм использует параметрическую форму прямой:

Точка находится в окне клипа, если

и

которое можно выразить в виде четырех неравенств

где

Чтобы вычислить окончательный сегмент линии:

  1. Линия, параллельная краю окна обрезки, имеет для этой границы.
  2. Если для этого , , то линия полностью снаружи и ее можно устранить.
  3. Когда , линия проходит снаружи внутрь окна клипа, а когда , линия проходит изнутри наружу.
  4. Для ненулевого , дает для точки пересечения линии и края окна (возможно, проецируемого).
  5. Два фактических пересечения линии с краями окна, если они существуют, описываются формулой и , рассчитывается следующим образом. Для , посмотрите на границы, для которых (т.е. снаружи внутрь). Брать быть крупнейшим среди . Для , посмотрите на границы, для которых (т.е. изнутри наружу). Брать быть минимумом .
  6. Если , линия полностью находится за пределами окна клипа. Если оно полностью внутри него.
// Liang—Barsky line-clipping algorithm
#include<iostream>
#include<graphics.h>
#include<math.h>

using namespace std;

// this function gives the maximum
float maxi(float arr[],int n) {
  float m = 0;
  for (int i = 0; i < n; ++i)
    if (m < arr[i])
      m = arr[i];
  return m;
}

// this function gives the minimum
float mini(float arr[], int n) {
  float m = 1;
  for (int i = 0; i < n; ++i)
    if (m > arr[i])
      m = arr[i];
  return m;
}

void liang_barsky_clipper(float xmin, float ymin, float xmax, float ymax,
                          float x1, float y1, float x2, float y2) {
  // defining variables
  float p1 = -(x2 - x1);
  float p2 = -p1;
  float p3 = -(y2 - y1);
  float p4 = -p3;

  float q1 = x1 - xmin;
  float q2 = xmax - x1;
  float q3 = y1 - ymin;
  float q4 = ymax - y1;

  float posarr[5], negarr[5];
  int posind = 1, negind = 1;
  posarr[0] = 1;
  negarr[0] = 0;

  rectangle(xmin, ymin, xmax, ymax); // drawing the clipping window

  if ((p1 == 0 && q1 < 0) || (p2 == 0 && q2 < 0) || (p3 == 0 && q3 < 0) || (p4 == 0 && q4 < 0)) {
      outtextxy(80, 80, "Line is parallel to clipping window!");
      return;
  }
  if (p1 != 0) {
    float r1 = q1 / p1;
    float r2 = q2 / p2;
    if (p1 < 0) {
      negarr[negind++] = r1; // for negative p1, add it to negative array
      posarr[posind++] = r2; // and add p2 to positive array
    } else {
      negarr[negind++] = r2;
      posarr[posind++] = r1;
    }
  }
  if (p3 != 0) {
    float r3 = q3 / p3;
    float r4 = q4 / p4;
    if (p3 < 0) {
      negarr[negind++] = r3;
      posarr[posind++] = r4;
    } else {
      negarr[negind++] = r4;
      posarr[posind++] = r3;
    }
  }

  float xn1, yn1, xn2, yn2;
  float rn1, rn2;
  rn1 = maxi(negarr, negind); // maximum of negative array
  rn2 = mini(posarr, posind); // minimum of positive array

  if (rn1 > rn2)  { // reject
    outtextxy(80, 80, "Line is outside the clipping window!");
    return;
  }

  xn1 = x1 + p2 * rn1;
  yn1 = y1 + p4 * rn1; // computing new points

  xn2 = x1 + p2 * rn2;
  yn2 = y1 + p4 * rn2;

  setcolor(CYAN);

  line(xn1, yn1, xn2, yn2); // the drawing the new line

  setlinestyle(1, 1, 0);

  line(x1, y1, xn1, yn1);
  line(x2, y2, xn2, yn2);
}

int main() {
  cout << "\nLiang-barsky line clipping";
  cout << "\nThe system window outlay is: (0,0) at bottom left and (631, 467) at top right";
  cout << "\nEnter the co-ordinates of the window(wxmin, wymin, wxmax, wymax):";
  float xmin, ymin, xmax, ymax;
  cin >> xmin >> ymin >> xmax >> ymax;
  cout << "\nEnter the end points of the line (x1, y1) and (x2, y2):";
  float x1, y1, x2, y2;
  cin >> x1 >> y1 >> x2 >> y2;

  int gd = DETECT, gm;

  // using the winbgim library for C++, initializing the graphics mode
  initgraph(&gd, &gm, "");
  liang_barsky_clipper(xmin, ymin, xmax, ymax, x1, y1, x2, y2);
  getch();
  closegraph();
}

См. также

[ редактировать ]

Алгоритмы, используемые для той же цели:

[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 8eb499ad1239e17b9ead35b1b9b599b4__1682895420
URL1:https://arc.ask3.ru/arc/aa/8e/b4/8eb499ad1239e17b9ead35b1b9b599b4.html
Заголовок, (Title) документа по адресу, URL1:
Liang–Barsky algorithm - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)