예제 #1
0
파일: HDxf.cpp 프로젝트: play113/swer
void HeeksDxfRead::OnReadSpline(struct SplineData& sd)
{
	bool closed = (sd.flag & 1) != 0;
	bool periodic = (sd.flag & 2) != 0;
	bool rational = (sd.flag & 4) != 0;
	// bool planar = (sd.flag & 8) != 0;
	// bool linear = (sd.flag & 16) != 0;

	SplineData sd_copy = sd;

	if(closed)
	{
		// add some more control points
		sd_copy.control_points += 3;

		//for(int i = 0; i<3; i++
		//sd_copy.controlx
	}

	TColgp_Array1OfPnt control (1,/*closed ? sd.controlx.size() + 1:*/sd.controlx.size());
	TColStd_Array1OfReal weight (1,sd.controlx.size());

	std::list<double> knoto;
	std::list<int> multo;

	std::list<double>::iterator ity = sd.controly.begin();
	std::list<double>::iterator itz = sd.controlz.begin();
	std::list<double>::iterator itw = sd.weight.begin();

	unsigned i=1; //int i=1;
	for(std::list<double>::iterator itx = sd.controlx.begin(); itx!=sd.controlx.end(); ++itx)
	{
		gp_Pnt pnt(*itx,*ity,*itz);
		control.SetValue(i,pnt);
		if(sd.weight.empty())
			weight.SetValue(i,1);
		else
		{
			weight.SetValue(i,*itw);
			++itw;
		}
		++i;
		++ity;
		++itz;
	}

	i=1;
	double last_knot = -1;
	for(std::list<double>::iterator it = sd.knot.begin(); it!=sd.knot.end(); ++it)
	{
		if(*it != last_knot)
		{
			knoto.push_back(*it);
			multo.push_back(1);
			i++;
		}
		else
		{
			int temp = multo.back();
			multo.pop_back();
			multo.push_back(temp+1);
		}
		last_knot = *it;
	}

	TColStd_Array1OfReal knot (1, knoto.size());
	TColStd_Array1OfInteger mult (1, knoto.size());

	std::list<int>::iterator itm = multo.begin();
	i = 1;
	for(std::list<double>::iterator it = knoto.begin(); it!=knoto.end(); ++it)
	{
		knot.SetValue(i,*it);
		int m = *itm;
		if(closed && (i == 1 || i == knoto.size()))m = 1;
		mult.SetValue(i, m);
		++itm;
		++i;
	}

	OnReadSpline(control, weight, knot, mult, sd.degree, periodic, rational);
}
예제 #2
0
파일: Pocket.cpp 프로젝트: play113/swer
static wxString WriteSketchDefn(HeeksObj* sketch)
{
#ifdef UNICODE
	std::wostringstream gcode;
#else
    std::ostringstream gcode;
#endif
    gcode.imbue(std::locale("C"));
	gcode << std::setprecision(10);

	bool started = false;

	double prev_e[3];

	std::list<HeeksObj*> new_spans;
	for(HeeksObj* span = sketch->GetFirstChild(); span; span = sketch->GetNextChild())
	{
		if(span->GetType() == SplineType)
		{
			((HSpline*)span)->ToBiarcs(new_spans, CPocket::max_deviation_for_spline_to_arc);
		}
		else
		{
			new_spans.push_back(span->MakeACopy());
		}
	}

	for(std::list<HeeksObj*>::iterator It = new_spans.begin(); It != new_spans.end(); It++)
	{
		HeeksObj* span_object = *It;

		double s[3] = {0, 0, 0};
		double e[3] = {0, 0, 0};
		double c[3] = {0, 0, 0};

		if(span_object){
			int type = span_object->GetType();

			if(type == LineType || type == ArcType)
			{
				span_object->GetStartPoint(s);
				CNCPoint start(s);

				if(started && (fabs(s[0] - prev_e[0]) > 0.0001 || fabs(s[1] - prev_e[1]) > 0.0001))
				{
					gcode << _T("a.append(c)\n");
					started = false;
				}

				if(!started)
				{
					gcode << _T("c = area.Curve()\n");
					gcode << _T("c.append(area.Vertex(0, area.Point(") << start.X(true) << _T(", ") << start.Y(true) << _T("), area.Point(0, 0)))\n");
					started = true;
				}
				span_object->GetEndPoint(e);
				CNCPoint end(e);

				if(type == LineType)
				{
					gcode << _T("c.append(area.Vertex(0, area.Point(") << end.X(true) << _T(", ") << end.Y(true) << _T("), area.Point(0, 0)))\n");
				}
				else if(type == ArcType)
				{
					span_object->GetCentrePoint(c);
					CNCPoint centre(c);

					double pos[3];
					extract(((HArc*)span_object)->m_axis.Direction(), pos);
					int span_type = (pos[2] >=0) ? 1:-1;
					gcode << _T("c.append(area.Vertex(") << span_type << _T(", area.Point(") << end.X(true) << _T(", ") << end.Y(true);
					gcode << _T("), area.Point(") << centre.X(true) << _T(", ") << centre.Y(true) << _T(")))\n");
				}
				memcpy(prev_e, e, 3*sizeof(double));
			} // End if - then
			else
			{
				if (type == CircleType)
				{
					if(started)
					{
						gcode << _T("a.append(c)\n");
						started = false;
					}

					std::list< std::pair<int, gp_Pnt > > points;
					span_object->GetCentrePoint(c);

					// Setup the four arcs that will make up the circle using UNadjusted
					// coordinates first so that the offsets align with the X and Y axes.
					double radius = ((HCircle*)span_object)->m_radius;

					points.push_back( std::make_pair(0, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north
					points.push_back( std::make_pair(-1, gp_Pnt( c[0] + radius, c[1], c[2] )) ); // east
					points.push_back( std::make_pair(-1, gp_Pnt( c[0], c[1] - radius, c[2] )) ); // south
					points.push_back( std::make_pair(-1, gp_Pnt( c[0] - radius, c[1], c[2] )) ); // west
					points.push_back( std::make_pair(-1, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north

					CNCPoint centre(c);

					gcode << _T("c = area.Curve()\n");
					for (std::list< std::pair<int, gp_Pnt > >::iterator l_itPoint = points.begin(); l_itPoint != points.end(); l_itPoint++)
					{
						CNCPoint pnt( l_itPoint->second );

						gcode << _T("c.append(area.Vertex(") << l_itPoint->first << _T(", area.Point(");
						gcode << pnt.X(true) << (_T(", ")) << pnt.Y(true);
						gcode << _T("), area.Point(") << centre.X(true) << _T(", ") << centre.Y(true) << _T(")))\n");
					} // End for
					gcode << _T("a.append(c)\n");
				}
			} // End if - else
		}
	}

	if(started)
	{
		gcode << _T("a.append(c)\n");
		started = false;
	}

	// delete the spans made
	for(std::list<HeeksObj*>::iterator It = new_spans.begin(); It != new_spans.end(); It++)
	{
		HeeksObj* span = *It;
		delete span;
	}

	gcode << _T("\n");
	return(wxString(gcode.str().c_str()));
}
예제 #3
0
파일: richradid.C 프로젝트: krafczyk/AMS
RichRadiatorTileManager::RichRadiatorTileManager(TrTrack *track){
  if(_number_of_rad_tiles==0){
    cerr<<"RichRadiatorTileManager::RichRadiatorTileManager -- tiles not initialized -- doing it"<<endl;
    Init();
  }

  // First decide wich kind of radiator is current
  AMSPoint pnt(0.,0.,RICHDB::RICradpos()-RICHDB::rad_height),point;
  AMSDir   dir(0.,0.,-1.);
  number theta,phi,length;
  
  // Transform RICH plane to AMS plane 
  pnt=RichAlignment::RichToAMS(pnt);
  dir=RichAlignment::RichToAMS(dir);

  // Get the track interpolation
  track->interpolate(pnt,dir,point,
		     theta,phi,length);


  // Transform the point to RICH frame again to get X and Y
  point=RichAlignment::AMSToRich(point);
  
  _current_tile=get_tile_number(point[0],point[1]);
  
  if(_current_tile<0){
    _p_direct=AMSPoint(0.,0.,0.);
    _p_reflected=AMSPoint(0.,0.,0.);
    _d_direct=AMSDir(0.,0.);
    _d_reflected=AMSDir(0.,0.);
    return;
  }


  // Use the mean position for the direct photons to estimate the
  // local mean index
  double dx=point[0]-_tiles[_current_tile]->position[0];
  double dy=point[1]-_tiles[_current_tile]->position[1];

  // Compute the distance to the tile border
  _distance2border=fmin(fabs(get_tile_boundingbox(_current_tile,0)-fabs(dx)),
			fabs(get_tile_boundingbox(_current_tile,1)-fabs(dy)));

  pnt.setp(0.,0.,RICHDB::RICradpos()-RICHDB::rad_height+getheight());

  // Transform to AMS
  pnt=RichAlignment::RichToAMS(pnt);

  track->interpolate(pnt,dir,point,
		     theta,phi,
		     length);

  // Transform the point to RICH frame again to get X and Y
  point=RichAlignment::AMSToRich(point);
  
  if(getkind()!=get_tile_kind(get_tile_number(point[0],point[1]))){
    _current_tile=-1;
    _p_direct=AMSPoint(0.,0.,0.);
    _p_reflected=AMSPoint(0.,0.,0.);
    _d_direct=AMSDir(0.,0.);
    _d_reflected=AMSDir(0.,0.);
    return;
  }
  
  _p_entrance=point;
  AMSDir d(theta,phi);
  _d_entrance=RichAlignment::AMSToRich(d);


  // Direct photons
  pnt.setp(0.,0.,RICHDB::RICradpos()-RICHDB::rad_height+_tiles[_current_tile]->mean_height);
  pnt=RichAlignment::RichToAMS(pnt);
  track->interpolate(pnt,dir,point,theta,phi,length);
  
  _p_direct=RichAlignment::AMSToRich(point);
  d=AMSDir(theta,phi);
  _d_direct=RichAlignment::AMSToRich(d);
  
  // Reflected photons
  pnt.setp(0.,0.,RICHDB::RICradpos()-RICHDB::rad_height+_tiles[_current_tile]->mean_height);
  pnt=RichAlignment::RichToAMS(pnt);
  track->interpolate(pnt,dir,point,theta,phi,length);
  
  _p_reflected=RichAlignment::AMSToRich(point);
  d=AMSDir(theta,phi);
  _d_reflected=RichAlignment::AMSToRich(d);
  
 
  if(_tiles[_current_tile]->kind==naf_kind) _local_index=_tiles[_current_tile]->mean_refractive_index;
  else _local_index=1+(_tiles[_current_tile]->mean_refractive_index-1)*
    (_tiles[_current_tile]->LocalIndex(dx,dy)-1)/
    (_tiles[_current_tile]->index-1);


  // Force the propagation direction to be downwards
  if(_d_direct[2]>0) _d_direct=_d_direct*(-1);
  if(_d_reflected[2]>0) _d_reflected=_d_reflected*(-1);


} 
예제 #4
0
파일: Terrain.cpp 프로젝트: prohan91/zyGrib
//---------------------------------------------------------
// paintEvent
//---------------------------------------------------------
void Terrain::paintEvent(QPaintEvent * /*event*/)
{
    QPainter pnt(this);
    QColor transp;
    int r = 100;
    if (!isResizing || !firstDrawingIsDone)
    {
		firstDrawingIsDone = true;
        // Draw the map and the GRIB data
        QCursor oldcursor = cursor();
        setCursor(Qt::WaitCursor);
        
        switch (currentFileType) {
			case DATATYPE_GRIB :
			case DATATYPE_MBLUE :
				drawer->draw_GSHHS_and_GriddedData 
						(pnt, mustRedraw, isEarthMapValid, proj, griddedPlot);
				break;
			case DATATYPE_IAC :
				drawer->draw_GSHHS_and_IAC 
						(pnt, mustRedraw, isEarthMapValid, proj, iacPlot);
				break;
			default :
				drawer->draw_GSHHS (pnt, mustRedraw, isEarthMapValid, proj);
        }
		
        setCursor(oldcursor);
		isEarthMapValid = true;
		mustRedraw = false;
		pleaseWait = false;
        
        if (selX0!=selX1 && selY0!=selY1) {
            // Draw the rectangle of the selected zone
            pnt.setPen(selectColor);
            transp = QColor(r,r,r, 80);
            pnt.setBrush(transp);
            int x0,y0, x1,y1;
            proj->map2screen(selX0, selY0, &x0, &y0);
            proj->map2screen(selX1, selY1, &x1, &y1);
            pnt.drawRect(x0, y0, x1-x0, y1-y0);
            
            if (showOrthodromie)
            {
                QPen penLine(QColor(Qt::white));
                penLine.setWidthF(1.6);
                pnt.setPen(penLine);
                draw_Orthodromie(pnt);
            }
        }
    }
    else {
        switch (currentFileType) {
			case DATATYPE_GRIB :
			case DATATYPE_MBLUE :
				drawer->draw_GSHHS_and_GriddedData 
						(pnt, false, true, proj, griddedPlot);
				break;
			case DATATYPE_IAC :
				drawer->draw_GSHHS_and_IAC 
						(pnt, false, true, proj, iacPlot);
				break;
			default :
				drawer->draw_GSHHS (pnt, mustRedraw, isEarthMapValid, proj);
        }
	}
    
    if (mustShowSpecialZone) {
		if (specialZoneX0!=specialZoneX1 && specialZoneY0!=specialZoneY1) {
			pnt.setPen(QColor(Qt::white));
			r = 80;
			transp = QColor(r,r,r, 50);
			pnt.setBrush(transp);
			int x0,y0, x1,y1;
			proj->map2screen(specialZoneX0, specialZoneY0, &x0, &y0);
			proj->map2screen(specialZoneX1, specialZoneY1, &x1, &y1);
			pnt.drawRect(x0, y0, x1-x0, y1-y0);
		}
    }
    
    if (pleaseWait) {
        // Write the message "please wait..." on the map
        QFont fontWait = Font::getFont(FONT_MapWait);
        QFontMetrics fmet(fontWait);
        pnt.setPen(QColor(Qt::white));
        r = 80;
        transp = QColor(r,r,r, 80);
        pnt.setFont(fontWait);
        pnt.setBrush(transp);
        QString txt = tr("  Please wait...  ");
        QRect rect = fmet.boundingRect(txt);

        rect.moveTo(20,20);
        pnt.drawRect(rect);
        pnt.drawText(rect, Qt::AlignHCenter|Qt::AlignVCenter , txt);
    }
}
예제 #5
0
CPoint2D CPoint2D::operator-(const CPoint2D& other) const
{ 
	CPoint2D pnt(m_X - other.m_X, m_Y - other.m_Y); 
	
	return pnt;
}
예제 #6
0
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static int isKeydown = false;
	int wmId, wmEvent;
/*	int tempX,tempY;*/
	switch (message) 
	{
	case WM_COMMAND:
	{
		wmId    = LOWORD(wParam); 
		wmEvent = HIWORD(wParam); 
		
		switch (wmId)
		{
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		case IDM_PENCIL:
			g_mode = modePENCIL;
			break;
		case IDM_POINTS:
			g_mode = modePOINTS;
			break;
		case IDM_LINES:
			g_mode = modeLINES;
			break;
		case IDM_Polygon:
			g_mode = modePOLYGON;
			break;
		case IDM_CIRCLE:
			g_mode = modeCIRCLE;
			break;
		case IDM_COLOR:
			DialogBox(hInst, (LPCTSTR)IDD_COLORBOX, hWnd, (DLGPROC)colorBox);
			break;
		case IDM_SIZEBOX:
			DialogBox(hInst, (LPCTSTR)IDD_DEFAULTWIDTH, hWnd, (DLGPROC)sizeBox);
			break;
		case IDM_CLEAR:
			{
				vec[0]->clear();
				vec[1]->clear();
				for(size_t i=2; i < vec.size(); ++i)
					delete vec[i];
				vec.erase(vec.begin() + 2, vec.end());
				InvalidateRect(hWnd, NULL, false);
				break;
			}
		case IDM_ADDPOINT:
			DialogBox(hInst, (LPCTSTR)IDD_ADDPOINT, hWnd, (DLGPROC)addPointBox);
			break;
		case IDM_ADDLINE:
			DialogBox(hInst, (LPCTSTR)IDD_ADDLINES, hWnd, (DLGPROC)addLineBox);
			break;
		case IDM_ADDPOLYGON:
			DialogBox(hInst, (LPCTSTR)IDD_ADDPOLYGON, hWnd, (DLGPROC)addPolygonBox);
			break;
		case IDM_ADDCIRCLE:
			DialogBox(hInst, (LPCTSTR)IDD_ADDCIRCLE, hWnd, (DLGPROC)addCircleBox);
			break;
		case IDM_SAVE: save(hWnd); break;
		case IDM_HELP:
			DialogBox(hInst, (LPCTSTR)IDD_HELPBOX, hWnd, (DLGPROC)Help);
			break;
		case IDM_DELETEPOINT:
			vec[0]->eraseLast();
			break;
		case IDM_DELETELINE:
			vec[1]->eraseLast();
			break;
		case IDM_DELETEOTHER:
			if(vec.size() >2)
				vec.erase(vec.end() -1);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	}

	case WM_RBUTTONDOWN:
		if(!isKeydown || g_mode != modePOLYGON) break;
		addLastPoint(lParam);
		break;
	case WM_MOUSEMOVE:
		if(!isKeydown) break;
		switch(g_mode)
		{
		case modePENCIL: addLastPoint(lParam); break;
		case modePOINTS: addPoints(lParam); break;
		case modeLINES: modifyLastLine(lParam); break;
		case modePOLYGON: 
		case modeCIRCLE: modifyLastPoint(lParam); break;
		}
		InvalidateRect(hWnd,NULL,false);
		break;
	case WM_LBUTTONDOWN:
		isKeydown = true;
		switch(g_mode)
		{
		case modePENCIL:
			{
				Point pnt(LOWORD(lParam),g_clientRect.bottom - HIWORD(lParam));
				PicElem* p = new Pencil;
				p->add(pnt, g_defColor,g_defSize);
				vec.push_back(p);
			}
			break;
		case modePOINTS: addPoints(lParam); break;
		case modeLINES:
			addLines(lParam,lParam);
			break;
		case modePOLYGON:
			{
				Point pnt(LOWORD(lParam),g_clientRect.bottom - HIWORD(lParam));
				PicElem* p = new Polygons;
				p->add(pnt, pnt, g_defColor,g_defSize);
				p->add(pnt, g_defColor,g_defSize);
				vec.push_back(p);
			}
			break;
		case modeCIRCLE:
			{
				Point pnt(LOWORD(lParam),g_clientRect.bottom - HIWORD(lParam));
				PicElem* p = new Circles;
				p->add(pnt, g_defColor, g_defSize);
				vec.push_back(p);
			}			
		}
		InvalidateRect(hWnd,NULL,false);
		break;
	case WM_LBUTTONUP:
		isKeydown = false;
		break;
	case WM_SIZE:
		{
			GetClientRect(g_hwnd, &g_clientRect);
			g_cliWidth = g_clientRect.right - g_clientRect.left;
			g_cliHeight = g_clientRect.bottom - g_clientRect.top;
			GetWindowRect(g_hwnd, &g_rect);
			g_scrWidth = g_rect.right - g_rect.left;
			g_scrHeight = g_rect.bottom - g_rect.top;
			if(g_cliWidth > 0 && g_cliHeight > 0)
				SceneResizeViewport(g_cliWidth, g_cliHeight);
		}
		break;
	case WM_CHAR:
		switch(wParam)
		{
		case '\n': case '\r':
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
			break;
		case ' ':
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
			break;				
		}
	case WM_PAINT:
		SceneShow();
		ValidateRect(hWnd,NULL);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
예제 #7
0
//===========================================================================
void SplineUtils::closest_on_rectgrid(const double* pt, const double* array,
			 int u_min, int u_max, int v_min, int v_max,
			 int nmb_coefs_u,
			 double& clo_u, double& clo_v)
//===========================================================================
{
    // m is number of columns
    // n is number of rows
    // in array, the column index runs fastest.

    // For each (not necessarily planar) quadrangle, split into 2
    // triangles. Then find distance to triangle, and closest point
    // in triangle.

    Vector3D pnt(pt);
    Vector3D p[4];
    Vector3D tri[3];

    Vector3D umask1(0, 1, 0);
    Vector3D umask2(1, 1, 0);
    Vector3D vmask1(0, 0, 1);
    Vector3D vmask2(0, 1, 1);

    double bestdist2 = 1e100;
    double best_u = 0;
    double best_v = 0;

    for (int i = u_min; i < u_max; ++i) {
	for (int j = v_min; j < v_max; ++j) {
	    // Pick the corner points counterclockwise
	    p[0].setValue(array + (j*nmb_coefs_u + i)*3);
	    p[1].setValue(array + (j*nmb_coefs_u + i+1)*3);
	    p[2].setValue(array + ((j+1)*nmb_coefs_u + i+1)*3);
	    p[3].setValue(array + ((j+1)*nmb_coefs_u + i)*3);
	    // Lower triangle, points 0, 1, 3.
	    tri[0] = p[0];
	    tri[1] = p[1];
	    tri[2] = p[3];
	    double clo_dist2;
	    Vector3D cltri = SplineUtils::closest_on_triangle(pnt, tri, clo_dist2);
	    if (clo_dist2 < bestdist2) {
		best_u = i + umask1*cltri;
		best_v = j + vmask1*cltri;
		bestdist2 = clo_dist2;
	    }
	    // Upper triangle, points 1, 2, 3.
	    tri[0] = p[1];
	    tri[1] = p[2];
	    tri[2] = p[3];
	    cltri = SplineUtils::closest_on_triangle(pnt, tri, clo_dist2);
	    if (clo_dist2 < bestdist2) {
		best_u = i + umask2*cltri;
		best_v = j + vmask2*cltri;
		bestdist2 = clo_dist2;
	    }
	}
    }
    clo_u = best_u;
    clo_v = best_v;
    int ii = min(int(floor(clo_u)), u_max - 1);
    int jj = min(int(floor(clo_v)), v_max - 1);
    p[0].setValue(array + (jj*nmb_coefs_u + ii)*3);
    p[1].setValue(array + (jj*nmb_coefs_u + ii+1)*3);
    p[2].setValue(array + ((jj+1)*nmb_coefs_u + ii+1)*3);
    p[3].setValue(array + ((jj+1)*nmb_coefs_u + ii)*3);
}
예제 #8
0
파일: assmodule.cpp 프로젝트: deviator/ass
pnt AssUnitRls::getNormal () const
{
    return pnt(0,0,1);
}
예제 #9
0
int kWindow::on_hit_test(kPoint pnt_)
{
 CPoint pnt(pnt_.x,pnt_.y);

 return CWnd::OnNcHitTest(pnt);
}
예제 #10
0
UINT kWindow::OnNcHitTest(CPoint point)
{
 kPoint pnt(point.x,point.y);

 return (UINT) on_hit_test(pnt);
}
 inline pnt operator -(const pnt &p){
     return pnt(x-p.x,y-p.y);
 }
 inline pnt operator +(const pnt &p){
     return pnt(x+p.x,y+p.y);
 }
예제 #13
0
SOrientedBoundingBox *
SOrientedBoundingBox::buildOBB(std::vector<SPoint3> &vertices)
{
#if defined(HAVE_MESH)

  int num_vertices = vertices.size();
  // First organize the data

  std::set<SPoint3> unique;
  unique.insert(vertices.begin(), vertices.end());

  num_vertices = unique.size();
  fullMatrix<double> data(3, num_vertices);

  fullVector<double> mean(3);
  fullVector<double> vmins(3);
  fullVector<double> vmaxs(3);

  mean.setAll(0);
  vmins.setAll(DBL_MAX);
  vmaxs.setAll(-DBL_MAX);

  size_t idx = 0;
  for(std::set<SPoint3>::iterator uIter = unique.begin(); uIter != unique.end();
      ++uIter) {
    const SPoint3 &pp = *uIter;
    for(int d = 0; d < 3; d++) {
      data(d, idx) = pp[d];
      vmins(d) = std::min(vmins(d), pp[d]);
      vmaxs(d) = std::max(vmaxs(d), pp[d]);
      mean(d) += pp[d];
    }
    idx++;
  }

  for(int i = 0; i < 3; i++) { mean(i) /= num_vertices; }

  // Get the deviation from the mean
  fullMatrix<double> B(3, num_vertices);
  for(int i = 0; i < 3; i++) {
    for(int j = 0; j < num_vertices; j++) { B(i, j) = data(i, j) - mean(i); }
  }

  // Compute the covariance matrix
  fullMatrix<double> covariance(3, 3);
  B.mult(B.transpose(), covariance);
  covariance.scale(1. / (num_vertices - 1));
  /*
  Msg::Debug("Covariance matrix");
  Msg::Debug("%f %f %f", covariance(0,0),covariance(0,1),covariance(0,2) );
  Msg::Debug("%f %f %f", covariance(1,0),covariance(1,1),covariance(1,2) );
  Msg::Debug("%f %f %f", covariance(2,0),covariance(2,1),covariance(2,2) );
  */
  for(int i = 0; i < 3; i++) {
    for(int j = 0; j < 3; j++) {
      if(std::abs(covariance(i, j)) < 10e-16) covariance(i, j) = 0;
    }
  }

  fullMatrix<double> left_eigv(3, 3);
  fullMatrix<double> right_eigv(3, 3);
  fullVector<double> real_eig(3);
  fullVector<double> img_eig(3);
  covariance.eig(real_eig, img_eig, left_eigv, right_eigv, true);

  // Now, project the data in the new basis.
  fullMatrix<double> projected(3, num_vertices);
  left_eigv.transpose().mult(data, projected);
  // Get the size of the box in the new direction
  fullVector<double> mins(3);
  fullVector<double> maxs(3);
  for(int i = 0; i < 3; i++) {
    mins(i) = DBL_MAX;
    maxs(i) = -DBL_MAX;
    for(int j = 0; j < num_vertices; j++) {
      maxs(i) = std::max(maxs(i), projected(i, j));
      mins(i) = std::min(mins(i), projected(i, j));
    }
  }

  // double means[3];
  double sizes[3];

  // Note:  the size is computed in the box's coordinates!
  for(int i = 0; i < 3; i++) {
    sizes[i] = maxs(i) - mins(i);
    // means[i] = (maxs(i) - mins(i)) / 2.;
  }

  if(sizes[0] == 0 && sizes[1] == 0) {
    // Entity is a straight line...
    SVector3 center;
    SVector3 Axis1;
    SVector3 Axis2;
    SVector3 Axis3;

    Axis1[0] = left_eigv(0, 0);
    Axis1[1] = left_eigv(1, 0);
    Axis1[2] = left_eigv(2, 0);
    Axis2[0] = left_eigv(0, 1);
    Axis2[1] = left_eigv(1, 1);
    Axis2[2] = left_eigv(2, 1);
    Axis3[0] = left_eigv(0, 2);
    Axis3[1] = left_eigv(1, 2);
    Axis3[2] = left_eigv(2, 2);

    center[0] = (vmaxs(0) + vmins(0)) / 2.0;
    center[1] = (vmaxs(1) + vmins(1)) / 2.0;
    center[2] = (vmaxs(2) + vmins(2)) / 2.0;

    return new SOrientedBoundingBox(center, sizes[0], sizes[1], sizes[2], Axis1,
                                    Axis2, Axis3);
  }

  // We take the smallest component, then project the data on the plane defined
  // by the other twos

  int smallest_comp = 0;
  if(sizes[0] <= sizes[1] && sizes[0] <= sizes[2])
    smallest_comp = 0;
  else if(sizes[1] <= sizes[0] && sizes[1] <= sizes[2])
    smallest_comp = 1;
  else if(sizes[2] <= sizes[0] && sizes[2] <= sizes[1])
    smallest_comp = 2;

  // The projection has been done circa line 161.
  // We just ignore the coordinate corresponding to smallest_comp.
  std::vector<SPoint2 *> points;
  for(int i = 0; i < num_vertices; i++) {
    SPoint2 *p = new SPoint2(projected(smallest_comp == 0 ? 1 : 0, i),
                             projected(smallest_comp == 2 ? 1 : 2, i));
    bool keep = true;
    for(std::vector<SPoint2 *>::iterator point = points.begin();
        point != points.end(); point++) {
      if(std::abs((*p)[0] - (**point)[0]) < 10e-10 &&
         std::abs((*p)[1] - (**point)[1]) < 10e-10) {
        keep = false;
        break;
      }
    }
    if(keep) { points.push_back(p); }
    else {
      delete p;
    }
  }

  // Find the convex hull from a delaunay triangulation of the points
  DocRecord record(points.size());
  record.numPoints = points.size();
  srand((unsigned)time(0));
  for(std::size_t i = 0; i < points.size(); i++) {
    record.points[i].where.h =
      points[i]->x() + (10e-6) * sizes[smallest_comp == 0 ? 1 : 0] *
                         (-0.5 + ((double)rand()) / RAND_MAX);
    record.points[i].where.v =
      points[i]->y() + (10e-6) * sizes[smallest_comp == 2 ? 1 : 0] *
                         (-0.5 + ((double)rand()) / RAND_MAX);
    record.points[i].adjacent = NULL;
  }

  try {
    record.MakeMeshWithPoints();
  } catch(const char *err) {
    Msg::Error("%s", err);
  }

  std::vector<Segment> convex_hull;
  for(int i = 0; i < record.numTriangles; i++) {
    Segment segs[3];
    segs[0].from = record.triangles[i].a;
    segs[0].to = record.triangles[i].b;
    segs[1].from = record.triangles[i].b;
    segs[1].to = record.triangles[i].c;
    segs[2].from = record.triangles[i].c;
    segs[2].to = record.triangles[i].a;

    for(int j = 0; j < 3; j++) {
      bool okay = true;
      for(std::vector<Segment>::iterator seg = convex_hull.begin();
          seg != convex_hull.end(); seg++) {
        if(((*seg).from == segs[j].from && (*seg).from == segs[j].to)
           // FIXME:
           // || ((*seg).from == segs[j].to && (*seg).from == segs[j].from)
        ) {
          convex_hull.erase(seg);
          okay = false;
          break;
        }
      }
      if(okay) { convex_hull.push_back(segs[j]); }
    }
  }

  // Now, examinate all the directions given by the edges of the convex hull
  // to find the one that lets us build the least-area bounding rectangle for
  // then points.
  fullVector<double> axis(2);
  axis(0) = 1;
  axis(1) = 0;
  fullVector<double> axis2(2);
  axis2(0) = 0;
  axis2(1) = 1;
  SOrientedBoundingRectangle least_rectangle;
  least_rectangle.center[0] = 0.0;
  least_rectangle.center[1] = 0.0;
  least_rectangle.size[0] = -1.0;
  least_rectangle.size[1] = 1.0;

  fullVector<double> segment(2);
  fullMatrix<double> rotation(2, 2);

  for(std::vector<Segment>::iterator seg = convex_hull.begin();
      seg != convex_hull.end(); seg++) {
    // segment(0) = record.points[(*seg).from].where.h -
    // record.points[(*seg).to].where.h;  segment(1) =
    // record.points[(*seg).from].where.v - record.points[(*seg).to].where.v;
    segment(0) = points[(*seg).from]->x() - points[(*seg).to]->x();
    segment(1) = points[(*seg).from]->y() - points[(*seg).to]->y();
    segment.scale(1.0 / segment.norm());

    double cosine = axis(0) * segment(0) + segment(1) * axis(1);
    double sine = axis(1) * segment(0) - segment(1) * axis(0);
    // double sine = axis(0)*segment(1) - segment(0)*axis(1);

    rotation(0, 0) = cosine;
    rotation(0, 1) = sine;
    rotation(1, 0) = -sine;
    rotation(1, 1) = cosine;

    // TODO C++11 std::numeric_limits<double>
    double max_x = -DBL_MAX;
    double min_x = DBL_MAX;
    double max_y = -DBL_MAX;
    double min_y = DBL_MAX;

    for(int i = 0; i < record.numPoints; i++) {
      fullVector<double> pnt(2);
      // pnt(0) = record.points[i].where.h;
      // pnt(1) = record.points[i].where.v;
      pnt(0) = points[i]->x();
      pnt(1) = points[i]->y();

      fullVector<double> rot_pnt(2);
      rotation.mult(pnt, rot_pnt);

      if(rot_pnt(0) < min_x) min_x = rot_pnt(0);
      if(rot_pnt(0) > max_x) max_x = rot_pnt(0);
      if(rot_pnt(1) < min_y) min_y = rot_pnt(1);
      if(rot_pnt(1) > max_y) max_y = rot_pnt(1);
    }

    /**/
    fullVector<double> center_rot(2);
    fullVector<double> center_before_rot(2);
    center_before_rot(0) = (max_x + min_x) / 2.0;
    center_before_rot(1) = (max_y + min_y) / 2.0;
    fullMatrix<double> rotation_inv(2, 2);

    rotation_inv(0, 0) = cosine;
    rotation_inv(0, 1) = -sine;
    rotation_inv(1, 0) = sine;
    rotation_inv(1, 1) = cosine;

    rotation_inv.mult(center_before_rot, center_rot);

    fullVector<double> axis_rot1(2);
    fullVector<double> axis_rot2(2);

    rotation_inv.mult(axis, axis_rot1);
    rotation_inv.mult(axis2, axis_rot2);

    if((least_rectangle.area() == -1) ||
       (max_x - min_x) * (max_y - min_y) < least_rectangle.area()) {
      least_rectangle.size[0] = max_x - min_x;
      least_rectangle.size[1] = max_y - min_y;
      least_rectangle.center[0] = (max_x + min_x) / 2.0;
      least_rectangle.center[1] = (max_y + min_y) / 2.0;
      least_rectangle.center[0] = center_rot(0);
      least_rectangle.center[1] = center_rot(1);
      least_rectangle.axisX[0] = axis_rot1(0);
      least_rectangle.axisX[1] = axis_rot1(1);
      //      least_rectangle.axisX[0] = segment(0);
      //      least_rectangle.axisX[1] = segment(1);
      least_rectangle.axisY[0] = axis_rot2(0);
      least_rectangle.axisY[1] = axis_rot2(1);
    }
  }
  // TODO C++11 std::numeric_limits<double>::min() / max()
  double min_pca = DBL_MAX;
  double max_pca = -DBL_MAX;
  for(int i = 0; i < num_vertices; i++) {
    min_pca = std::min(min_pca, projected(smallest_comp, i));
    max_pca = std::max(max_pca, projected(smallest_comp, i));
  }
  double center_pca = (max_pca + min_pca) / 2.0;
  double size_pca = (max_pca - min_pca);

  double raw_data[3][5];
  raw_data[0][0] = size_pca;
  raw_data[1][0] = least_rectangle.size[0];
  raw_data[2][0] = least_rectangle.size[1];

  raw_data[0][1] = center_pca;
  raw_data[1][1] = least_rectangle.center[0];
  raw_data[2][1] = least_rectangle.center[1];

  for(int i = 0; i < 3; i++) {
    raw_data[0][2 + i] = left_eigv(i, smallest_comp);
    raw_data[1][2 + i] =
      least_rectangle.axisX[0] * left_eigv(i, smallest_comp == 0 ? 1 : 0) +
      least_rectangle.axisX[1] * left_eigv(i, smallest_comp == 2 ? 1 : 2);
    raw_data[2][2 + i] =
      least_rectangle.axisY[0] * left_eigv(i, smallest_comp == 0 ? 1 : 0) +
      least_rectangle.axisY[1] * left_eigv(i, smallest_comp == 2 ? 1 : 2);
  }
  // Msg::Info("Test 1 : %f
  // %f",least_rectangle.center[0],least_rectangle.center[1]);
  // Msg::Info("Test 2 : %f
  // %f",least_rectangle.axisY[0],least_rectangle.axisY[1]);

  int tri[3];

  if(size_pca > least_rectangle.size[0]) {
    // P > R0
    if(size_pca > least_rectangle.size[1]) {
      // P > R1
      tri[0] = 0;
      if(least_rectangle.size[0] > least_rectangle.size[1]) {
        // R0 > R1
        tri[1] = 1;
        tri[2] = 2;
      }
      else {
        // R1 > R0
        tri[1] = 2;
        tri[2] = 1;
      }
    }
    else {
      // P < R1
      tri[0] = 2;
      tri[1] = 0;
      tri[2] = 1;
    }
  }
  else { // P < R0
    if(size_pca < least_rectangle.size[1]) {
      // P < R1
      tri[2] = 0;
      if(least_rectangle.size[0] > least_rectangle.size[1]) {
        tri[0] = 1;
        tri[1] = 2;
      }
      else {
        tri[0] = 2;
        tri[1] = 1;
      }
    }
    else {
      tri[0] = 1;
      tri[1] = 0;
      tri[2] = 2;
    }
  }

  SVector3 size;
  SVector3 center;
  SVector3 Axis1;
  SVector3 Axis2;
  SVector3 Axis3;

  for(int i = 0; i < 3; i++) {
    size[i] = raw_data[tri[i]][0];
    center[i] = raw_data[tri[i]][1];
    Axis1[i] = raw_data[tri[0]][2 + i];
    Axis2[i] = raw_data[tri[1]][2 + i];
    Axis3[i] = raw_data[tri[2]][2 + i];
  }

  SVector3 aux1;
  SVector3 aux2;
  SVector3 aux3;
  for(int i = 0; i < 3; i++) {
    aux1(i) = left_eigv(i, smallest_comp);
    aux2(i) = left_eigv(i, smallest_comp == 0 ? 1 : 0);
    aux3(i) = left_eigv(i, smallest_comp == 2 ? 1 : 2);
  }
  center = aux1 * center_pca + aux2 * least_rectangle.center[0] +
           aux3 * least_rectangle.center[1];
  // center[1] = -center[1];

  /*
  Msg::Info("Box center : %f %f %f",center[0],center[1],center[2]);
  Msg::Info("Box size : %f %f %f",size[0],size[1],size[2]);
  Msg::Info("Box axis 1 : %f %f %f",Axis1[0],Axis1[1],Axis1[2]);
  Msg::Info("Box axis 2 : %f %f %f",Axis2[0],Axis2[1],Axis2[2]);
  Msg::Info("Box axis 3 : %f %f %f",Axis3[0],Axis3[1],Axis3[2]);

  Msg::Info("Volume : %f", size[0]*size[1]*size[2]);
  */

  return new SOrientedBoundingBox(center, size[0], size[1], size[2], Axis1,
                                  Axis2, Axis3);
#else
  Msg::Error("SOrientedBoundingBox requires mesh module");
  return 0;
#endif
}
예제 #14
0
Python CProfile::WriteSketchDefn(HeeksObj* sketch, bool reversed )
{
	// write the python code for the sketch
	Python python;

	if ((sketch->GetShortString() != NULL) && (wxString(sketch->GetShortString()).size() > 0))
	{
		python << (wxString::Format(_T("comment(%s)\n"), PythonString(sketch->GetShortString()).c_str()));
	}

	python << _T("curve = area.Curve()\n");

	bool started = false;
	std::list<HeeksObj*> spans;
	switch(sketch->GetType())
	{
	case SketchType:
		for(HeeksObj* span_object = sketch->GetFirstChild(); span_object; span_object = sketch->GetNextChild())
		{
			if(reversed)spans.push_front(span_object);
			else spans.push_back(span_object);
		}
		break;
	case CircleType:
		spans.push_back(sketch);
		break;
	case AreaType:
		break;
	}

	std::list<HeeksObj*> new_spans;
	for(std::list<HeeksObj*>::iterator It = spans.begin(); It != spans.end(); It++)
	{
		HeeksObj* span = *It;
		if(span->GetType() == SplineType)
		{
			std::list<HeeksObj*> new_spans2;
			heeksCAD->SplineToBiarcs(span, new_spans2, CProfile::max_deviation_for_spline_to_arc);
			if(reversed)
			{
				for(std::list<HeeksObj*>::reverse_iterator It2 = new_spans2.rbegin(); It2 != new_spans2.rend(); It2++)
				{
					HeeksObj* s = *It2;
					new_spans.push_back(s);
				}
			}
			else
			{
				for(std::list<HeeksObj*>::iterator It2 = new_spans2.begin(); It2 != new_spans2.end(); It2++)
				{
					HeeksObj* s = *It2;
					new_spans.push_back(s);
				}
			}
		}
		else
		{
			new_spans.push_back(span->MakeACopy());
		}
	}

	for(std::list<HeeksObj*>::iterator It = new_spans.begin(); It != new_spans.end(); It++)
	{
		HeeksObj* span_object = *It;
		double s[3] = {0, 0, 0};
		double e[3] = {0, 0, 0};
		double c[3] = {0, 0, 0};


		if(span_object){
			int type = span_object->GetType();
			if(type == LineType || type == ArcType || type == CircleType)
			{
				if(!started && type != CircleType)
				{
					if(reversed)span_object->GetEndPoint(s);
					else span_object->GetStartPoint(s);
					CNCPoint start(s);

					python << _T("curve.append(area.Point(");
					python << start.X(true);
					python << _T(", ");
					python << start.Y(true);
					python << _T("))\n");
					started = true;
				}
				if(reversed)span_object->GetStartPoint(e);
				else span_object->GetEndPoint(e);
				CNCPoint end(e);

				if(type == LineType)
				{
					python << _T("curve.append(area.Point(");
					python << end.X(true);
					python << _T(", ");
					python << end.Y(true);
					python << _T("))\n");
				}
				else if(type == ArcType)
				{
					span_object->GetCentrePoint(c);
					CNCPoint centre(c);

					double pos[3];
					heeksCAD->GetArcAxis(span_object, pos);
					int span_type = ((pos[2] >=0) != reversed) ? 1: -1;
					python << _T("curve.append(area.Vertex(");
					python << (span_type);
					python << (_T(", area.Point("));
					python << end.X(true);
					python << (_T(", "));
					python << end.Y(true);
					python << (_T("), area.Point("));
					python << centre.X(true);
					python << (_T(", "));
					python << centre.Y(true);
					python << (_T(")))\n"));
				}
				else if(type == CircleType)
				{
					std::list< std::pair<int, gp_Pnt > > points;
					span_object->GetCentrePoint(c);

					double radius = heeksCAD->CircleGetRadius(span_object);

					// Setup the four arcs to make up the full circle using UNadjusted
					// coordinates.  We do this so that the offsets are expressed along the
					// X and Y axes.  We will adjust the resultant points later.

					// The kurve code needs a start point first.
					points.push_back( std::make_pair(0, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north
					if(reversed)
					{
						points.push_back( std::make_pair(1, gp_Pnt( c[0] - radius, c[1], c[2] )) ); // west
						points.push_back( std::make_pair(1, gp_Pnt( c[0], c[1] - radius, c[2] )) ); // south
						points.push_back( std::make_pair(1, gp_Pnt( c[0] + radius, c[1], c[2] )) ); // east
						points.push_back( std::make_pair(1, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north
					}
					else
					{
						points.push_back( std::make_pair(-1, gp_Pnt( c[0] + radius, c[1], c[2] )) ); // east
						points.push_back( std::make_pair(-1, gp_Pnt( c[0], c[1] - radius, c[2] )) ); // south
						points.push_back( std::make_pair(-1, gp_Pnt( c[0] - radius, c[1], c[2] )) ); // west
						points.push_back( std::make_pair(-1, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north
					}

					CNCPoint centre(c);

					for (std::list< std::pair<int, gp_Pnt > >::iterator l_itPoint = points.begin(); l_itPoint != points.end(); l_itPoint++)
					{
						CNCPoint pnt( l_itPoint->second );

						python << (_T("curve.append(area.Vertex("));
						python << l_itPoint->first << _T(", area.Point(");
						python << pnt.X(true);
						python << (_T(", "));
						python << pnt.Y(true);
						python << (_T("), area.Point("));
						python << centre.X(true);
						python << (_T(", "));
						python << centre.Y(true);
						python << (_T(")))\n"));
					} // End for
				}
			}
		}
	}

	// delete the spans made
	for(std::list<HeeksObj*>::iterator It = new_spans.begin(); It != new_spans.end(); It++)
	{
		HeeksObj* span = *It;
		delete span;
	}

	python << _T("\n");

	if(m_profile_params.m_start_given || m_profile_params.m_end_given)
	{
		double startx, starty, finishx, finishy;

		wxString start_string;
		if(m_profile_params.m_start_given)
		{
#ifdef UNICODE
			std::wostringstream ss;
#else
			std::ostringstream ss;
#endif

			gp_Pnt starting(m_profile_params.m_start[0] / theApp.m_program->m_units,
					m_profile_params.m_start[1] / theApp.m_program->m_units,
					0.0 );

			startx = starting.X();
			starty = starting.Y();

			ss.imbue(std::locale("C"));
			ss<<std::setprecision(10);
			ss << ", start = area.Point(" << startx << ", " << starty << ")";
			start_string = ss.str().c_str();
		}


		wxString finish_string;
		wxString beyond_string;
		if(m_profile_params.m_end_given)
		{
#ifdef UNICODE
			std::wostringstream ss;
#else
			std::ostringstream ss;
#endif

			gp_Pnt finish(m_profile_params.m_end[0] / theApp.m_program->m_units,
					m_profile_params.m_end[1] / theApp.m_program->m_units,
					0.0 );

			finishx = finish.X();
			finishy = finish.Y();

			ss.imbue(std::locale("C"));
			ss<<std::setprecision(10);
			ss << ", finish = area.Point(" << finishx << ", " << finishy << ")";
			finish_string = ss.str().c_str();

			if(m_profile_params.m_end_beyond_full_profile)beyond_string = _T(", end_beyond = True");
		}

		python << (wxString::Format(_T("kurve_funcs.make_smaller( curve%s%s%s)\n"), start_string.c_str(), finish_string.c_str(), beyond_string.c_str())).c_str();
	}

	return(python);
}
예제 #15
0
//===========================================================================
void SplineUtils::closest_on_rectgrid(const double* pt, const double* array,
			 int m, int n,
			 double& clo_u, double& clo_v)
//===========================================================================
{
    // m is number of columns
    // n is number of rows
    // in array, the column index runs fastest.

    // For each (not necessarily planar) quadrangle, split into 2
    // triangles. Then find distance to triangle, and closest point
    // in triangle.

    Vector3D pnt(pt);
    Vector3D p[4];
    Vector3D tri[3];

    Vector3D umask1(0, 1, 0);
    Vector3D umask2(1, 1, 0);
    Vector3D vmask1(0, 0, 1);
    Vector3D vmask2(0, 1, 1);

    double bestdist2 = 1e100;
    double best_u = 0;
    double best_v = 0;

    for (int col = 0; col < m-1; ++col) {
	for (int row = 0; row < n-1; ++row) {
	    // Pick the corner points counterclockwise
	    p[0].setValue(array + (row*m + col)*3);
	    p[1].setValue(array + (row*m + col+1)*3);
	    p[2].setValue(array + ((row+1)*m + col+1)*3);
	    p[3].setValue(array + ((row+1)*m + col)*3);
	    // Lower triangle, points 0, 1, 3.
	    tri[0] = p[0];
	    tri[1] = p[1];
	    tri[2] = p[3];
	    double clo_dist2;
	    Vector3D cltri = SplineUtils::closest_on_triangle(pnt, tri, clo_dist2);
	    if (clo_dist2 < bestdist2) {
		best_u = col + umask1*cltri;
		best_v = row + vmask1*cltri;
		bestdist2 = clo_dist2;
	    }
	    // Upper triangle, points 1, 2, 3.
	    tri[0] = p[1];
	    tri[1] = p[2];
	    tri[2] = p[3];
	    cltri = SplineUtils::closest_on_triangle(pnt, tri, clo_dist2);
	    if (clo_dist2 < bestdist2) {
		best_u = col + umask2*cltri;
		best_v = row + vmask2*cltri;
		bestdist2 = clo_dist2;
	    }
	}
    }
    clo_u = best_u;
    clo_v = best_v;
    int i = int(floor(clo_u));
    if (i >= m-1)
	i = m-2;
    int j = int(floor(clo_v));
    if (j >= n-1)
	j = n-2;
    p[0].setValue(array + (j*m + i)*3);
    p[1].setValue(array + (j*m + i+1)*3);
    p[2].setValue(array + ((j+1)*m + i+1)*3);
    p[3].setValue(array + ((j+1)*m + i)*3);
}
예제 #16
0
파일: Path.C 프로젝트: 99731/GoTools
//==========================================================================
bool Path::estimateHoleInfo(vector<ftEdge*> edges, Point& centre, 
			    Point& axis, double& radius)
//==========================================================================
{
  centre.resize(edges[0]->geomCurve()->dimension());
  centre.setValue(0.0);

  // Select four points
  // First make parameterization
  vector<double> parval(edges.size()+1);
  vector<double> edgelen(edges.size()+1);
  parval[0] = 0.0;
  edgelen[0] = 0.0;
  size_t ki;
  for (ki=0; ki<edges.size(); ++ki)
    {
      double tdel = edges[ki]->tMax() - edges[ki]->tMin();
      double len = edges[ki]->estimatedCurveLength();
      parval[ki+1] = parval[ki]+tdel;
      edgelen[ki+1] = edgelen[ki] + len;
      centre += edges[ki]->point(edges[ki]->tMin());
    }
  int nmb_vx = (int)edges.size();
  if (edges[edges.size()-1]->next() != edges[0])
    {
      centre += edges[edges.size()-1]->point(edges[edges.size()-1]->tMax());
      nmb_vx++;
    }
  centre /= nmb_vx;

  vector<Point> pnt(4);
  int kj;
  //double tdel = (parval[parval.size()-1] - parval[0])/(double)4;
  double del = (edgelen[edgelen.size()-1] - edgelen[0])/(double)4;
  double tpar, len;
  for (kj=0, len=edgelen[0]+0.5*del; kj<4; ++kj, len+=del)
    {
      for (ki=0; ki<edgelen.size()-1; ++ki)
	if (len < edgelen[ki+1])
	  break;

      double frac = (len - edgelen[ki])/(edgelen[ki+1] - edgelen[ki]);
      tpar = parval[ki] + frac*(parval[ki+1]-parval[ki]);

      pnt[kj] = edges[ki]->point(edges[ki]->tMin() + tpar - parval[ki]);
    }

  Point centre2 = 0.25*(pnt[0] + pnt[1] + pnt[2] + pnt[3]);

  // std::ofstream of("hole_pts.g2");
  // of << "400 1 0 4 0 155 100 255" << std::endl;
  // of << pnt.size() << std::endl;
  // for (ki=0; ki<pnt.size(); ++ki)
  //   of << pnt[ki] << std::endl;
  // of << "400 1 0 4 255 0 0 255" << std::endl;
  // of << "1" << std::endl;
  // of << centre << std::endl;
  // of << "400 1 0 4 0 255 0 255" << std::endl;
  // of << "1" << std::endl;
  // of << centre2 << std::endl;

  centre = centre2;
  //axis = (pnt[1] - pnt[0]).cross(pnt[3] - pnt[2]);
  axis = (pnt[2] - pnt[0]).cross(pnt[3] - pnt[1]);
  double axlen = axis.length();
  double lentol = 1.0e-10;
  if (axlen < lentol)
    return false;

  axis.normalize();
  
  Point x1 = 0.5*(pnt[0] + pnt[1]);
  Point x2 = 0.5*(pnt[1] + pnt[2]);

  Point d1 = (pnt[1]-pnt[0]).cross(axis);
  d1.normalize();
  Point d2 = (pnt[2]-pnt[1]).cross(axis);
  d2.normalize();

  Point tmp1 = x1 + d1;
  Point tmp2 = x2 + d2;

  //double d1d2 = d1*d2;
  //double tdiv = 1.0 - d1d2*d1d2;
  //double t1 = (-x1*d1 + x2*d1 + d1d2*x1*d2 - d1d2*x2*d2)/tdiv;

  //centre = x1 + t1*d1;
  radius = (centre - pnt[0]).length();

//   // Adjust radius relative to bounding box
//   vector<Point> pos;
//   pos.insert(pos.end(), pnt.begin(), pnt.end());
//   for (ki=0; ki<edges.size(); ++ki)
//     {
//       pos.push_back(edges[ki]->point(edges[ki]->tMin()));
//       pos.push_back(edges[ki]->point(edges[ki]->tMax()));
//     }

//   BoundingBox box;
//   box.setFromPoints(pos);
//   double len = box.high().dist(box.low());
//   radius = std::min(radius, 0.5*len);
  return true;
}
예제 #17
0
int main(int argc, char **argv)
{
//    enableFPE();

#ifdef __sgi 	
	signal(SIGSEGV, (void (*)(int))sighand);
	signal(SIGTRAP, (void (*)(int))sighand);
	signal(SIGBUS, (void (*)(int))sighand);
#endif
   
    // OSG init
    osgInit(argc,argv);

    if (argc > 1 && ! strcmp(argv[1],"-bench"))
    {
        runBench = true;
        argc--;
        argv++;
        glutInitWindowPosition(0,0);
        glutInitWindowSize(600,600);
    }

    if (argc > 1 && ! strcmp(argv[1],"-test"))
    {
        testSet = true;
        doMotion = false;
        argc--;
        argv++;
    }

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    GLUTWindowPtr gwin= GLUTWindow::create();
    gwin->setId(winid);
    gwin->init();

    // create the scene
    NodePtr scene = Node::create();    
    NodePtr pnode = Node::create();
    
    ComponentTransformPtr trans = ComponentTransform::create();
    beginEditCP(scene);
    scene->setCore(trans);
    scene->addChild(pnode);
    endEditCP(scene);
    
    beginEditCP(trans);
    trans->setTranslation(Vec3f(2,0,0));
    trans->setRotation(Quaternion(Vec3f(0,1,0),Pi/2));
    trans->setScale(Vec3f(2,2,2));
    endEditCP(trans);
    
    
    particles = Particles::create();
    beginEditCP(pnode);
    pnode->setCore(particles);
    endEditCP(pnode);

    numParticles = 100;
    
    if (argc > 1)
    {
        numParticles=atoi(argv[1]);
    }
    
    beginEditCP(particles);

    pnts=GeoPositions3f::create();
    secpnts=GeoPositions3f::create();
    
    addRefCP(pnts);
    addRefCP(secpnts);
    
    GeoColors3fPtr  cols  = GeoColors3f::create();
    GeoNormals3fPtr norms = GeoNormals3f::create();

    MFPnt3f* p=pnts->editFieldPtr();
    MFPnt3f* sp=secpnts->editFieldPtr();
    MFVec3f *size=particles->editMFSizes();

    indices = particles->editMFIndices();
    
    velocities=new Vec3f [numParticles];
    
    beginEditCP(pnts);
    beginEditCP(secpnts);
    beginEditCP(cols);
    if(!testSet)
    {
        for(UInt32 i=0; i < numParticles; ++i)
        {
            Pnt3f pnt(osgrand(),osgrand(),osgrand());
            indices->push_back(i);  
            p->push_back(pnt);  
            sp->push_back(pnt);  
            velocities[i].setValues(osgrand()/30.f/2, osgrand()/30.f/2, osgrand()/30.f/2);
            cols->editFieldPtr()->push_back( 
                Color3f(osgrand()/2.f + .5f,osgrand()/2.f + .5f,osgrand()/2.f + .5f) );
            size->push_back(
                Vec3f(osgrand()/20.f+0.05,osgrand()/20.f+0.05,osgrand()/20.f+0.05));
        }
    }
    else
    {
        Pnt3f   tpos[] = 
        { Pnt3f(.5,.5,.5), Pnt3f (.5,.5,.7), Pnt3f(.5,.5,.9), Pnt3f(.7,.5,.5), 
          Pnt3f(.5,.7,.5), Pnt3f (-1000,-1000,-1000) };
        
        Pnt3f   tsecpos[] = 
        { Pnt3f(0,0,0), Pnt3f(0,0,0), Pnt3f(0,0,0), Pnt3f(0,0,0), 
          Pnt3f(0,0,0) };
        
        Vec3f   tvel[] = 
        { Vec3f(0,0,0), Vec3f(0,0,0), Vec3f(0,0,0), Vec3f(0,0,0), 
          Vec3f(0,0,0) };
        
        Color3f tcol[] = 
        { Color3f(1,0,0), Color3f(0,1,0), Color3f(0,0,1), Color3f(1,1,0), 
          Color3f(1,0,1), Color3f(0,1,1), Color3f(1,1,1) };
        
        Vec3f   tsize[] = 
        { Vec3f(.1,0,0), Vec3f(.1,0,0), Vec3f(.1,0,0), Vec3f(.1,0,0), 
          Vec3f(.1,0,0) };

        for(UInt32 i=0; tpos[i][0] > -1000; ++i)
        {
            indices->push_back(i);  
            p->push_back(tpos[i]);  
            sp->push_back(tsecpos[i]);  
            velocities[i].setValue(tvel[i]);
            cols->editFieldPtr()->push_back(tcol[i]);
            size->push_back(tsize[i]);
        }
       
    }
    endEditCP(pnts);
    endEditCP(secpnts);
    endEditCP(cols);

    beginEditCP(norms);
    norms->push_back(Vec3f(0,1,0));
    endEditCP(norms);

    particles->setPositions( pnts );
    particles->setSecPositions( secpnts );
    particles->setColors( cols );
    particles->setNormals( norms );
                    
    endEditCP(particles);
 
    // set volume static to prevent constant update
    beginEditCP(pnode, Node::VolumeFieldMask);
#ifndef OSG_2_PREP
    Volume &v = pnode->editVolume(false).getInstance();
#else
    Volume &v = pnode->editVolume(false);
#endif
    v.setEmpty();
    v.extendBy(Pnt3f(0,0,0));
    v.extendBy(Pnt3f(1,1,1));
    v.setStatic();
#ifndef OSG_2_PREP
    pnode->editVolume(false).instanceChanged();
#endif
    endEditCP  (pnode, Node::VolumeFieldMask);
  
    SimpleTexturedMaterialPtr tm;

    tm = SimpleTexturedMaterial::create();

    UChar8 imgdata[] =
        {  255,255,255,  255,0,0,  255,0,255,
           255,0,0,  255,0,0,  255,255,255 };
    ImagePtr pImage = Image::create();

    if (argc > 2)
    {
        pImage->read(argv[2]);
    }
    else
    {
        pImage->set(Image::OSG_RGB_PF, 3, 2, 1, 1, 1, 0, imgdata);
    }
    
    beginEditCP(tm);
    tm->setDiffuse( Color3f( 1,1,1 ) );
    tm->setLit( false );

    tm->setImage( pImage );
    tm->setEnvMode( GL_MODULATE );
    
    BlendChunkPtr bl=BlendChunk::create();
    
    beginEditCP(bl);
    bl->setSrcFactor(GL_SRC_ALPHA);
    //bl->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
    bl->setDestFactor(GL_ONE);
#if 0
    bl->setAlphaFunc(GL_EQUAL);
    bl->setAlphaValue(1);   
#endif
    endEditCP(bl);
   
    tm->addChunk(bl);
    
    endEditCP(tm);

    particles->setMaterial( tm );

#if 0
    // write it, just for testing

    std::ofstream out("test.osg");
    OSGWriter w(out);
    
    w.write(scene);
    
#endif

    // create the SimpleSceneManager helper
    mgr = new SimpleSceneManager;

    // tell the manager what to manage
    mgr->setWindow(gwin );
    mgr->setRoot  (scene);

    // show the whole scene
    mgr->showAll();

    //mgr->setHighlight(scene);
    
    // GLUT main loop
    glutMainLoop();

    return 0;
}
예제 #18
0
CPoint2D CPoint2D::operator+(const CPoint2D& other) const
{ 
	CPoint2D pnt(m_X + other.m_X, m_Y + other.m_Y); 
	
	return pnt;
}
예제 #19
0
void ImageOfSphere::AddPixel(real32 x,real32 y)
{
 bs::Pnt pnt(x,y);
 edge.AddBack(pnt);
}
예제 #20
0
int tri_mesh::swap(int sind, FLT tol) {
	int j,t1,t2,s1p,s2p,snum1,snum2,tind,sind1,p0,p1,vt1,vt2,dir;

	t1 = seg(sind).tri(0);
	t2 = seg(sind).tri(1);

	if (t1 < 0 || t2 < 0) return(0);

	for(snum1 = 0; snum1 < 3; ++snum1)
		if (tri(t1).seg(snum1) == sind) break;

	for(snum2 = 0; snum2 < 3; ++snum2)
		if (tri(t2).seg(snum2) == sind) break;

	p0 = seg(sind).pnt(0);
	p1 = seg(sind).pnt(1);
	vt1 = tri(t1).pnt(snum1);
	vt2 = tri(t2).pnt(snum2);

	if (MIN(minangle(p0,p1,vt1),minangle(p1,p0,vt2)) >
		MIN(minangle(vt2,vt1,p0),minangle(vt1,vt2,p1)) -tol -10.0*EPSILON) return(0);

	/* MARK TOUCHED */
	tri(sind).info |= STOUC;
	tri(t1).info |= TTOUC;
	tri(t2).info |= TTOUC;

	/* SWAP SIDE */
	seg(sind).pnt(0) = vt2;
	seg(sind).pnt(1) = vt1;

	/* KEEP 2/3 POINTS IN SAME SPOT */
	tri(t1).pnt((snum1 +2)%3) = vt2;
	tri(t2).pnt((snum2 +2)%3) = vt1;

	s1p = (snum1 +1)%3;
	s2p = (snum2 +1)%3;

	/* FIX 2 CHANGED EXTERIOR SIDES */
	tri(t1).seg(snum1) = tri(t2).seg(s2p);
	tri(t1).sgn(snum1) = tri(t2).sgn(s2p);
	tri(t1).tri(snum1) = tri(t2).tri(s2p);

	tri(t2).seg(snum2) = tri(t1).seg(s1p);
	tri(t2).sgn(snum2) = tri(t1).sgn(s1p);
	tri(t2).tri(snum2) = tri(t1).tri(s1p);

	/* FIX STRI/TTRI FOR 2 CHANGED EXTERIOR SIDES */
	sind1 = tri(t1).seg(snum1);
	dir = (1 -tri(t1).sgn(snum1))/2;
	seg(sind1).tri(dir) = t1;
	tind = tri(t1).tri(snum1);
	if (tind > -1) {
		for(j=0;j<3;++j)
			if (tri(tind).seg(j) == sind1) break;
		tri(tind).tri(j) = t1;
	}

	sind1 = tri(t2).seg(snum2);
	dir = (1 -tri(t2).sgn(snum2))/2;
	seg(sind1).tri(dir) = t2;
	tind = tri(t2).tri(snum2);
	if (tind > -1) {
		for(j=0;j<3;++j)
			if (tri(tind).seg(j) == sind1) break;
		tri(tind).tri(j) = t2;
	}

	pnt(p0).tri = t1;
	pnt(p1).tri = t2;

	tri(t1).tri(s1p) = t2;
	tri(t2).tri(s2p) = t1;

	tri(t1).seg(s1p) = sind;
	tri(t2).seg(s2p) = sind;
	tri(t1).sgn(s1p) =  1;
	tri(t2).sgn(s2p) = -1;

#ifdef DEBUG_ADAPT
		std::ostringstream nstr;
		nstr << adapt_count++ << std::flush;
		adapt_file = "adapt" +nstr.str();
		nstr.str("");
		output(adapt_file,debug_adapt);
#endif

	return(1);
}
예제 #21
0
void MapGraphicsView::scanFinished(QList<WifiDataResult> results)
{
    int fontSize = 10;// * (1/m_scaleFactor);
#ifdef Q_OS_ANDROID
    fontSize = 5;
#endif

    int margin = fontSize/2;
    int y = margin;
    int lineJump = (int)(fontSize * 1.33);

#ifdef Q_OS_ANDROID
    margin = fontSize;
    y = margin;
    lineJump = fontSize * 4;
#endif

    int numLines = results.size();
    if(numLines <= 0)
        numLines = 1; // for a special message

    int imgWidth = 150;
    int imgHeight = numLines * lineJump + margin * 3;

    QImage img(imgWidth, imgHeight, QImage::Format_ARGB32_Premultiplied);
    memset(img.bits(), 0, img.byteCount());
    QPainter p(&img);

    p.fillRect(img.rect(), QColor(0,0,0,150));

    p.setFont(QFont("Monospace", fontSize, QFont::Bold));

    QSize historySize(
        //(int)(imgWidth - margin * 2),
        margin * 4,
        (int)(lineJump - 4.));

    foreach(WifiDataResult result, results)
    {
        if(!m_apSigHist.contains(result.mac))
            m_apSigHist.insert(result.mac, new MapSignalHistory(m_gs->baseColorForAp(result.mac)));

        MapSignalHistory *hist = m_apSigHist.value(result.mac);
        hist->addValue(result.value);

        QColor color = m_gs->colorForSignal(1.0, result.mac).lighter(100);
#ifdef Q_OS_ANDROID
        color = color.darker(300);
#endif
        QColor outline = Qt::white; //qGray(color.rgb()) < 60 ? Qt::white : Qt::black;
        QPoint pnt(QPoint(
                       margin/2 + historySize.width(),
                       y += lineJump));
        qDrawTextC(p, pnt.x(), pnt.y(),
                   QString( "%1% %2"  )
                   .arg(QString().sprintf("%02d", (int)round(result.value * 100.)))
                   .arg(result.essid),
                   outline,
                   color);

        p.setOpacity(0.80);
        p.drawImage(
            QPoint(
                0 /*margin*/,
                (int)(y - lineJump * .75)
            ),
            hist->renderGraph(historySize)
            .mirrored(true,false)
        );

        p.setOpacity(1.0);
    }

    if(results.size() <= 0)
    {
        qDrawTextC(p, margin, margin + margin + p.font().pointSize() * 2, tr("No APs nearby or WiFi off"), Qt::red, Qt::white);
    }

    // Draw border on top of any text that may overflow
    p.setPen(Qt::black);
    p.drawRect(img.rect().adjusted(0,0,-1,-1));

// 	qDebug() << "MapGraphicsView::scanFinished(): Rendered "<<img.size()<<" size HUD";
// 	img.save("hud.png");

    p.end();
    m_hudLabel->setPixmap(QPixmap::fromImage(img));
    //updateViewportLayout();

}
예제 #22
0
void CardViewItem::showFullString( const QPoint &itempos, CardViewTip *tip )
{
  bool trimmed( false );
  QString s;
  int mrg = mView->itemMargin();
  int y = mView->d->mBFm->height() + 6 + mrg;
  int w = mView->itemWidth() - (2 * mrg);
  int lw;
  bool drawLabels = mView->drawFieldLabels();
  bool isLabel = drawLabels && itempos.x() < w / 2 ? true : false;

  if ( itempos.y() < y ) {
    if ( itempos.y() < 8 + mrg || itempos.y() > y - 4 )
      return;
    // this is the caption
    s = caption();
    trimmed = mView->d->mBFm->width( s ) > w - 4;
    y = 2 + mrg;
    lw = 0;
    isLabel = true;
  } else {
    // find the field
    Field *f = fieldAt( itempos );
    if ( !f || ( !mView->showEmptyFields() && f->second.isEmpty() ) )
      return;

    // y position:
    // header font height + 4px hader margin + 2px leading + item margin
    // + actual field index * (fontheight + 2px leading)
    int maxLines = mView->maxFieldLines();
    bool se = mView->showEmptyFields();
    int fh = mView->d->mFm->height();

    Field *_f;
    for ( _f = d->mFieldList.first(); _f != f; _f = d->mFieldList.next() )
      if ( se || ! _f->second.isEmpty() )
        y += ( qMin( _f->second.count( '\n' ) + 1, maxLines ) * fh ) + 2;

    if ( isLabel && itempos.y() > y + fh )
      return;

    s = isLabel ? f->first : f->second;

    int colonWidth = mView->d->mFm->width(":");
    lw = drawLabels ? qMin( w / 2 - 4 - mrg, d->maxLabelWidth + colonWidth + 4 ) : 0;
    int mw = isLabel ? lw - colonWidth : w - lw - ( mrg * 2 );
    if ( isLabel ) {
      trimmed = mView->d->mFm->width( s ) > mw - colonWidth;
    } else {
      QRect r( mView->d->mFm->boundingRect( 0, 0, INT_MAX, INT_MAX, Qt::AlignTop|Qt::AlignLeft, s ) );
      trimmed = r.width() > mw || r.height() / fh >  qMin( s.count( '\n' ) + 1, maxLines );
    }
  }

  if ( trimmed ) {
    tip->setFont( (isLabel && !lw) ? mView->headerFont() : mView->font() );
    tip->setText( s );
    tip->adjustSize();
    // find a proper position
    int lx;
    lx = isLabel || !drawLabels ? mrg : lw + mrg + 2;
    QPoint pnt( mView->contentsToViewport( QPoint( d->x, d->y ) ) );
    pnt += QPoint( lx, y );
    if ( pnt.x() < 0 )
      pnt.setX( 0 );
    if ( pnt.x() + tip->width() > mView->visibleWidth() )
      pnt.setX( mView->visibleWidth() - tip->width() );
    if ( pnt.y() + tip->height() > mView->visibleHeight() )
      pnt.setY( qMax( 0, mView->visibleHeight() - tip->height() ) );
    // show
    tip->move( pnt );
    tip->show();
  }
}
예제 #23
0
void tri_hp_ps::length() {
	int i,j,k,v0,v1,v2,indx,sind,tind,count;
	TinyVector<FLT,2> dx0,dx1,dx2,ep,dedpsi;
	FLT q,p,duv,um,vm,u,v;
	FLT sum,ruv,ratio;
	FLT length0,length1,length2,lengthept;
	FLT ang1,curved1,ang2,curved2;
	FLT norm;


	gbl->eanda = 0.0;
	for(tind=0;tind<ntri;++tind) {
		q = 0.0;
		p = 0.0;
		duv = 0.0;
		um = ug.v(tri(tind).pnt(2),0);
		vm = ug.v(tri(tind).pnt(2),1);
		for(j=0;j<3;++j) {
			v0 = tri(tind).pnt(j);
			p += fabs(ug.v(v0,2));
			duv += fabs(u-um)+fabs(v-vm);
		}
		gbl->eanda(0) += 1./3.*(p*area(tind) +duv*gbl->mu*sqrt(area(tind)) );
		gbl->eanda(1) += area(tind);
	}
	sim::blks.allreduce(gbl->eanda.data(),gbl->eanda_recv.data(),2,blocks::flt_msg,blocks::sum);
	norm = gbl->eanda_recv(0)/gbl->eanda_recv(1);
	gbl->fltwk(Range(0,npnt-1)) = 0.0;

	switch(basis::tri(log2p)->p()) {
		case(1): {
			for(i=0;i<nseg;++i) {
				v0 = seg(i).pnt(0);
				v1 = seg(i).pnt(1);
				ruv = gbl->mu/distance(v0,v1);
				sum = distance2(v0,v1)*(ruv*(fabs(ug.v(v0,0) -ug.v(v1,0)) +fabs(ug.v(v0,1) -ug.v(v1,1))) +fabs(ug.v(v0,2) -ug.v(v1,2)));
				gbl->fltwk(v0) += sum;
				gbl->fltwk(v1) += sum;
			}                            
			break;
		}

		default: {
			indx = basis::tri(log2p)->sm()-1;
			for(i=0;i<nseg;++i) {
				v0 = seg(i).pnt(0);
				v1 = seg(i).pnt(1);
				ruv = +gbl->mu/distance(v0,v1);
				sum = distance2(v0,v1)*(ruv*(fabs(ug.s(i,indx,0)) +fabs(ug.s(i,indx,1))) +fabs(ug.s(i,indx,2)));
				gbl->fltwk(v0) += sum;
				gbl->fltwk(v1) += sum;
			}

			/* BOUNDARY CURVATURE */
			for(i=0;i<nebd;++i) {
				if (!(hp_ebdry(i)->is_curved())) continue;

				for(j=0;j<ebdry(i)->nseg;++j) {
					sind = ebdry(i)->seg(j);
					v1 = seg(sind).pnt(0);
					v2 = seg(sind).pnt(1);

					crdtocht1d(sind);

					/* FIND ANGLE BETWEEN LINEAR SIDES */
					tind = seg(sind).tri(0);
					for(k=0;k<3;++k)
						if (tri(tind).seg(k) == sind) break;

					v0 = tri(tind).pnt(k);

					dx0(0) = pnts(v2)(0)-pnts(v1)(0);
					dx0(1) = pnts(v2)(1)-pnts(v1)(1);
					length0 = dx0(0)*dx0(0) +dx0(1)*dx0(1);

					dx1(0) = pnts(v0)(0)-pnts(v2)(0);
					dx1(1) = pnts(v0)(1)-pnts(v2)(1);
					length1 = dx1(0)*dx1(0) +dx1(1)*dx1(1);

					dx2(0) = pnts(v1)(0)-pnts(v0)(0);
					dx2(1) = pnts(v1)(1)-pnts(v0)(1);
					length2 = dx2(0)*dx2(0) +dx2(1)*dx2(1);

					basis::tri(log2p)->ptprobe1d(2,&ep(0),&dedpsi(0),-1.0,&cht(0,0),MXTM);
					lengthept = dedpsi(0)*dedpsi(0) +dedpsi(1)*dedpsi(1);

					ang1 = acos(-(dx0(0)*dx2(0) +dx0(1)*dx2(1))/sqrt(length0*length2));
					curved1 = acos((dx0(0)*dedpsi(0) +dx0(1)*dedpsi(1))/sqrt(length0*lengthept));

					basis::tri(log2p)->ptprobe1d(2,&ep(0),&dedpsi(0),1.0,&cht(0,0),MXTM);
					lengthept = dedpsi(0)*dedpsi(0) +dedpsi(1)*dedpsi(1);

					ang2 = acos(-(dx0(0)*dx1(0) +dx0(1)*dx1(1))/sqrt(length0*length1));
					curved2 = acos((dx0(0)*dedpsi(0) +dx0(1)*dedpsi(1))/sqrt(length0*lengthept));                            

					sum = gbl->curvature_sensitivity*(curved1/ang1 +curved2/ang2);
					gbl->fltwk(v0) += sum*gbl->error_target*norm*pnt(v0).nnbor;
					gbl->fltwk(v1) += sum*gbl->error_target*norm*pnt(v1).nnbor;
				}
			}
			break;
		}
	}

	for(i=0;i<npnt;++i) {
		gbl->fltwk(i) = pow(gbl->fltwk(i)/(norm*pnt(i).nnbor*gbl->error_target),1./(basis::tri(log2p)->p()+1+ND));
		lngth(i) /= gbl->fltwk(i);        
	}

	/* AVOID HIGH ASPECT RATIOS */
	int nsweep = 0;
	do {
		count = 0;
		for(i=0;i<nseg;++i) {
			v0 = seg(i).pnt(0);
			v1 = seg(i).pnt(1);
			ratio = lngth(v1)/lngth(v0);

			if (ratio > 3.0) {
				lngth(v1) = 2.5*lngth(v0);
				++count;
			}
			else if (ratio < 0.333) {
				lngth(v0) = 2.5*lngth(v1);
				++count;
			}
		}
		++nsweep;
		*gbl->log << "#aspect ratio fixes " << nsweep << ' ' << count << std::endl;
	} while(count > 0 && nsweep < 5);

	return;
}