⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basic2.cpp

📁 wxGTK 是 wxWidgets 的 linux GTK+ (>2.2.3)版本。wxWidgets 是一个跨平台的 GUI 框架
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/////////////////////////////////////////////////////////////////////////////// Name:        basic2.cpp// Purpose:     Basic OGL classes (2)// Author:      Julian Smart// Modified by:// Created:     12/07/98// RCS-ID:      $Id: basic2.cpp,v 1.25 2005/10/06 18:17:21 ABX Exp $// Copyright:   (c) Julian Smart// Licence:     wxWindows licence/////////////////////////////////////////////////////////////////////////////// For compilers that support precompilation, includes "wx.h".#include "wx/wxprec.h"#ifdef __BORLANDC__#pragma hdrstop#endif#ifndef WX_PRECOMP#include "wx/wx.h"#endif#if wxUSE_PROLOGIO#include "wx/deprecated/wxexpr.h"#endif#ifdef new#undef new#endif#include <stdio.h>#include <ctype.h>#include <math.h>#include "wx/ogl/ogl.h"// Control point types// Rectangle and most other shapes#define CONTROL_POINT_VERTICAL   1#define CONTROL_POINT_HORIZONTAL 2#define CONTROL_POINT_DIAGONAL   3// Line#define CONTROL_POINT_ENDPOINT_TO 4#define CONTROL_POINT_ENDPOINT_FROM 5#define CONTROL_POINT_LINE       6// Two stage construction: need to call CreateIMPLEMENT_DYNAMIC_CLASS(wxPolygonShape, wxShape)wxPolygonShape::wxPolygonShape(){  m_points = NULL;  m_originalPoints = NULL;}void wxPolygonShape::Create(wxList *the_points){  ClearPoints();  if (!the_points)  {      m_originalPoints = new wxList;      m_points = new wxList;  }  else  {      m_originalPoints = the_points;      // Duplicate the list of points      m_points = new wxList;      wxObjectList::compatibility_iterator node = the_points->GetFirst();      while (node)      {          wxRealPoint *point = (wxRealPoint *)node->GetData();          wxRealPoint *new_point = new wxRealPoint(point->x, point->y);          m_points->Append((wxObject*) new_point);          node = node->GetNext();      }      CalculateBoundingBox();      m_originalWidth = m_boundWidth;      m_originalHeight = m_boundHeight;      SetDefaultRegionSize();  }}wxPolygonShape::~wxPolygonShape(){    ClearPoints();}void wxPolygonShape::ClearPoints(){  if (m_points)  {    wxObjectList::compatibility_iterator node = m_points->GetFirst();    while (node)    {      wxRealPoint *point = (wxRealPoint *)node->GetData();      delete point;      m_points->Erase(node);      node = m_points->GetFirst();    }    delete m_points;    m_points = NULL;  }  if (m_originalPoints)  {    wxObjectList::compatibility_iterator node = m_originalPoints->GetFirst();    while (node)    {      wxRealPoint *point = (wxRealPoint *)node->GetData();      delete point;      m_originalPoints->Erase(node);      node = m_originalPoints->GetFirst();    }    delete m_originalPoints;    m_originalPoints = NULL;  }}// Width and height. Centre of object is centre of box.void wxPolygonShape::GetBoundingBoxMin(double *width, double *height){  *width = m_boundWidth;  *height = m_boundHeight;}void wxPolygonShape::CalculateBoundingBox(){  // Calculate bounding box at construction (and presumably resize) time  double left = 10000;  double right = -10000;  double top = 10000;  double bottom = -10000;  wxObjectList::compatibility_iterator node = m_points->GetFirst();  while (node)  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    if (point->x < left) left = point->x;    if (point->x > right) right = point->x;    if (point->y < top) top = point->y;    if (point->y > bottom) bottom = point->y;    node = node->GetNext();  }  m_boundWidth = right - left;  m_boundHeight = bottom - top;}// Recalculates the centre of the polygon, and// readjusts the point offsets accordingly.// Necessary since the centre of the polygon// is expected to be the real centre of the bounding// box.void wxPolygonShape::CalculatePolygonCentre(){  double left = 10000;  double right = -10000;  double top = 10000;  double bottom = -10000;  wxObjectList::compatibility_iterator node = m_points->GetFirst();  while (node)  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    if (point->x < left) left = point->x;    if (point->x > right) right = point->x;    if (point->y < top) top = point->y;    if (point->y > bottom) bottom = point->y;    node = node->GetNext();  }  double bwidth = right - left;  double bheight = bottom - top;  double newCentreX = (double)(left + (bwidth/2.0));  double newCentreY = (double)(top + (bheight/2.0));  node = m_points->GetFirst();  while (node)  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    point->x -= newCentreX;    point->y -= newCentreY;    node = node->GetNext();  }  m_xpos += newCentreX;  m_ypos += newCentreY;}bool PolylineHitTest(double n, double xvec[], double yvec[],                           double x1, double y1, double x2, double y2){  bool isAHit = false;  int i;  double lastx = xvec[0];  double lasty = yvec[0];  double min_ratio = 1.0;  double line_ratio;  double other_ratio;  for (i = 1; i < n; i++)  {    oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i],                            &line_ratio, &other_ratio);    if (line_ratio != 1.0)      isAHit = true;    lastx = xvec[i];    lasty = yvec[i];    if (line_ratio < min_ratio)      min_ratio = line_ratio;  }  // Do last (implicit) line if last and first doubles are not identical  if (!(xvec[0] == lastx && yvec[0] == lasty))  {    oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0],                            &line_ratio, &other_ratio);    if (line_ratio != 1.0)      isAHit = true;  }  return isAHit;}bool wxPolygonShape::HitTest(double x, double y, int *attachment, double *distance){  // Imagine four lines radiating from this point. If all of these lines hit the polygon,  // we're inside it, otherwise we're not. Obviously we'd need more radiating lines  // to be sure of correct results for very strange (concave) shapes.  double endPointsX[4];  double endPointsY[4];  // North  endPointsX[0] = x;  endPointsY[0] = (double)(y - 1000.0);  // East  endPointsX[1] = (double)(x + 1000.0);  endPointsY[1] = y;  // South  endPointsX[2] = x;  endPointsY[2] = (double)(y + 1000.0);  // West  endPointsX[3] = (double)(x - 1000.0);  endPointsY[3] = y;  // Store polygon points in an array  int np = m_points->GetCount();  double *xpoints = new double[np];  double *ypoints = new double[np];  wxObjectList::compatibility_iterator node = m_points->GetFirst();  int i = 0;  while (node)  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    xpoints[i] = point->x + m_xpos;    ypoints[i] = point->y + m_ypos;    node = node->GetNext();    i ++;  }  // We assume it's inside the polygon UNLESS one or more  // lines don't hit the outline.  bool isContained = true;  int noPoints = 4;  for (i = 0; i < noPoints; i++)  {    if (!PolylineHitTest(np, xpoints, ypoints, x, y, endPointsX[i], endPointsY[i]))      isContained = false;  }/*  if (isContained)    ClipsErrorFunction("It's a hit!\n");  else    ClipsErrorFunction("No hit.\n");*/  delete[] xpoints;  delete[] ypoints;  if (!isContained)    return false;  int nearest_attachment = 0;  // If a hit, check the attachment points within the object.  int n = GetNumberOfAttachments();  double nearest = 999999.0;  for (i = 0; i < n; i++)  {    double xp, yp;    if (GetAttachmentPositionEdge(i, &xp, &yp))    {      double l = (double)sqrt(((xp - x) * (xp - x)) +                 ((yp - y) * (yp - y)));      if (l < nearest)      {        nearest = l;        nearest_attachment = i;      }    }  }  *attachment = nearest_attachment;  *distance = nearest;  return true;}// Really need to be able to reset the shape! Otherwise, if the// points ever go to zero, we've lost it, and can't resize.void wxPolygonShape::SetSize(double new_width, double new_height, bool WXUNUSED(recursive)){  SetAttachmentSize(new_width, new_height);  // Multiply all points by proportion of new size to old size  double x_proportion = (double)(fabs(new_width/m_originalWidth));  double y_proportion = (double)(fabs(new_height/m_originalHeight));  wxObjectList::compatibility_iterator node = m_points->GetFirst();  wxObjectList::compatibility_iterator original_node = m_originalPoints->GetFirst();  while (node && original_node)  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    wxRealPoint *original_point = (wxRealPoint *)original_node->GetData();    point->x = (original_point->x * x_proportion);    point->y = (original_point->y * y_proportion);    node = node->GetNext();    original_node = original_node->GetNext();  }//  CalculateBoundingBox();  m_boundWidth = (double)fabs(new_width);  m_boundHeight = (double)fabs(new_height);  SetDefaultRegionSize();}// Make the original points the same as the working pointsvoid wxPolygonShape::UpdateOriginalPoints(){  if (!m_originalPoints) m_originalPoints = new wxList;  wxObjectList::compatibility_iterator original_node = m_originalPoints->GetFirst();  while (original_node)  {    wxObjectList::compatibility_iterator next_node = original_node->GetNext();    wxRealPoint *original_point = (wxRealPoint *)original_node->GetData();    delete original_point;    m_originalPoints->Erase(original_node);    original_node = next_node;  }  wxObjectList::compatibility_iterator node = m_points->GetFirst();  while (node)  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    wxRealPoint *original_point = new wxRealPoint(point->x, point->y);    m_originalPoints->Append((wxObject*) original_point);    node = node->GetNext();  }  CalculateBoundingBox();  m_originalWidth = m_boundWidth;  m_originalHeight = m_boundHeight;}void wxPolygonShape::AddPolygonPoint(int pos){  wxObjectList::compatibility_iterator node = m_points->Item(pos);  if (!node) node = m_points->GetFirst();  wxRealPoint *firstPoint = (wxRealPoint *)node->GetData();  wxObjectList::compatibility_iterator node2 = m_points->Item(pos + 1);  if (!node2) node2 = m_points->GetFirst();  wxRealPoint *secondPoint = (wxRealPoint *)node2->GetData();  double x = (double)((secondPoint->x - firstPoint->x)/2.0 + firstPoint->x);  double y = (double)((secondPoint->y - firstPoint->y)/2.0 + firstPoint->y);  wxRealPoint *point = new wxRealPoint(x, y);  if (pos >= (int) (m_points->GetCount() - 1))    m_points->Append((wxObject*) point);  else    m_points->Insert(node2, (wxObject*) point);  UpdateOriginalPoints();  if (m_selected)  {    DeleteControlPoints();    MakeControlPoints();  }}void wxPolygonShape::DeletePolygonPoint(int pos){  wxObjectList::compatibility_iterator node = m_points->Item(pos);  if (node)  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    delete point;    m_points->Erase(node);    UpdateOriginalPoints();    if (m_selected)    {      DeleteControlPoints();      MakeControlPoints();    }  }}// Assume (x1, y1) is centre of box (most generally, line end at box)bool wxPolygonShape::GetPerimeterPoint(double x1, double y1,                                     double x2, double y2,                                     double *x3, double *y3){  int n = m_points->GetCount();  // First check for situation where the line is vertical,  // and we would want to connect to a point on that vertical --  // oglFindEndForPolyline can't cope with this (the arrow  // gets drawn to the wrong place).  if ((m_attachmentMode == ATTACHMENT_MODE_NONE) && (x1 == x2))  {    // Look for the point we'd be connecting to. This is    // a heuristic...    wxObjectList::compatibility_iterator node = m_points->GetFirst();    while (node)    {      wxRealPoint *point = (wxRealPoint *)node->GetData();      if (point->x == 0.0)      {        if ((y2 > y1) && (point->y > 0.0))        {          *x3 = point->x + m_xpos;          *y3 = point->y + m_ypos;          return true;        }        else if ((y2 < y1) && (point->y < 0.0))        {          *x3 = point->x + m_xpos;          *y3 = point->y + m_ypos;          return true;        }      }      node = node->GetNext();    }  }  double *xpoints = new double[n];  double *ypoints = new double[n];  wxObjectList::compatibility_iterator node = m_points->GetFirst();  int i = 0;  while (node)  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    xpoints[i] = point->x + m_xpos;    ypoints[i] = point->y + m_ypos;    node = node->GetNext();    i ++;  }  oglFindEndForPolyline(n, xpoints, ypoints,                        x1, y1, x2, y2, x3, y3);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -