Стрелка на OpenGL
AntXXX Дата: Четверг, 05 Июня 2014, 21:57 | Сообщение # 1
был не раз
Сейчас нет на сайте
Здравствуйте! Может ли кто-то привести пример хорошей реализации функции, которая получает на ввод координаты концов отрезков и рисует стрелку? Заранее спасибо!
Snake174 Дата: Пятница, 06 Июня 2014, 06:17 | Сообщение # 2
участник
Сейчас нет на сайте
Пример на Qt, но думаю на OGL не составит большого труда переделать.
Код
class RArrow { public: RArrow(); void raDrawArrow( QPainter *p ); void raSetArrowHead(); void raSetArrowLine(); void raSetArrowHead2(); void raSetArrowLine2(); public: QPointF raArrowPoints[ 10 ]; QPointF raStartPoint; QPointF raEndPoint; double raLineWidth; double raHeadWidth; double raHeadHeight; QColor raBorderColor; QColor raFillColor; double raBorderThickness; bool twoSided; };
Код
//================================================================================================= RArrow::RArrow() { raStartPoint = QPoint( -1, -1 ); raEndPoint = QPoint( -1, -1 ); raLineWidth = 0; raHeadHeight = 0; raHeadWidth = 0; raBorderThickness = 0; twoSided = false; for (int i = 0; i < 10; ++i) raArrowPoints[i] = QPointF( -1, -1 ); } //================================================================================================= void RArrow::raSetArrowHead() { double x1 = raStartPoint.x(); double y1 = raStartPoint.y(); double x2 = raEndPoint.x(); double y2 = raEndPoint.y(); double distance = sqrt( pow( x2 - x1, 2 ) + pow( y2 - y1, 2 ) ); double dx = x2 + (x1 - x2) * raHeadHeight / distance; double dy = y2 + (y1 - y2) * raHeadHeight / distance; double k = raHeadWidth / raHeadHeight; double x2o = x2 - dx; double y2o = dy - y2; double x3 = y2o * k + dx; double y3 = x2o * k + dy; double x4 = dx - y2o * k; double y4 = dy - x2o * k; raArrowPoints[0] = QPointF( x4, y4 ); raArrowPoints[1] = QPointF( x2, y2 ); raArrowPoints[2] = QPointF( x3, y3 ); } //================================================================================================= void RArrow::raSetArrowLine() { double x1 = raStartPoint.x(); double y1 = raStartPoint.y(); double x2 = (raArrowPoints[0].x() + raArrowPoints[2].x()) / 2.0; double y2 = (raArrowPoints[0].y() + raArrowPoints[2].y()) / 2.0; double k = raLineWidth / sqrt( pow( x2 - x1, 2 ) + pow( y2 - y1, 2 ) ); double x2o = x2 - x1; double y2o = y1 - y2; double x3 = y2o * k + x1; double y3 = x2o * k + y1; double x4 = x1 - y2o * k; double y4 = y1 - x2o * k; double x1o = x1 - x2; double y1o = y2 - y1; double x5 = y1o * k + x2; double y5 = x1o * k + y2; double x6 = x2 - y1o * k; double y6 = y2 - x1o * k; raArrowPoints[4] = QPointF( x3, y3 ); raArrowPoints[5] = QPointF( x4, y4 ); raArrowPoints[6] = QPointF( x5, y5 ); raArrowPoints[3] = QPointF( x6, y6 ); } //================================================================================================= void RArrow::raSetArrowHead2() { double x1 = raEndPoint.x(); double y1 = raEndPoint.y(); double x2 = raStartPoint.x(); double y2 = raStartPoint.y(); double distance = sqrt( pow( x2 - x1, 2 ) + pow( y2 - y1, 2 ) ); double dx = x2 + (x1 - x2) * raHeadHeight / distance; double dy = y2 + (y1 - y2) * raHeadHeight / distance; double k = raHeadWidth / raHeadHeight; double x2o = x2 - dx; double y2o = dy - y2; double x3 = y2o * k + dx; double y3 = x2o * k + dy; double x4 = dx - y2o * k; double y4 = dy - x2o * k; raArrowPoints[5] = QPointF( x4, y4 ); raArrowPoints[6] = QPointF( x2, y2 ); raArrowPoints[7] = QPointF( x3, y3 ); } //================================================================================================= void RArrow::raSetArrowLine2() { double x1 = (raArrowPoints[0].x() + raArrowPoints[2].x()) / 2.0; double y1 = (raArrowPoints[0].y() + raArrowPoints[2].y()) / 2.0; double x2 = (raArrowPoints[5].x() + raArrowPoints[7].x()) / 2.0; double y2 = (raArrowPoints[5].y() + raArrowPoints[7].y()) / 2.0; double k = raLineWidth / sqrt( pow( x2 - x1, 2 ) + pow( y2 - y1, 2 ) ); double x2o = x2 - x1; double y2o = y1 - y2; double x3 = y2o * k + x1; double y3 = x2o * k + y1; double x4 = x1 - y2o * k; double y4 = y1 - x2o * k; double x1o = x1 - x2; double y1o = y2 - y1; double x5 = y1o * k + x2; double y5 = x1o * k + y2; double x6 = x2 - y1o * k; double y6 = y2 - x1o * k; raArrowPoints[9] = QPointF( x3, y3 ); raArrowPoints[3] = QPointF( x4, y4 ); raArrowPoints[4] = QPointF( x5, y5 ); raArrowPoints[8] = QPointF( x6, y6 ); } //================================================================================================= void RArrow::raDrawArrow( QPainter *p ) { p->setPen( QPen( QBrush( raBorderColor ), raBorderThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) ); p->setBrush( QBrush( raFillColor ) ); if (!twoSided) { raSetArrowHead(); raSetArrowLine(); } else { raSetArrowHead(); raSetArrowHead2(); raSetArrowLine2(); } p->setRenderHint( QPainter::Antialiasing, true ); if (!twoSided) p->drawPolygon( raArrowPoints, 7 ); else p->drawPolygon( raArrowPoints, 10 ); } //=================================================================================================
Код
void LegendScene::drawForeground( QPainter *painter, const QRectF &/*rect*/ ) { painter->beginNativePainting(); RArrow arrow; arrow.raStartPoint = QPointF( 10, 10 ); arrow.raEndPoint = QPointF( 100, 100 ); arrow.raHeadWidth = 5.0; arrow.raHeadHeight = 15.0; arrow.raBorderThickness = 2.0; arrow.raLineWidth = 2.0; arrow.raBorderColor = Qt::black; arrow.raFillColor = Qt::gray; arrow.twoSided = true; arrow.raDrawArrow( painter ); painter->endNativePainting(); }
Как это всё выглядит можешь посмотреть в этой теме SEE . В шапке под спойлером "Скриншоты" пятый скрин.
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
morglodddd Дата: Пятница, 06 Июня 2014, 08:49 | Сообщение # 3
участник
Сейчас нет на сайте
На OpenGL есть огромное множество способов нарисовать отрезок: Можно шейдером, можно матрицами, можно буфферами, можно старейшим glBegin/glEnd. Какой тебе подходит больше?
AntXXX Дата: Пятница, 06 Июня 2014, 15:24 | Сообщение # 4
был не раз
Сейчас нет на сайте
2morglodddd: Отрезок та понятно как нарисовать, а вот треугольник на конце отрезка не очень то и выходит. 2Snake174: Спасибо за пример но как-то много кода. Думал есть способ попроще. И ещё как можно нормально строить отрезок под окружностью. Код
void Objects::draw() { glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); for(float i=0.0; i<2*M_PI; i+=M_PI/18) glVertex3f(this->x+this->r*sin(i), this->y+this->r*cos(i), 10.0); glEnd(); } void Objects::line(int x1, int y1, int x2, int y2) { glLineWidth(3); glBegin(GL_LINES); glVertex3f(x1, y1, -10.0); glVertex3f(x2, y2, -10.0); glEnd(); }
Вроде и координаты по z нормально задаю.
morglodddd Дата: Пятница, 06 Июня 2014, 18:24 | Сообщение # 5
участник
Сейчас нет на сайте
Цитата AntXXX (
)
а вот треугольник на конце отрезка не очень то и выходит
Начерти на бумаге линию, поставь задачу на одном из концов построить равнобедренный треугольник при том что даны точки линии немного геометрии