Example #1
0
bool
GlueMapWindow::on_mouse_up(int x, int y)
{
  if (drag_mode != DRAG_NONE)
    release_capture();

  // Ignore single click event if double click detected
  if (ignore_single_click) {
    ignore_single_click = false;
    return true;
  }

  int click_time = mouse_down_clock.elapsed();
  mouse_down_clock.reset();

  enum drag_mode old_drag_mode = drag_mode;
  drag_mode = DRAG_NONE;

  switch (old_drag_mode) {
  case DRAG_NONE:
    break;

  case DRAG_TARGET:
    TargetDragged(drag_last_valid_target.x, drag_last_valid_target.y);
    break;

  case DRAG_PAN:
    /* allow the use of the stretched last buffer for the next two
       redraws */
    scale_buffer = 2;
    return true;

  case DRAG_SIMULATOR:
    if (click_time > 50 &&
        compare_squared(drag_start.x - x, drag_start.y - y,
                        Layout::Scale(36)) == 1) {
      GeoPoint G = visible_projection.Screen2LonLat(x, y);

      double distance = hypot(drag_start.x - x, drag_start.y - y);

      // This drag moves the aircraft (changes speed and direction)
      const Angle oldbearing = Basic().TrackBearing;
      const fixed minspeed = fixed(1.1) * (task != NULL ?
                                           task->get_glide_polar() :
                                           GlidePolar(fixed_zero)).get_Vmin();
      const Angle newbearing = Bearing(drag_start_geopoint, G);
      if (((newbearing - oldbearing).as_delta().magnitude_degrees() < fixed(30)) ||
          (Basic().GroundSpeed < minspeed))
        device_blackboard.SetSpeed(min(fixed(100.0),
                                       max(minspeed,
                                           fixed(distance / (Layout::FastScale(3))))));

      device_blackboard.SetTrackBearing(newbearing);
      // change bearing without changing speed if direction change > 30
      // 20080815 JMW prevent dragging to stop glider

      // JMW trigger recalcs immediately
      TriggerGPSUpdate();
      return true;
    }

    break;

  case DRAG_GESTURE:
    const char* gesture = gestures.Finish();
    if (gesture && on_mouse_gesture(gesture))
      return true;

    break;
  }

  if (!SettingsMap().TargetPan) {
    if(click_time < 1000) {
      // click less then one second -> open nearest waypoint details
      if (way_points != NULL &&
          PopupNearestWaypointDetails(*way_points, drag_start_geopoint,
                                      visible_projection.DistancePixelsToMeters(Layout::Scale(10)),
                                      true))
        return true;
    }
    else {
      // click more then one second -> open nearest airspace details
      if (airspace_database != NULL &&
          AirspaceDetailsAtPoint(drag_start_geopoint))
        return true;
    }
  }

  return false;
}
Example #2
0
template<typename T> T _min(T a, T b, T c) { return min(min(a,b),c); }
Example #3
0
void ZMST::exec() {
  smst.calculateMST();
  //reserve before mass data pushing back
  lines_.reserve(smst.lines().size());
  for (int i = 0; i < (int)smst.lines().size(); i ++)
    lines_.push_back(Line_Z(smst.lines()[i].start(), smst.lines()[i].end(),
                            Point()));
  //lines is a sorted line vector, while smst.lines_ is in father-child order
  sort(lines_.begin(), lines_.end(), lineCmp);
  //make the positive direction table
  int* head = new int[points().size() + 1];
  for (int i = 0, j = 0; i <= (int)points().size() && j <= (int)lines().size(); ) {
    if (j == (int)lines().size() || line(j).start() != i - 1)
      head[i ++] = j;
    else
      j ++;
  }
  //Discretization
  int* father = new int[points().size()],
     * xgrids = new int[points().size()],
     * ygrids = new int[points().size()],
     xgridsize, ygridsize;
  for (int i = 0; i < (int)lines_.size(); i ++) {
    father[lines_[i].end()] = lines_[i].start();
  }
  father[0] = -1;
  for (int i = 0; i < (int)points().size(); i ++) {
    xgrids[i] = point(i).x();
    ygrids[i] = point(i).y();
  }
  sort (xgrids, xgrids + points().size());
  sort (ygrids, ygrids + points().size());
  xgridsize = unique(xgrids, xgrids + points().size()) - xgrids;
  ygridsize = unique(ygrids, ygrids + points().size()) - ygrids;
  vector<vector<layout> > subProb(vector<vector<layout> >(points().size(),
                                                          vector<layout>()));
  //Enumerate all layouts
  for (vector<Line_Z>::iterator it = lines_.begin();
       it != lines_.end(); ++ it) {
    int minx = min(point(it->start()).x(), point(it->end()).x()),
        maxx = max(point(it->start()).x(), point(it->end()).x()),
        miny = min(point(it->start()).y(), point(it->end()).y()),
        maxy = max(point(it->start()).y(), point(it->end()).y());
    int minxid = lower_bound(xgrids, xgrids + xgridsize, minx) - xgrids,
        maxxid = lower_bound(xgrids, xgrids + xgridsize, maxx) - xgrids,
        minyid = lower_bound(ygrids, ygrids + ygridsize, miny) - ygrids,
        maxyid = lower_bound(ygrids, ygrids + ygridsize, maxy) - ygrids;
    for (int i = minxid; i <= maxxid; i ++) {
      subProb[it->end()].push_back(Point(xgrids[i], point(it->start()).y()));
    }
    for (int i = minyid; i <= maxyid; i ++) {
      subProb[it->end()].push_back(Point(point(it->start()).x(), ygrids[i]));
    }
  }
  //Caculate from leaves to root
  int stack[6];
  for (vector<Line>::const_reverse_iterator it = smst.lines().rbegin();
       it != smst.lines().rend(); ++ it) {
    for (vector<layout>::iterator lit = subProb[it->end()].begin();
         lit != subProb[it->end()].end(); ++ lit) {
      dfs(it->end(), father[it->end()], head[it->end()], *lit, lines(),
          subProb, head, stack);
    }
  }
  subProb[0].push_back(point(0));
  dfs(0, 0, head[0], subProb[0][0], lines(), subProb, head, stack);
  getAns(0, subProb[0][0],subProb, head);
  delete []head;
  delete []xgrids;
  delete []ygrids;
  delete []father;
}
Example #4
0
void CBumpWater::UploadCoastline(const int x1, const int y1, const int x2, const int y2)
{
	GLfloat* coastmap=NULL;
	bool usedPBO = false;

	if (pboID) {
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID);
		glBufferData(GL_PIXEL_UNPACK_BUFFER, gs->mapx*gs->mapy*4*4, 0, GL_STREAM_DRAW);
		coastmap = (GLfloat*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
		usedPBO = true;
	}

	if(coastmap == NULL) {
		coastmap = new GLfloat[gs->mapx*gs->mapy*4];
		usedPBO = false;
	}

	/*for (int y = 0; y < gs->mapy; y++) {
		for (int x = 0; x < gs->mapx; x++) {
			float3& normal = readmap->facenormals[(y*gs->mapx+x)*2];
			normalmap[(y*gs->mapx+x)*4]   = normal.x;
			normalmap[(y*gs->mapx+x)*4+1] = normal.y;
			normalmap[(y*gs->mapx+x)*4+2] = normal.z;
			normalmap[(y*gs->mapx+x)*4+3] = 1;
		}
	}*/

	int xmin = max(x1 - 10*2,0);
	int xmax = min(x2 + 10*2,gs->mapx);
	int ymin = max(y1 - 10*2,0);
	int ymax = min(y2 + 10*2,gs->mapy);
	int xsize = xmax - xmin;
	int ysize = ymax - ymin;

	const float* heightMap = readmap->GetHeightmap();
	for (int y = ymin; y < ymax; ++y) {
		int yindex  = y*(gs->mapx + 1);
		int yindex2 = (y-ymin)*xsize;
		for (int x = xmin; x < xmax; ++x) {
			int index  = yindex + x;
			int index2 = (yindex2 + (x-xmin)) << 2;
			const float& height = heightMap[index];
			coastmap[index2]   = (height>0.0f)?1:0;
			coastmap[index2+1] = (height>0.0f)?1:0;
			coastmap[index2+2] = (height>0.0f)?1:0;
			coastmap[index2+3] = height;
		}
	}


	if (usedPBO) {
		glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
		glBindTexture(GL_TEXTURE_2D, coastTexture[1]);
		glTexSubImage2D(GL_TEXTURE_2D, 0, xmin, ymin, xsize,ysize, GL_RGBA, GL_FLOAT, 0);
		glBufferData(GL_PIXEL_UNPACK_BUFFER, 0, 0, GL_STREAM_DRAW); //free it
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
	}else{
		glBindTexture(GL_TEXTURE_2D, coastTexture[1]);
		glTexSubImage2D(GL_TEXTURE_2D, 0, xmin, ymin, xsize,ysize, GL_RGBA, GL_FLOAT, coastmap);
		delete[] coastmap;
	}
}
Example #5
0
int main( int argc, char *argv[] ) {
	using std::auto_ptr;
	using std::exception;
	using std::ofstream;
	using std::cout;
	using std::cerr;
	using std::endl;
	using std::setprecision;
	using std::setiosflags;
	using std::ios;
	using std::min;
	using boost::timer;

	auto_ptr<Voronoi::StipplingParameters> parameters;
	
	try {
		parameters = parseArguments( argc, argv );
		if (parameters.get() == NULL) {
			return 0;
		}
	} catch ( exception e ) {
		return -1;
	}

	STIPPLER_HANDLE stippler;

	ofstream log;
	if ( parameters->createLogs ) {
		log.open( "log.txt" );
	}

	try {
		stippler = create_stippler( parameters.get() );
	} catch ( exception e ) {
		delete[] parameters.get()->inputFile;
		cerr << e.what() << endl;

		return -1;
	}

	write_configuration( cout, *(parameters.get()) );
	if ( parameters->createLogs ) {
		write_configuration( log, *(parameters.get()) );
	}

	int iteration = 0;
	float t = parameters->threshold + 1.0f;
	do {
		timer profiler;

		stippler_distribute(stippler);

		if ( parameters->createLogs ) {
			log << "Iteration " << (++iteration) << " completed in " << profiler.elapsed() << " seconds." << endl;
			cout << "Iteration " << iteration << " completed in " << profiler.elapsed() << " seconds." << endl;
		}

		t = stippler_getAverageDisplacement( stippler );

		if ( parameters->createLogs ) {
			log << "Current Displacement: " << t << endl;
			cout << "Current Displacement: " << t << endl;
		}

		cout << setiosflags(ios::fixed) << setprecision(2) << min((parameters->threshold / t * 100), 100.0f) << "% Complete" << endl; 
	} while ( t > parameters->threshold );

	// render final result to SVG
	try {
		render( stippler, *(parameters.get()) );
	} catch (exception e) {
		cerr << e.what();
	}

	delete[] parameters.get()->inputFile;

	if ( parameters->createLogs ) {
		log.close();
	}

	destroy_stippler( stippler );

	return 0;
}
void	
TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
                             int lx, int ly)
{
    try
    {
        Lock lock (*_streamData);

        if (_data->slices.size() == 0)
	    throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
			       "as pixel data source.");

	if (!isValidTile (dx1, dy1, lx, ly) || !isValidTile (dx2, dy2, lx, ly))
	    throw IEX_NAMESPACE::ArgExc ("Tile coordinates are invalid.");

	if (!isValidLevel (lx, ly))
	    THROW (IEX_NAMESPACE::ArgExc,
                   "Level coordinate "
                   "(" << lx << ", " << ly << ") "
                   "is invalid.");
        //
        // Determine the first and last tile coordinates in both dimensions
        // based on the file's lineOrder
        //
                               
        if (dx1 > dx2)
            swap (dx1, dx2);
        
        if (dy1 > dy2)
            swap (dy1, dy2);
        
        int dyStart = dy1;
	int dyStop  = dy2 + 1;
	int dY      = 1;
    
        if (_data->lineOrder == DECREASING_Y)
        {
            dyStart = dy2;
            dyStop  = dy1 - 1;
            dY      = -1;
        }
        
        int numTiles = (dx2 - dx1 + 1) * (dy2 - dy1 + 1);
        int numTasks = min ((int)_data->tileBuffers.size(), numTiles);

        //
        // Create a task group for all tile buffer tasks.  When the
	// task group goes out of scope, the destructor waits until
	// all tasks are complete.
        //

        {
            TaskGroup taskGroup;
    
            //
            // Add in the initial compression tasks to the thread pool
            //
    
            int nextCompBuffer = 0;
	    int dxComp         = dx1;
	    int dyComp         = dyStart;

            while (nextCompBuffer < numTasks)
            {
                ThreadPool::addGlobalTask (new TileBufferTask (&taskGroup,
                                                               _data,
                                                               nextCompBuffer++,
                                                               dxComp, dyComp,
                                                               lx, ly));
                dxComp++;

                if (dxComp > dx2)
                {
                    dxComp = dx1;
                    dyComp += dY;
                }
            }
            
            //
            // Write the compressed buffers and add in more compression
	    // tasks until done
            //
    
            int nextWriteBuffer = 0;
	    int dxWrite         = dx1;
	    int dyWrite         = dyStart;

            while (nextWriteBuffer < numTiles)
            {
		//
                // Wait until the nextWriteBuffer is ready to be written
		//

                TileBuffer* writeBuffer =
                                    _data->getTileBuffer (nextWriteBuffer);

                writeBuffer->wait();
    
		//
                // Write the tilebuffer
		//

                bufferedTileWrite (_streamData, _data, dxWrite, dyWrite, lx, ly,
                                   writeBuffer->dataPtr,
                                   writeBuffer->dataSize);
                
		//
                // Release the lock on nextWriteBuffer
		//

                writeBuffer->post();
                
		//
                // If there are no more tileBuffers to compress, then
		// only continue to write out remaining tileBuffers,
		// otherwise keep adding compression tasks.
		//

                if (nextCompBuffer < numTiles)
                {
		    //
                    // add nextCompBuffer as a compression Task
		    //

                    ThreadPool::addGlobalTask
			(new TileBufferTask (&taskGroup,
					     _data,
					     nextCompBuffer,
                                             dxComp, dyComp,
					     lx, ly));
                }
    
                nextWriteBuffer++;
                dxWrite++;

                if (dxWrite > dx2)
                {
                    dxWrite = dx1;
                    dyWrite += dY;
                }
                    
                nextCompBuffer++;
                dxComp++;

                if (dxComp > dx2)
                {
                    dxComp = dx1;
                    dyComp += dY;
                }
            }

	    //
            // finish all tasks
	    //
        }

	//
	// Exeption handling:
	//
	// TileBufferTask::execute() may have encountered exceptions, but
	// those exceptions occurred in another thread, not in the thread
	// that is executing this call to TiledOutputFile::writeTiles().
	// TileBufferTask::execute() has caught all exceptions and stored
	// the exceptions' what() strings in the tile buffers.
	// Now we check if any tile buffer contains a stored exception; if
	// this is the case then we re-throw the exception in this thread.
	// (It is possible that multiple tile buffers contain stored
	// exceptions.  We re-throw the first exception we find and
	// ignore all others.)
	//

	const string *exception = 0;

        for (size_t i = 0; i < _data->tileBuffers.size(); ++i)
	{
            TileBuffer *tileBuffer = _data->tileBuffers[i];

	    if (tileBuffer->hasException && !exception)
		exception = &tileBuffer->exception;

	    tileBuffer->hasException = false;
	}

	if (exception)
	    throw IEX_NAMESPACE::IoExc (*exception);
    }
    catch (IEX_NAMESPACE::BaseExc &e)
    {
        REPLACE_EXC (e, "Failed to write pixel data to image "
                        "file \"" << fileName() << "\". " << e);
        throw;
    }
}
Example #7
0
void PoolingLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) {
  if (!propagate_down[0]) {
    return;
  }
  const Dtype* top_diff = top[0]->cpu_diff();
  Dtype* bottom_diff = (*bottom)[0]->mutable_cpu_diff();
  // Different pooling methods. We explicitly do the switch outside the for
  // loop to save time, although this results in more codes.
  caffe_set((*bottom)[0]->count(), Dtype(0), bottom_diff);
  // We'll output the mask to top[1] if it's of size >1.
  const bool use_top_mask = top.size() > 1;
  const int* mask = NULL;  // suppress warnings about uninitialized variables
  const Dtype* top_mask = NULL;
  switch (this->layer_param_.pooling_param().pool()) {
  case PoolingParameter_PoolMethod_MAX:
    // The main loop
    if (use_top_mask) {
      top_mask = top[1]->cpu_data();
    } else {
      mask = max_idx_.cpu_data();
    }
    for (int n = 0; n < top[0]->num(); ++n) {
      for (int c = 0; c < channels_; ++c) {
        for (int ph = 0; ph < pooled_height_; ++ph) {
          for (int pw = 0; pw < pooled_width_; ++pw) {
            const int index = ph * pooled_width_ + pw;
            const int bottom_index =
                use_top_mask ? top_mask[index] : mask[index];
            bottom_diff[bottom_index] += top_diff[index];
          }
        }
        bottom_diff += (*bottom)[0]->offset(0, 1);
        top_diff += top[0]->offset(0, 1);
        if (use_top_mask) {
          top_mask += top[0]->offset(0, 1);
        } else {
          mask += top[0]->offset(0, 1);
        }
      }
    }
    break;
  case PoolingParameter_PoolMethod_AVE:
    // The main loop
    for (int n = 0; n < top[0]->num(); ++n) {
      for (int c = 0; c < channels_; ++c) {
        for (int ph = 0; ph < pooled_height_; ++ph) {
          for (int pw = 0; pw < pooled_width_; ++pw) {
            int hstart = ph * stride_h_ - pad_h_;
            int wstart = pw * stride_w_ - pad_w_;
            int hend = min(hstart + kernel_h_, height_ + pad_h_);
            int wend = min(wstart + kernel_w_, width_ + pad_w_);
            int pool_size = (hend - hstart) * (wend - wstart);
            hstart = max(hstart, 0);
            wstart = max(wstart, 0);
            hend = min(hend, height_);
            wend = min(wend, width_);
            for (int h = hstart; h < hend; ++h) {
              for (int w = wstart; w < wend; ++w) {
                bottom_diff[h * width_ + w] +=
                  top_diff[ph * pooled_width_ + pw] / pool_size;
              }
            }
          }
        }
        // offset
        bottom_diff += (*bottom)[0]->offset(0, 1);
        top_diff += top[0]->offset(0, 1);
      }
    }
    break;
  case PoolingParameter_PoolMethod_STOCHASTIC:
    NOT_IMPLEMENTED;
    break;
  default:
    LOG(FATAL) << "Unknown pooling method.";
  }
}
Example #8
0
node<P> batch_insert(const DistanceCallback& dcb, const P& p,
		int max_scale, 
		int top_scale,
		v_array<ds_node<P> >& point_set, 
		v_array<ds_node<P> >& consumed_set,
		v_array<v_array<ds_node<P> > >& stack)
{
	if (point_set.index == 0) 
		return new_leaf(p);
	else {
		DefaultScalarType max_dist = max_set(point_set); //O(|point_set|)
		int next_scale = min(max_scale - 1, get_scale(max_dist));
		if (next_scale == -2147483647-1) // We have points with distance 0.
		{
			v_array<node<P> > children;
			push(children,new_leaf(p));
			while (point_set.index > 0)
			{
				push(children,new_leaf(point_set.last().p));
				push(consumed_set,point_set.last());
				point_set.decr();
			}
			node<P> n = new_node(p);
			n.scale = 100; // A magic number meant to be larger than all scales.  
			n.max_dist = 0;
			alloc(children,children.index);
			n.num_children = children.index;
			n.children = children.elements;
			return n;
		}
		else
		{
			v_array<ds_node<P> > far = pop(stack);
			split(point_set,far,max_scale); //O(|point_set|)

			node<P> child = batch_insert(dcb, p, next_scale, top_scale, point_set, consumed_set, stack);

			if (point_set.index == 0)
			{
				push(stack,point_set);
				point_set=far;
				return child;
			}
			else {
				node<P> n = new_node(p);
				v_array<node<P> > children;
				push(children, child);
				v_array<ds_node<P> > new_point_set = pop(stack);
				v_array<ds_node<P> > new_consumed_set = pop(stack);
				while (point_set.index != 0) { //O(|point_set| * num_children)
					P new_point = point_set.last().p;
					DefaultScalarType new_dist = point_set.last().dist.last();
					push(consumed_set, point_set.last());
					point_set.decr();

					dist_split(dcb,point_set,new_point_set,new_point,max_scale); //O(|point_saet|)
					dist_split(dcb,far,new_point_set,new_point,max_scale); //O(|far|)

					node<P> new_child = 
						batch_insert(dcb, new_point, next_scale, top_scale, new_point_set, new_consumed_set, stack);
					new_child.parent_dist = new_dist;

					push(children, new_child);

					DefaultScalarType fmax = dist_of_scale(max_scale);
					for(int i = 0; i< new_point_set.index; i++) //O(|new_point_set|)
					{
						new_point_set[i].dist.decr();
						if (new_point_set[i].dist.last() <= fmax)
							push(point_set, new_point_set[i]);
						else
							push(far, new_point_set[i]);
					}
					for(int i = 0; i< new_consumed_set.index; i++) //O(|new_point_set|)
					{
						new_consumed_set[i].dist.decr();
						push(consumed_set, new_consumed_set[i]);
					}
					new_point_set.index = 0;
					new_consumed_set.index = 0;
				}
				push(stack,new_point_set);
				push(stack,new_consumed_set);
				push(stack,point_set);
				point_set=far;
				n.scale = top_scale - max_scale;
				n.max_dist = max_set(consumed_set);
				alloc(children,children.index);
				n.num_children = children.index;
				n.children = children.elements;
				return n;
			}
		}
	}
}
Example #9
0
void	
ScanLineInputFile::readPixels (int scanLine1, int scanLine2)
{
    try
    {
        Lock lock (*_data);

	if (_data->slices.size() == 0)
	    throw Iex::ArgExc ("No frame buffer specified "
			       "as pixel data destination.");

	int scanLineMin = min (scanLine1, scanLine2);
	int scanLineMax = max (scanLine1, scanLine2);

	if (scanLineMin < _data->minY || scanLineMax > _data->maxY)
	    throw Iex::ArgExc ("Tried to read scan line outside "
			       "the image file's data window.");

        //
        // We impose a numbering scheme on the lineBuffers where the first
        // scanline is contained in lineBuffer 1.
        //
        // Determine the first and last lineBuffer numbers in this scanline
        // range. We always attempt to read the scanlines in the order that
        // they are stored in the file.
        //

        int start, stop, dl;

        if (_data->lineOrder == INCREASING_Y)
        {
            start = (scanLineMin - _data->minY) / _data->linesInBuffer;
            stop  = (scanLineMax - _data->minY) / _data->linesInBuffer + 1;
            dl = 1;
        }
        else
        {
            start = (scanLineMax - _data->minY) / _data->linesInBuffer;
            stop  = (scanLineMin - _data->minY) / _data->linesInBuffer - 1;
            dl = -1;
        }

        //
        // Create a task group for all line buffer tasks.  When the
	// task group goes out of scope, the destructor waits until
	// all tasks are complete.
        //
        
        {
            TaskGroup taskGroup;
    
            //
            // Add the line buffer tasks.
            //
            // The tasks will execute in the order that they are created
            // because we lock the line buffers during construction and the
            // constructors are called by the main thread.  Hence, in order
	    // for a successive task to execute the previous task which
	    // used that line buffer must have completed already.
            //
    
            for (int l = start; l != stop; l += dl)
            {
                ThreadPool::addGlobalTask (newLineBufferTask (&taskGroup,
                                                              _data, l,
                                                              scanLineMin,
                                                              scanLineMax));
            }
        
	    //
            // finish all tasks
	    //
        }
        
	//
	// Exeption handling:
	//
	// LineBufferTask::execute() may have encountered exceptions, but
	// those exceptions occurred in another thread, not in the thread
	// that is executing this call to ScanLineInputFile::readPixels().
	// LineBufferTask::execute() has caught all exceptions and stored
	// the exceptions' what() strings in the line buffers.
	// Now we check if any line buffer contains a stored exception; if
	// this is the case then we re-throw the exception in this thread.
	// (It is possible that multiple line buffers contain stored
	// exceptions.  We re-throw the first exception we find and
	// ignore all others.)
	//

	const string *exception = 0;

        for (int i = 0; i < _data->lineBuffers.size(); ++i)
	{
            LineBuffer *lineBuffer = _data->lineBuffers[i];

	    if (lineBuffer->hasException && !exception)
		exception = &lineBuffer->exception;

	    lineBuffer->hasException = false;
	}

	if (exception)
	    throw Iex::IoExc (*exception);
    }
    catch (Iex::BaseExc &e)
    {
	REPLACE_EXC (e, "Error reading pixel data from image "
		        "file \"" << fileName() << "\". " << e);
	throw;
    }
}
Example #10
0
// Spawner is not necessarily parent, in case of subunits/fighters
bool Bullet::Initialize(Unit *spawner, int player_, int direction, WeaponType weapon, const Point &pos)
{
    Assert(!bulletframes_in_progress);
    list.prev = nullptr;
    list.next = nullptr;

    move_target = Point(0xffff, 0xffff);
    current_speed = 0;

    // Yes, bw mixes bullet's images with spawner's unit code.
    // At least wraith's lasers actually depend on this behaviour.
    const char *desc = "Bullet::Initialize (First frame of bullet's animation modifies the unit who spawned it)";
    UnitIscriptContext ctx(spawner, nullptr, desc, MainRng(), false);
    bool success = ((Flingy *)this)->Initialize(&ctx, weapon.Flingy(), player_, direction, pos);
    if (!success)
        return false;

    player = player_;
    Assert(weapon.Raw() < 0x100);
    weapon_id = (uint8_t)weapon.Raw();
    time_remaining = weapon.DeathTime();
    flingy_flags |= 0x8;
    flags = 0;
    bounces_remaining = 0;
    // Bw calls State_Init here, it should just return instantly though as no iscript has been run
    order_signal = 0;
    auto spin = weapon.LaunchSpin();
    if (spin != 0)
    {
        bool spin_positive = MainRng()->Rand(2) == 1;
        // Goliath dual missiles etc, ugh
        static bool last_bullet_spin_positive;
        if (spawner == *bw::last_bullet_spawner)
            spin_positive = !last_bullet_spin_positive;
        last_bullet_spin_positive = spin_positive;
        if (!spin_positive)
            spin = 0 - spin;
        movement_direction += spin;
        facing_direction = movement_direction;
        *bw::last_bullet_spawner = spawner;
    }

    if (spawner->Type().IsSubunit())
        parent = spawner->subunit;
    else if (spawner->Type() == UnitId::Scarab)
        parent = spawner->interceptor.parent;
    else
        parent = spawner;

    if (parent) // Parent may be nullptr if scara is shot and reaver dies before hit
        spawned.Add(parent->spawned_bullets);
    if (spawner->flags & UnitStatus::Hallucination)
        flags |= 0x2;
    previous_target = nullptr;
    target = spawner->target;
    if (target)
    {
        order_target_pos = target->sprite->position;
        sprite->elevation = target->sprite->elevation + 1;
        SetTarget(target);
    }
    else
    {
        order_target_pos = spawner->order_target_pos;
        sprite->elevation = spawner->sprite->elevation + 1;
    }

    switch (weapon.Behaviour())
    {
        case 0x8: // Move near
        {
            Assert(spawner->bullet_spread_seed < 0x100);
            spread_seed = (uint8_t)spawner->bullet_spread_seed;
            spawner->bullet_spread_seed++;
            if (spawner->bullet_spread_seed >= sizeof random_chances / sizeof(random_chances[0]))
                spawner->bullet_spread_seed = 0;
            const Point32 &diff = random_chances[spread_seed];
            Point &pos = order_target_pos;
            int x = min((int)*bw::map_width - 1, max(0, (int)pos.x - diff.x));
            int y = min((int)*bw::map_height - 1, max(0, (int)pos.y - diff.y));
            order_target_pos = Point(x, y);
            UpdateMoveTarget(order_target_pos);
        }
        break;
        case 0x2: case 0x4: // Appear on target unit / site
        if (target && parent)
        {
            if (MainRng()->Rand(0x100) <= bw::GetMissChance(parent, target))
            {
                int x = sprite->position.x - bw::circle[direction][0] * 30 / 256;
                int y = sprite->position.y - bw::circle[direction][1] * 30 / 256;
                x = max(0, min((int)*bw::map_width - 1, (int)x));
                y = max(0, min((int)*bw::map_height - 1, (int)y));
                Move(Point(x, y));
                flags |= 0x1;
            }
        }
        break;
        case 0x3: // Persist on target site
            Move(order_target_pos);
        break;
        case 0x6: // Suicide
        if (parent)
        {
            parent->flags |= UnitStatus::SelfDestructing;
            parent->Remove(nullptr);
        }
        break;
        case 0x9: // Go to max range
        {
            auto max_range = (Type().MaxRange() + 20) * 256;
            auto x = bw::circle[facing_direction][0] * max_range / 65536;
            auto y = bw::circle[facing_direction][1] * max_range / 65536;
            order_target_pos = spawner->sprite->position + Point(x, y);
            UpdateMoveTarget(order_target_pos);
        }
        break;
        case 0x7: case 0x1: case 0x0: // Bounce, Fly & follow/don't
            bounces_remaining = 3; // Won't matter on others
            if (target && parent)
            {
                if (MainRng()->Rand(0x100) <= bw::GetMissChance(parent, target))
                {
                    int x = order_target_pos.x - bw::circle[direction][0] * 30 / 256;
                    int y = order_target_pos.y - bw::circle[direction][1] * 30 / 256;
                    x = max(0, min((int)*bw::map_width - 1, (int)x));
                    y = max(0, min((int)*bw::map_height - 1, (int)y));
                    order_target_pos = Point(x, y);
                    flags |= 0x1;
                }
            }
            UpdateMoveTarget(order_target_pos);
        break;
        case 0x5: // Appear on attacker
        break;
        default:
            Warning("Unknown weapons.dat behaviour %x for weapon %x", Type().Behaviour(), weapon_id);
            return false;
        break;
    }
    return true;
}
Example #11
0
static void RefreshCalculator(void) {
  WndProperty* wp;

  RefreshTask();
  RefreshTaskStatistics();
  target_point = max(target_point,ActiveWayPoint);

  bool nodisplay = !AATEnabled 
    || (target_point==0) 
    || !ValidTaskPoint(target_point+1);

  if (btnMove) {
    if (nodisplay) {
      btnMove->SetVisible(false);
      TargetMoveMode = false;
    } else {
      btnMove->SetVisible(true);
    }
  } 

  nodisplay = nodisplay || TargetMoveMode;

  wp = (WndProperty*)wf->FindByName(TEXT("prpTaskPoint"));
  if (wp) {
    if (TargetMoveMode) {
      wp->SetVisible(false);
    } else {
      wp->SetVisible(true);
    }
  }

  WindowControl* wc = (WindowControl*)wf->FindByName(TEXT("btnOK"));
  if (wc) {
    if (TargetMoveMode) {
      wc->SetVisible(false);
    } else {
      wc->SetVisible(true);
    }
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpAATTargetLocked"));
  if (wp) {
    wp->GetDataField()->Set(Task[target_point].AATTargetLocked);
    wp->RefreshDisplay();
    if (nodisplay) {
      wp->SetVisible(false);
    } else {
      wp->SetVisible(true);
    }
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpRange"));
  if (wp) {
    wp->GetDataField()->SetAsFloat(Range*100.0);
    wp->RefreshDisplay();
    if (nodisplay) {
      wp->SetVisible(false);
    } else {
      wp->SetVisible(true);
    }
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpRadial"));
  if (wp) {
    wp->GetDataField()->SetAsFloat(Radial);
    wp->RefreshDisplay();
    if (nodisplay) {
      wp->SetVisible(false);
    } else {
      wp->SetVisible(true);
    }
  }

  // update outputs
  double dd = CALCULATED_INFO.TaskTimeToGo;
  if ((CALCULATED_INFO.TaskStartTime>0.0)&&(CALCULATED_INFO.Flying)) {
    dd += GPS_INFO.Time-CALCULATED_INFO.TaskStartTime;
  }
  dd= min(24.0*60.0,dd/60.0);
  wp = (WndProperty*)wf->FindByName(TEXT("prpAATEst"));
  if (wp) {
    wp->GetDataField()->SetAsFloat(dd);
    wp->RefreshDisplay();
  }
  wp = (WndProperty*)wf->FindByName(TEXT("prpAATDelta"));
  if (wp) {
    wp->GetDataField()->SetAsFloat(dd-AATTaskLength);
    if (AATEnabled) {
      wp->SetVisible(true);
    } else {
      wp->SetVisible(false);
    }
    wp->RefreshDisplay();
  }

  double v1;
  if (CALCULATED_INFO.TaskTimeToGo>0) {
    v1 = CALCULATED_INFO.TaskDistanceToGo/
      CALCULATED_INFO.TaskTimeToGo;
  } else {
    v1 = 0;
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpSpeedRemaining"));
  if (wp) {
    wp->GetDataField()->SetAsFloat(v1*TASKSPEEDMODIFY);
    wp->GetDataField()->SetUnits(Units::GetTaskSpeedName());
    wp->RefreshDisplay();
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpSpeedAchieved"));
  if (wp) {
    wp->GetDataField()->SetAsFloat(CALCULATED_INFO.TaskSpeed*TASKSPEEDMODIFY);
    wp->GetDataField()->SetUnits(Units::GetTaskSpeedName());
    wp->RefreshDisplay();
  }

}
Example #12
0
void ScrollBar::processMessage(Message& msg) {
	switch (msg.message) {
		case wmReflect + WM_HSCROLL :
		case wmReflect + WM_VSCROLL : {
			SCROLLINFO info;
			info.cbSize = sizeof(info);
			info.fMask = SIF_ALL;
			verify(GetScrollInfo(handle(), SB_CTL, &info));
			int pos = info.nPos;
			bool tracking = false;
			switch (LOWORD(msg.wparam)) {
				case SB_THUMBPOSITION : pos = info.nTrackPos; break;
				case SB_THUMBTRACK    : pos = info.nTrackPos; tracking = true; break;
				case SB_LINEUP        : pos = pos - lineSize(); break;
				case SB_LINEDOWN      : pos = pos + lineSize(); break;
				case SB_PAGEUP        : pos = pos - static_cast<int>(info.nPage); break;
				case SB_PAGEDOWN      : pos = pos + static_cast<int>(info.nPage); break;
				case SB_TOP           : pos = 0; break;
				case SB_BOTTOM        : pos = info.nMax - info.nPage + 1; break;
			}
			pos = min(pos, info.nMax - static_cast<int>(info.nPage) + 1);
			pos = max(pos, info.nMin);
			const int oldPos = info.nPos;
			if (pos != oldPos) {
				info.fMask = SIF_POS;
				info.nPos = pos;
				SetScrollInfo(handle(), SB_CTL, &info, TRUE);
			}
			if (pos != oldPos || LOWORD(msg.wparam) == SB_THUMBPOSITION) {
				Scroll event(*this, info.nPos, pos, tracking);
				onScroll()(event);
			}
		} break;
		case wmReflect + WM_CTLCOLORSCROLLBAR : {
			HBRUSH brush = this->brush();
			if (brush) {
				Graphics graphics((HDC)msg.wparam);
				graphics.brushOrigin(brushOrigin());
				msg.result = (LRESULT)brush;
			} else {
				Control::processMessage(msg);
			}
		} break;
		case WM_MOUSEWHEEL : {
			SCROLLINFO info;
			info.cbSize = sizeof(info);
			info.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
			verify(GetScrollInfo(handle(), SB_CTL, &info));
			int delta = GET_WHEEL_DELTA_WPARAM(msg.wparam);
			delta = (delta / WHEEL_DELTA) * lineSize();
			int pos = info.nPos - delta;
			pos = min(pos, info.nMax - static_cast<int>(info.nPage) + 1);
			pos = max(pos, info.nMin);
			value(pos);
			Control::processMessage(msg);
		} break;
		default : {
			Control::processMessage(msg);
		} break;
	}
}
Example #13
0
int CUnitHandler::TestUnitBuildSquare(
	const BuildInfo& buildInfo,
	CFeature*& feature,
	int allyteam,
	std::vector<float3>* canbuildpos,
	std::vector<float3>* featurepos,
	std::vector<float3>* nobuildpos,
	const std::vector<Command>* commands)
{
	feature = NULL;

	const int xsize = buildInfo.GetXSize();
	const int zsize = buildInfo.GetZSize();
	const float3 pos = buildInfo.pos;

	const int x1 = (int) (pos.x - (xsize * 0.5f * SQUARE_SIZE));
	const int x2 = x1 + xsize * SQUARE_SIZE;
	const int z1 = (int) (pos.z - (zsize * 0.5f * SQUARE_SIZE));
	const int z2 = z1 + zsize * SQUARE_SIZE;
	const float h = GetBuildHeight(pos, buildInfo.def);

	int canBuild = 2;

	if (buildInfo.def->needGeo) {
		canBuild = 0;
		std::vector<CFeature*> features = qf->GetFeaturesExact(pos, max(xsize, zsize) * 6);

		for (std::vector<CFeature*>::iterator fi = features.begin(); fi != features.end(); ++fi) {
			if ((*fi)->def->geoThermal
				&& fabs((*fi)->pos.x - pos.x) < (xsize * 4 - 4)
				&& fabs((*fi)->pos.z - pos.z) < (zsize * 4 - 4)) {
				canBuild = 2;
				break;
			}
		}
	}

	if (commands != NULL) {
		//! unsynced code
		for (int x = x1; x < x2; x += SQUARE_SIZE) {
			for (int z = z1; z < z2; z += SQUARE_SIZE) {
				int tbs = TestBuildSquare(float3(x, pos.y, z), buildInfo.def, feature, gu->myAllyTeam);

				if (tbs) {
					std::vector<Command>::const_iterator ci = commands->begin();

					for (; ci != commands->end() && tbs; ci++) {
						BuildInfo bc(*ci);

						if (std::max(bc.pos.x - x - SQUARE_SIZE, x - bc.pos.x) * 2 < bc.GetXSize() * SQUARE_SIZE &&
							std::max(bc.pos.z - z - SQUARE_SIZE, z - bc.pos.z) * 2 < bc.GetZSize() * SQUARE_SIZE) {
							tbs = 0;
						}
					}

					if (!tbs) {
						nobuildpos->push_back(float3(x, h, z));
						canBuild = 0;
					} else if (feature || tbs == 1) {
						featurepos->push_back(float3(x, h, z));
					} else {
						canbuildpos->push_back(float3(x, h, z));
					}

					canBuild = min(canBuild, tbs);
				} else {
					nobuildpos->push_back(float3(x, h, z));
					canBuild = 0;
				}
			}
		}
	} else {
		for (int x = x1; x < x2; x += SQUARE_SIZE) {
			for (int z = z1; z < z2; z += SQUARE_SIZE) {
				canBuild = min(canBuild, TestBuildSquare(float3(x, h, z), buildInfo.def, feature, allyteam));

				if (canBuild == 0) {
					return 0;
				}
			}
		}
	}

	return canBuild;
}
Example #14
0
bool overlaps(interval_t a, interval_t b)
{
	int v = min(a.stop,b.stop) - max(a.start,b.start) + 1;
	return (v >= 1);
}
Example #15
0
static  int VtoI(double V) {
    return min(NUM_V_POINTS-1, iround(V*(NUM_V_POINTS-1)/V_SCALE));
  }
Example #16
0
// Creation of the physics box... quite cabalistic and extensive func...
// Need to put a (really) smarter algorithm in there...
void EERIE_PHYSICS_BOX_Create(EERIE_3DOBJ * obj)
{
	if (!obj) return;

	EERIE_PHYSICS_BOX_Release(obj);

	if (obj->vertexlist.empty()) return;

	obj->pbox =	(PHYSICS_BOX_DATA *)
	            malloc(sizeof(PHYSICS_BOX_DATA));
	memset(obj->pbox, 0, sizeof(PHYSICS_BOX_DATA));
	obj->pbox->nb_physvert = 15;
	obj->pbox->stopcount = 0;
	obj->pbox->vert =	(PHYSVERT *)
	                    malloc(sizeof(PHYSVERT) * obj->pbox->nb_physvert);
	memset(obj->pbox->vert, 0, sizeof(PHYSVERT)*obj->pbox->nb_physvert);
	
	Vec3f cubmin = Vec3f::repeat(std::numeric_limits<float>::max());
	Vec3f cubmax = Vec3f::repeat(-std::numeric_limits<float>::max());
	
	for(size_t k = 0; k < obj->vertexlist.size(); k++) {
		if(long(k) != obj->origin) {
			cubmin = componentwise_min(cubmin, obj->vertexlist[k].v);
			cubmax = componentwise_max(cubmax, obj->vertexlist[k].v);
		}
	}
	
	obj->pbox->vert[0].pos = cubmin + (cubmax - cubmin) * .5f;
	obj->pbox->vert[13].pos = obj->pbox->vert[0].pos;
	obj->pbox->vert[13].pos.y = cubmin.y;
	obj->pbox->vert[14].pos = obj->pbox->vert[0].pos;
	obj->pbox->vert[14].pos.y = cubmax.y;
	
	for (int k = 1; k < obj->pbox->nb_physvert - 2; k++)
	{
		obj->pbox->vert[k].pos.x = obj->pbox->vert[0].pos.x;
		obj->pbox->vert[k].pos.z = obj->pbox->vert[0].pos.z;

		if (k < 5)		obj->pbox->vert[k].pos.y = cubmin.y;
		else if (k < 9)	obj->pbox->vert[k].pos.y = obj->pbox->vert[0].pos.y;
		else			obj->pbox->vert[k].pos.y = cubmax.y;
	}

	float diff = cubmax.y - cubmin.y;

	if (diff < 12.f) 
	{
		cubmax.y += 8.f; 
		cubmin.y -= 8.f; 

		for (int k = 1; k < obj->pbox->nb_physvert - 2; k++)
		{
			obj->pbox->vert[k].pos.x = obj->pbox->vert[0].pos.x;
			obj->pbox->vert[k].pos.z = obj->pbox->vert[0].pos.z;

			if (k < 5)		obj->pbox->vert[k].pos.y = cubmin.y;
			else if (k < 9)	obj->pbox->vert[k].pos.y = obj->pbox->vert[0].pos.y;
			else			obj->pbox->vert[k].pos.y = cubmax.y;
		}

		obj->pbox->vert[14].pos.y = cubmax.y;
		obj->pbox->vert[13].pos.y = cubmin.y;
		float RATI = diff * ( 1.0f / 8 );

		for (size_t k = 0; k < obj->vertexlist.size(); k++)
		{
			if (k == (size_t)obj->origin) continue;

			Vec3f curr = obj->vertexlist[k].v;
			long SEC = 1;
			obj->pbox->vert[SEC].pos.x = min(obj->pbox->vert[SEC].pos.x, curr.x);
			obj->pbox->vert[SEC].pos.z = min(obj->pbox->vert[SEC].pos.z, curr.z);

			obj->pbox->vert[SEC+1].pos.x = min(obj->pbox->vert[SEC+1].pos.x, curr.x);
			obj->pbox->vert[SEC+1].pos.z = max(obj->pbox->vert[SEC+1].pos.z, curr.z);

			obj->pbox->vert[SEC+2].pos.x = max(obj->pbox->vert[SEC+2].pos.x, curr.x);
			obj->pbox->vert[SEC+2].pos.z = max(obj->pbox->vert[SEC+2].pos.z, curr.z);

			obj->pbox->vert[SEC+3].pos.x = max(obj->pbox->vert[SEC+3].pos.x, curr.x);
			obj->pbox->vert[SEC+3].pos.z = min(obj->pbox->vert[SEC+3].pos.z, curr.z);

			SEC = 5;
			obj->pbox->vert[SEC].pos.x = min(obj->pbox->vert[SEC].pos.x, curr.x - RATI);
			obj->pbox->vert[SEC].pos.z = min(obj->pbox->vert[SEC].pos.z, curr.z - RATI);

			obj->pbox->vert[SEC+1].pos.x = min(obj->pbox->vert[SEC+1].pos.x, curr.x - RATI);
			obj->pbox->vert[SEC+1].pos.z = max(obj->pbox->vert[SEC+1].pos.z, curr.z + RATI);

			obj->pbox->vert[SEC+2].pos.x = max(obj->pbox->vert[SEC+2].pos.x, curr.x + RATI);
			obj->pbox->vert[SEC+2].pos.z = max(obj->pbox->vert[SEC+2].pos.z, curr.z + RATI);

			obj->pbox->vert[SEC+3].pos.x = max(obj->pbox->vert[SEC+3].pos.x, curr.x + RATI);
			obj->pbox->vert[SEC+3].pos.z = min(obj->pbox->vert[SEC+3].pos.z, curr.z - RATI);


			SEC = 9;
			obj->pbox->vert[SEC].pos.x = min(obj->pbox->vert[SEC].pos.x, curr.x);
			obj->pbox->vert[SEC].pos.z = min(obj->pbox->vert[SEC].pos.z, curr.z);

			obj->pbox->vert[SEC+1].pos.x = min(obj->pbox->vert[SEC+1].pos.x, curr.x);
			obj->pbox->vert[SEC+1].pos.z = max(obj->pbox->vert[SEC+1].pos.z, curr.z);

			obj->pbox->vert[SEC+2].pos.x = max(obj->pbox->vert[SEC+2].pos.x, curr.x);
			obj->pbox->vert[SEC+2].pos.z = max(obj->pbox->vert[SEC+2].pos.z, curr.z);

			obj->pbox->vert[SEC+3].pos.x = max(obj->pbox->vert[SEC+3].pos.x, curr.x);
			obj->pbox->vert[SEC+3].pos.z = min(obj->pbox->vert[SEC+3].pos.z, curr.z);
		}
	}
	else
	{
		float cut = (cubmax.y - cubmin.y) * ( 1.0f / 3 );
		float ysec2 = cubmin.y + cut * 2.f;
		float ysec1 = cubmin.y + cut;

		for (size_t k = 0; k < obj->vertexlist.size(); k++)
		{
			if (k == (size_t)obj->origin) continue;

			Vec3f curr = obj->vertexlist[k].v;
			long SEC;

			if (curr.y < ysec1)
			{
				SEC = 1;
			}
			else if (curr.y < ysec2)
			{
				SEC = 5;
			}
			else
			{
				SEC = 9;
			}

			obj->pbox->vert[SEC].pos.x = min(obj->pbox->vert[SEC].pos.x, curr.x);
			obj->pbox->vert[SEC].pos.z = min(obj->pbox->vert[SEC].pos.z, curr.z);

			obj->pbox->vert[SEC+1].pos.x = min(obj->pbox->vert[SEC+1].pos.x, curr.x);
			obj->pbox->vert[SEC+1].pos.z = max(obj->pbox->vert[SEC+1].pos.z, curr.z);

			obj->pbox->vert[SEC+2].pos.x = max(obj->pbox->vert[SEC+2].pos.x, curr.x);
			obj->pbox->vert[SEC+2].pos.z = max(obj->pbox->vert[SEC+2].pos.z, curr.z);

			obj->pbox->vert[SEC+3].pos.x = max(obj->pbox->vert[SEC+3].pos.x, curr.x);
			obj->pbox->vert[SEC+3].pos.z = min(obj->pbox->vert[SEC+3].pos.z, curr.z);
		}
	}

	for (int k = 0; k < 4; k++)
	{
		if (EEfabs(obj->pbox->vert[5+k].pos.x - obj->pbox->vert[0].pos.x) < 2.f)
			obj->pbox->vert[5+k].pos.x = (obj->pbox->vert[1+k].pos.x + obj->pbox->vert[9+k].pos.x) * .5f;

		if (EEfabs(obj->pbox->vert[5+k].pos.z - obj->pbox->vert[0].pos.z) < 2.f)
			obj->pbox->vert[5+k].pos.z = (obj->pbox->vert[1+k].pos.z + obj->pbox->vert[9+k].pos.z) * .5f;
	}

	obj->pbox->radius = 0.f;

	for(int k = 0; k < obj->pbox->nb_physvert; k++) {
		float distt = dist(obj->pbox->vert[k].pos, obj->pbox->vert[0].pos);

		if (distt > 20.f)
		{
			obj->pbox->vert[k].pos.x = (obj->pbox->vert[k].pos.x
			                            - obj->pbox->vert[0].pos.x) * 0.5f +
			                           obj->pbox->vert[0].pos.x;
			obj->pbox->vert[k].pos.z = (obj->pbox->vert[k].pos.z
			                            - obj->pbox->vert[0].pos.z) * 0.5f +
			                           obj->pbox->vert[0].pos.z;
		}

		obj->pbox->vert[k].initpos = obj->pbox->vert[k].pos;

		if(k != 0) {
			float d = dist(obj->pbox->vert[0].pos, obj->pbox->vert[k].pos);
			obj->pbox->radius = max(obj->pbox->radius, d);
		}
	}
}
Example #17
0
static  double ItoV(int i) {
    return max(0,min(i,NUM_V_POINTS-1))*V_SCALE/(NUM_V_POINTS-1);
  }
Example #18
0
void UnpoolingLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
  if (!propagate_down[0]) {
    return;
  }
  const Dtype* top_diff = top[0]->cpu_diff();
  Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();
  // Different unpooling methods. We explicitly do the switch outside the for
  // loop to save time, although this results in more codes.
  caffe_set(bottom[0]->count(), Dtype(0), bottom_diff);
  // We'll output the mask to top[1] if it's of size >1.
  const bool use_bottom_mask = bottom.size() > 1;
  const Dtype* bottom_mask = NULL;
  switch (this->layer_param_.unpooling_param().unpool()) {
  case UnpoolingParameter_UnpoolMethod_MAX:
    if (use_bottom_mask) {
      bottom_mask = bottom[1]->cpu_data();
    } 
    // The main loop
    for (int n = 0; n < top[0]->num(); ++n) {
      for (int c = 0; c < channels_; ++c) {
        for (int ph = 0; ph < height_; ++ph) {
          for (int pw = 0; pw < width_; ++pw) {
            int uph = max(0,min(ph * stride_h_ - pad_h_, unpooled_height_-1));
            int upw = max(0,min(pw * stride_w_ - pad_w_, unpooled_width_-1)); 
            const int index = ph * width_ + pw;
            const int unpooled_index = uph * unpooled_width_ + upw; 
            if (use_bottom_mask) {
              const int mask_index = bottom_mask[index];
              bottom_diff[index] = top_diff[mask_index]; 
            } else {
              bottom_diff[index] = top_diff[unpooled_index];
            }
          }
        }
        // compute offset
        bottom_diff += bottom[0]->offset(0, 1);
        top_diff += top[0]->offset(0, 1);
        if (use_bottom_mask) {
          bottom_mask += bottom[1]->offset(0, 1);
        } 
      }
    }
    break;
  case UnpoolingParameter_UnpoolMethod_AVE:
    for (int i = 0; i < bottom[0]->count(); ++i) {
      bottom_diff[i] = 0;
    }
    // The main loop
    for (int n = 0; n < bottom[0]->num(); ++n) {
      for (int c = 0; c < channels_; ++c) {
        for (int ph = 0; ph < height_; ++ph) {
          for (int pw = 0; pw < width_; ++pw) {
            int hstart = ph * stride_h_ - pad_h_;
            int wstart = pw * stride_w_ - pad_w_;
            int hend = min(hstart + kernel_h_, unpooled_height_ + pad_h_);
            int wend = min(wstart + kernel_w_, unpooled_width_ + pad_w_);
            int pool_size = (hend - hstart) * (wend - wstart);
            hstart = max(hstart, 0);
            wstart = max(wstart, 0);
            hend = min(hend, unpooled_height_);
            wend = min(wend, unpooled_width_);
            for (int h = hstart; h < hend; ++h) {
              for (int w = wstart; w < wend; ++w) {
                bottom_diff[ph * width_ + pw] +=
                    top_diff[h * unpooled_width_ + w];
              }
            }
            bottom_diff[ph * width_ + pw] /= pool_size;
          }
        }
        // compute offset
        bottom_diff += bottom[0]->offset(0, 1);
        top_diff += top[0]->offset(0, 1);
      }
    }
    break;
  case UnpoolingParameter_UnpoolMethod_TILE:
    for (int i = 0; i < bottom[0]->count(); ++i) {
      bottom_diff[i] = 0;
    }
    // The main loop
    for (int n = 0; n < bottom[0]->num(); ++n) {
      for (int c = 0; c < channels_; ++c) {
        for (int ph = 0; ph < height_; ++ph) {
          for (int pw = 0; pw < width_; ++pw) {
            int hstart = ph * stride_h_ - pad_h_;
            int wstart = pw * stride_w_ - pad_w_;
            int hend = min(hstart + kernel_h_, unpooled_height_ + pad_h_);
            int wend = min(wstart + kernel_w_, unpooled_width_ + pad_w_);
            int pool_size = (hend - hstart) * (wend - wstart);
            hstart = max(hstart, 0);
            wstart = max(wstart, 0);
            hend = min(hend, unpooled_height_);
            wend = min(wend, unpooled_width_);
            for (int h = hstart; h < hend; ++h) {
              for (int w = wstart; w < wend; ++w) {
                bottom_diff[ph * width_ + pw] +=
                    top_diff[h * unpooled_width_ + w];
              }
            }
            bottom_diff[ph * width_ + pw] /= pool_size;
          }
        }
        // compute offset
        bottom_diff += bottom[0]->offset(0, 1);
        top_diff += top[0]->offset(0, 1);
      }
    }
    break;
  default:
    LOG(FATAL) << "Unknown unpooling method.";
  }
}
Example #19
0
void PoolingLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top) {
  const Dtype* bottom_data = bottom[0]->cpu_data();
  Dtype* top_data = (*top)[0]->mutable_cpu_data();
  const int top_count = (*top)[0]->count();
  // We'll output the mask to top[1] if it's of size >1.
  const bool use_top_mask = top->size() > 1;
  int* mask = NULL;  // suppress warnings about uninitalized variables
  Dtype* top_mask = NULL;
  // Different pooling methods. We explicitly do the switch outside the for
  // loop to save time, although this results in more code.
  switch (this->layer_param_.pooling_param().pool()) {
  case PoolingParameter_PoolMethod_MAX:
    // Initialize
    if (use_top_mask) {
      top_mask = (*top)[1]->mutable_cpu_data();
      caffe_set(top_count, Dtype(-1), top_mask);
    } else {
      mask = max_idx_.mutable_cpu_data();
      caffe_set(top_count, -1, mask);
    }
    caffe_set(top_count, Dtype(-FLT_MAX), top_data);
    // The main loop
    for (int n = 0; n < bottom[0]->num(); ++n) {
      for (int c = 0; c < channels_; ++c) {
        for (int ph = 0; ph < pooled_height_; ++ph) {
          for (int pw = 0; pw < pooled_width_; ++pw) {
            int hstart = ph * stride_h_ - pad_h_;
            int wstart = pw * stride_w_ - pad_w_;
            int hend = min(hstart + kernel_h_, height_);
            int wend = min(wstart + kernel_w_, width_);
            hstart = max(hstart, 0);
            wstart = max(wstart, 0);
            const int pool_index = ph * pooled_width_ + pw;
            for (int h = hstart; h < hend; ++h) {
              for (int w = wstart; w < wend; ++w) {
                const int index = h * width_ + w;
                if (bottom_data[index] > top_data[pool_index]) {
                  top_data[pool_index] = bottom_data[index];
                  if (use_top_mask) {
                    top_mask[pool_index] = static_cast<Dtype>(index);
                  } else {
                    mask[pool_index] = index;
                  }
                }
              }
            }
          }
        }
        // compute offset
        bottom_data += bottom[0]->offset(0, 1);
        top_data += (*top)[0]->offset(0, 1);
        if (use_top_mask) {
          top_mask += (*top)[0]->offset(0, 1);
        } else {
          mask += (*top)[0]->offset(0, 1);
        }
      }
    }
    break;
  case PoolingParameter_PoolMethod_AVE:
    for (int i = 0; i < top_count; ++i) {
      top_data[i] = 0;
    }
    // The main loop
    for (int n = 0; n < bottom[0]->num(); ++n) {
      for (int c = 0; c < channels_; ++c) {
        for (int ph = 0; ph < pooled_height_; ++ph) {
          for (int pw = 0; pw < pooled_width_; ++pw) {
            int hstart = ph * stride_h_ - pad_h_;
            int wstart = pw * stride_w_ - pad_w_;
            int hend = min(hstart + kernel_h_, height_ + pad_h_);
            int wend = min(wstart + kernel_w_, width_ + pad_w_);
            int pool_size = (hend - hstart) * (wend - wstart);
            hstart = max(hstart, 0);
            wstart = max(wstart, 0);
            hend = min(hend, height_);
            wend = min(wend, width_);
            for (int h = hstart; h < hend; ++h) {
              for (int w = wstart; w < wend; ++w) {
                top_data[ph * pooled_width_ + pw] +=
                    bottom_data[h * width_ + w];
              }
            }
            top_data[ph * pooled_width_ + pw] /= pool_size;
          }
        }
        // compute offset
        bottom_data += bottom[0]->offset(0, 1);
        top_data += (*top)[0]->offset(0, 1);
      }
    }
    break;
  case PoolingParameter_PoolMethod_STOCHASTIC:
    NOT_IMPLEMENTED;
    break;
  default:
    LOG(FATAL) << "Unknown pooling method.";
  }
}
Example #20
0
void CheMPS2::DMRGSCFrotations::rotate( const FourIndex * ORIG_VMAT, FourIndex * NEW_VMAT, DMRGSCFintegrals * ROT_TEI, const char space1, const char space2, const char space3, const char space4, DMRGSCFindices * idx, DMRGSCFunitary * umat, double * mem1, double * mem2, const int mem_size, const string filename ){

   /* Matrix elements ( 1 2 | 3 4 ) */

   assert(( space1 == 'O' ) || ( space1 == 'A' ) || ( space1 == 'V' ) || ( space1 == 'C' ) || ( space1 == 'F' ));
   assert(( space2 == 'O' ) || ( space2 == 'A' ) || ( space2 == 'V' ) || ( space2 == 'C' ) || ( space2 == 'F' ));
   assert(( space3 == 'O' ) || ( space3 == 'A' ) || ( space3 == 'V' ) || ( space3 == 'C' ) || ( space3 == 'F' ));
   assert(( space4 == 'O' ) || ( space4 == 'A' ) || ( space4 == 'V' ) || ( space4 == 'C' ) || ( space4 == 'F' ));

   const int num_irreps = idx->getNirreps();
   const bool equal12 = ( space1 == space2 );
   const bool equal34 = ( space3 == space4 );
   const bool eightfold = (( space1 == space3 ) && ( space2 == space4 ));

   for ( int irrep1 = 0; irrep1 < num_irreps; irrep1++ ){
      for ( int irrep2 = (( equal12 ) ? irrep1 : 0 ); irrep2 < num_irreps; irrep2++ ){ // irrep2 >= irrep1 if space1 == space2
         const int product_symm = Irreps::directProd( irrep1, irrep2 );
         for ( int irrep3 = (( eightfold ) ? irrep1 : 0 ); irrep3 < num_irreps; irrep3++ ){
            const int irrep4 = Irreps::directProd( product_symm, irrep3 );
            if ( irrep4 >= (( equal34 ) ? irrep3 : 0 ) ){ // irrep4 >= irrep3 if space3 == space4

               const int NEW1 = dimension( idx, irrep1, space1 );
               const int NEW2 = dimension( idx, irrep2, space2 );
               const int NEW3 = dimension( idx, irrep3, space3 );
               const int NEW4 = dimension( idx, irrep4, space4 );

               if (( NEW1 > 0 ) && ( NEW2 > 0 ) && ( NEW3 > 0 ) && ( NEW4 > 0 )){

                  const int ORIG1 = idx->getNORB( irrep1 );
                  const int ORIG2 = idx->getNORB( irrep2 );
                  const int ORIG3 = idx->getNORB( irrep3 );
                  const int ORIG4 = idx->getNORB( irrep4 );

                  double * umat1 = umat->getBlock( irrep1 ) + jump( idx, irrep1, space1 );
                  double * umat2 = umat->getBlock( irrep2 ) + jump( idx, irrep2, space2 );
                  double * umat3 = umat->getBlock( irrep3 ) + jump( idx, irrep3, space3 );
                  double * umat4 = umat->getBlock( irrep4 ) + jump( idx, irrep4, space4 );

                  const int block_size1 = mem_size / ( ORIG1 * ORIG2 ); // Floor of amount of times orig( first  ) fits in mem_size
                  const int block_size2 = mem_size / ( ORIG3 * ORIG4 ); // Floor of amount of times orig( second ) fits in mem_size
                  assert( block_size1 > 0 );
                  assert( block_size2 > 0 );

                  const bool pack_first  = (( equal12 ) && ( irrep1 == irrep2 ));
                  const bool pack_second = (( equal34 ) && ( irrep3 == irrep4 ));
                  const int   first_size = (( pack_first  ) ? (  NEW1 * (  NEW1 + 1 )) / 2 :  NEW1 * NEW2  );
                  const int  second_size = (( pack_second ) ? ( ORIG3 * ( ORIG3 + 1 )) / 2 : ORIG3 * ORIG4 );

                  const bool io_free = (( block_size1 >= second_size ) && ( block_size2 >= first_size ));
                  hid_t file_id, dspc_id, dset_id;

                  if ( io_free == false ){
                     assert( filename.compare( "edmistonruedenberg" ) != 0 );
                     open_file( &file_id, &dspc_id, &dset_id, first_size, second_size, filename );
                  }

                  // First half transformation
                  int start = 0;
                  while ( start < second_size ){
                     const int stop = min( start + block_size1, second_size );
                     const int size = stop - start;
                     fetch( mem1, ORIG_VMAT, irrep1, irrep2, irrep3, irrep4, idx, start, stop, pack_second );
                     blockwise_first(  mem1, mem2, ORIG1, ORIG2, size, umat1, NEW1, ORIG1 );
                     blockwise_second( mem2, mem1, NEW1,  ORIG2, size, umat2, NEW2, ORIG2 );
                     if ( pack_first ){
                        package_first( mem1, mem2, NEW1, first_size, size );
                        double * temp = mem1;
                        mem1 = mem2;
                        mem2 = temp;
                     }
                     if ( io_free == false ){ write_file( dspc_id, dset_id, mem1, start, size, first_size ); }
                     start += size;
                  }
                  assert( start == second_size );

                  // Do the second half transformation
                  start = 0;
                  while ( start < first_size ){
                     const int stop = min( start + block_size2, first_size );
                     const int size = stop - start;
                     if ( io_free == false ){ read_file( dspc_id, dset_id, mem1, start, size, second_size ); }
                     if ( pack_second ){
                        unpackage_second( mem1, mem2, size, ORIG3 );
                        double * temp = mem1;
                        mem1 = mem2;
                        mem2 = temp;
                     }
                     blockwise_fourth( mem1, mem2, size, ORIG3, ORIG4, umat4, NEW4, ORIG4 );
                     blockwise_third(  mem2, mem1, size, ORIG3, NEW4,  umat3, NEW3, ORIG3 );
                     write( mem1, NEW_VMAT, ROT_TEI, space1, space2, space3, space4, irrep1, irrep2, irrep3, irrep4, idx, start, stop, pack_first );
                     start += size;
                  }
                  assert( start == first_size );
                  if ( io_free == false ){ close_file( file_id, dspc_id, dset_id ); }
               }
            }
         }
      }
   }

}
Example #21
0
// print the current state on the last line of the lcd
void LcdDisplay::printState(void){
	uint16_t time = UINT16_MAX; // init to max
	uint8_t state = tempControl.getDisplayState();
	if(state != stateOnDisplay){ //only print static text when state has changed
		stateOnDisplay = state;
		// Reprint state and clear rest of the line
		const char * part1 = STR_empty_string;
		const char * part2 = STR_empty_string;
		switch (state){
			case IDLE:
				part1 = PSTR("Idl");
				part2 = STR_ing_for;
				break;
			case WAITING_TO_COOL:
				part1 = STR_Wait_to_;
				part2 = STR_Cool;
				break;
			case WAITING_TO_HEAT:
				part1 = STR_Wait_to_;
				part2 = STR_Heat;
				break;
			case WAITING_FOR_PEAK_DETECT:
				part1 = PSTR("Waiting for peak");
				break;
			case COOLING:
				part1 = STR_Cool;
				part2 = STR_ing_for;
				break;
			case HEATING:
				part1 = STR_Heat;
				part2 = STR_ing_for;
				break;
			case COOLING_MIN_TIME:
				part1 = STR_Cool;
				part2 = STR__time_left;
				break;
			case HEATING_MIN_TIME:
				part1 = STR_Heat;
				part2 = STR__time_left;
				break;
			case DOOR_OPEN:
				part1 = PSTR("Door open");
				break;
			case STATE_OFF:
				part1 = PSTR("Temp. control OFF");
				break;
			default:
				part1 = PSTR("Unknown status!");
				break;
		}
		printAt_P(0, 3, part1);
		lcd.print_P(part2);		
		lcd.printSpacesToRestOfLine();
	}
	uint16_t sinceIdleTime = tempControl.timeSinceIdle();
	if(state==IDLE){
		time = 	min(tempControl.timeSinceCooling(), tempControl.timeSinceHeating());
	}
	else if(state==COOLING || state==HEATING){
		time = sinceIdleTime;
	}
	else if(state==COOLING_MIN_TIME){
		time = MIN_COOL_ON_TIME-sinceIdleTime;
	}
	
	else if(state==HEATING_MIN_TIME){
		time = MIN_HEAT_ON_TIME-sinceIdleTime;
	}
	else if(state == WAITING_TO_COOL || state == WAITING_TO_HEAT){
		time = tempControl.getWaitTime();
	}
	if(time != UINT16_MAX){
		char timeString[10];
#if DISPLAY_TIME_HMS  // 96 bytes more space required. 
		unsigned int minutes = time/60;		
		unsigned int hours = minutes/60;
		int stringLength = sprintf_P(timeString, PSTR("%dh%02dm%02d"), hours, minutes%60, time%60);
		char * printString = timeString;
		if(!hours){
			printString = &timeString[2];
			stringLength = stringLength-2;
		}
		printAt(20-stringLength, 3, printString);
#else
		int stringLength = sprintf_P(timeString, STR_FMT_U, (unsigned int)time);
		printAt(20-stringLength, 3, timeString);
#endif		
	}
}
Example #22
0
    void draw_quad(int qi, int qj,
		   vector<int>& imin, vector<int>& imax
	) {
	int i,j;
	double u, v;
	double v0, v1, v2, v3, v4;
	// Coordonnees du quad dans l'offscreen
	double ax = (X.value(qj+0,qi+0)-x1)*m_dx, ay=(Y.value(qj+0,qi+0)-y1)*m_dy;
	double bx = (X.value(qj+0,qi+1)-x1)*m_dx, by=(Y.value(qj+0,qi+1)-y1)*m_dy;
	double cx = (X.value(qj+1,qi+1)-x1)*m_dx, cy=(Y.value(qj+1,qi+1)-y1)*m_dy;
	double dx = (X.value(qj+1,qi+0)-x1)*m_dx, dy=(Y.value(qj+1,qi+0)-y1)*m_dy;
	// indice des sommets (A,B,C,D)<->0,1,2,3<->(qi,qj),(qi+1,qj),(qi+1,qj+1),(qi,qj+1)
	// trie par ordre x croissant ou y croissant (selon xarg, yarg)
	double ymin = min(ay,min(by,min(cy,dy)));
	double ymax = max(ay,max(by,max(cy,dy)));

	int i0 = int(ymin+.5);
	int i1 = int(ymax+.5);
//	printf("Quads: i=%d->%d\n", i0, i1);

	if (i0<0) i0=0;
	if (i1>=D.ni) i1=D.ni-1;
	if (i1<i0) return;

	iymin = min(iymin,i0);
	iymax = max(iymax,i1);
	for(i=i0;i<=i1;++i) {
	    imax[i]=-1;
	    imin[i]=D.nj;
	}

	// Compute the rasterized border of the quad
	bool visible = false;
	visible |= vert_line(ax,ay,bx,by,D.nj,imin,imax, border, 0xff000000, D);
	visible |= vert_line(bx,by,cx,cy,D.nj,imin,imax, border, 0xff000000, D);
	visible |= vert_line(cx,cy,dx,dy,D.nj,imin,imax, border, 0xff000000, D);
	visible |= vert_line(dx,dy,ax,ay,D.nj,imin,imax, border, 0xff000000, D);
	if (!visible)
	    return;

	double ex = ax+cx-dx-bx;
	double ey = ay+cy-dy-by;
	double n = 1./sqrt((cx-ax)*(cx-ax)+(cy-ay)*(cy-ay));
	if (n>1e2) n = 1.0;

	// Normalize vectors with ||AC||
	ax *= n; ay *= n;
	bx = bx*n-ax; by = by*n-ay;
	cx = cx*n-ax; cy = cy*n-ay;
	dx = dx*n-ax; dy = dy*n-ay;
	ex *= n; ey *= n;

	v1 = Z.value(qj,qi);
	v2 = Z.value(qj+1,qi);
	v3 = Z.value(qj+1,qi+1);
	v4 = Z.value(qj,qi+1);

	if (isnan(v1) || isnan(v2) || isnan(v3) || isnan(v4)) {
	    // XXX Color = Alpha
	    return ;
	}
	int dm=0, dM=0;
	if (border) {
	    dm=1;dM=-1;
	}
	npy_uint32 col = scale.eval( v1*(1-vflat)*(1-uflat) +
				 v2*  vflat  *(1-uflat) +
				 v3*  vflat  *  uflat   +
				 v4*(1-vflat)*  uflat   );
	for(i=i0+dm;i<=i1+dM;++i) {
	    ixmin = min(ixmin,imin[i]);
	    ixmax = max(ixmax,imax[i]);
	    int jmin=max(0,imin[i])+dm;
	    int jmax=min(imax[i],D.nj-1)+dM;
	    for(j=jmin;j<=jmax;++j) {
		if (!flat) {
		    params(j*n,i*n, ax,ay, bx,by, cx,cy, dx,dy, ex,ey, u,v);
		    if (u<0) u=0.; else if (u>1.) u=1.;
		    if (v<0) v=0.; else if (v>1.) v=1.;
		    /* v0 = v1*(1-v)*(1-u) + v2*v*(1-u) + v3*v*u + v4*(1-v)*u; */
		    v0 = u*( v*(v1-v2+v3-v4)+v4-v1 ) + v*(v2-v1) + v1;
		    col = scale.eval(v0);
		}
		D.value(j,i) = col;
	    }
	}
    }
Example #23
0
void CBumpWater::UpdateCoastmap(const int x1, const int y1, const int x2, const int y2)
{
	glDisable(GL_BLEND);
	glDepthMask(GL_FALSE);
	glDisable(GL_DEPTH_TEST);

	coastFBO.Bind();

	glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, coastTexture[1]);
	glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, coastTexture[0]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glMatrixMode(GL_TEXTURE);
		glPushMatrix();
		glLoadIdentity();
		glScalef(1.0f/gs->mapx, 1.0f/gs->mapy, 1);
	glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		glOrtho(0,1,0,1,-1,1);
	glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadIdentity();
		glScalef(1.0f/gs->mapx, 1.0f/gs->mapy, 1);

	glViewport(0,0,gs->mapx, gs->mapy);
	glUseProgram(blurShader);

	int xmin = max(x1 - 10*2,0);
	int xmax = min(x2 + 10*2,gs->mapx);
	int ymin = max(y1 - 10*2,0);
	int ymax = min(y2 + 10*2,gs->mapy);
	int xsize = xmax - xmin;
	int ysize = ymax - ymin;

	glUniform2f(blurDirLoc,1.0f/gs->mapx,0.0f);
	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
	glUniform1i(blurTexLoc,1);

	glBegin(GL_QUADS);
		glTexCoord2f(xmin,ymin); glVertex2f(xmin,ymin);
		glTexCoord2f(xmin,ymax); glVertex2f(xmin,ymax);
		glTexCoord2f(xmax,ymax); glVertex2f(xmax,ymax);
		glTexCoord2f(xmax,ymin); glVertex2f(xmax,ymin);
	glEnd();

	for (int i=0; i<5; ++i){
		glUniform2f(blurDirLoc,0.0f,1.0f/gs->mapy);
		glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
		glUniform1i(blurTexLoc,0);

		glBegin(GL_QUADS);
			glTexCoord2f(xmin,ymin); glVertex2f(xmin,ymin);
			glTexCoord2f(xmin,ymax); glVertex2f(xmin,ymax);
			glTexCoord2f(xmax,ymax); glVertex2f(xmax,ymax);
			glTexCoord2f(xmax,ymin); glVertex2f(xmax,ymin);
		glEnd();

		glUniform2f(blurDirLoc,1.0f/gs->mapx,0.0f);
		glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
		glUniform1i(blurTexLoc,1);

		glBegin(GL_QUADS);
			glTexCoord2f(xmin,ymin); glVertex2f(xmin,ymin);
			glTexCoord2f(xmin,ymax); glVertex2f(xmin,ymax);
			glTexCoord2f(xmax,ymax); glVertex2f(xmax,ymax);
			glTexCoord2f(xmax,ymin); glVertex2f(xmax,ymin);
		glEnd();
	}

	glMatrixMode(GL_TEXTURE);
		glPopMatrix();
	glMatrixMode(GL_PROJECTION);
		glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
		glPopMatrix();

	//glActiveTexture(GL_TEXTURE0);
	//glBindTexture(GL_TEXTURE_2D, coastTexture[0]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glGenerateMipmapEXT(GL_TEXTURE_2D);

	glUseProgram(0);
	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);

	coastFBO.Unbind();
}
bool Brents1DMinimization<Scalar>::approxMinimize(
  const MeritFunc1DBase<Scalar> &phi,
  const PointEval1D<Scalar> &pointLower,
  const Ptr<PointEval1D<Scalar> > &pointMiddle,
  const PointEval1D<Scalar> &pointUpper,
  const Ptr<int> &numIters
  ) const
{

  using Teuchos::as;
  using Teuchos::TabularOutputter;
  typedef Teuchos::TabularOutputter TO;
  typedef ScalarTraits<Scalar> ST;
  using Teuchos::OSTab;
  typedef PointEval1D<Scalar> PE1D;
  using std::min;
  using std::max;
  
#ifdef TEUCHOS_DEBUG
  TEUCHOS_TEST_FOR_EXCEPT(is_null(pointMiddle));
  TEUCHOS_ASSERT_INEQUALITY(pointLower.alpha, <, pointMiddle->alpha);
  TEUCHOS_ASSERT_INEQUALITY(pointMiddle->alpha, <, pointUpper.alpha);
  TEUCHOS_ASSERT_INEQUALITY(pointLower.phi, !=, PE1D::valNotGiven());
  TEUCHOS_ASSERT_INEQUALITY(pointMiddle->phi, !=, PE1D::valNotGiven());
  TEUCHOS_ASSERT_INEQUALITY(pointUpper.phi, !=, PE1D::valNotGiven());
#endif

  const RCP<Teuchos::FancyOStream> out = this->getOStream();

  *out << "\nStarting Brent's 1D minimization algorithm ...\n\n";
  
  TabularOutputter tblout(out);
  
  tblout.pushFieldSpec("itr", TO::INT);
  tblout.pushFieldSpec("alpha_a", TO::DOUBLE);
  tblout.pushFieldSpec("alpha_min", TO::DOUBLE);
  tblout.pushFieldSpec("alpha_b", TO::DOUBLE);
  tblout.pushFieldSpec("phi(alpha_min)", TO::DOUBLE);
  tblout.pushFieldSpec("alpha_b - alpha_a", TO::DOUBLE);
  tblout.pushFieldSpec("alpha_min - alpha_avg", TO::DOUBLE);
  tblout.pushFieldSpec("tol", TO::DOUBLE);

  tblout.outputHeader();
  
  const Scalar INV_GOLD2=0.3819660112501051518; // (1/golden-ratio)^2
  const Scalar TINY = ST::squareroot(ST::eps());
  
  const Scalar alpha_l = pointLower.alpha, phi_l = pointLower.phi;
  Scalar &alpha_m = pointMiddle->alpha, &phi_m = pointMiddle->phi;
  const Scalar alpha_u = pointUpper.alpha, phi_u = pointUpper.phi;

  Scalar d = ST::nan();
  Scalar e = ST::nan();
  Scalar u = ST::nan();
  
  Scalar phi_w = min(phi_l, phi_u);

  Scalar alpha_v = ST::nan();
  Scalar alpha_w = ST::nan();
  Scalar phi_v = ST::nan();

  if (phi_w == phi_l){  
    alpha_w  = alpha_l;
    alpha_v  = alpha_u;
    phi_v = phi_u;
  }
  else {
    alpha_w  = alpha_u;
    alpha_v  = alpha_l;
    phi_v = phi_l;
  }

  Scalar alpha_min = alpha_m;
  Scalar phi_min = phi_m;
  Scalar alpha_a = alpha_l;
  Scalar alpha_b = alpha_u;
  
  bool foundMin = false;

  int iteration = 0;

  for ( ; iteration <= max_iters_; ++iteration) {

    if (iteration < 2)
      e = 2.0 * (alpha_b - alpha_a);

    const Scalar alpha_avg = 0.5 *(alpha_a + alpha_b);
    const Scalar tol1 = rel_tol_ * ST::magnitude(alpha_min) + TINY;
    const Scalar tol2 = 2.0 * tol1;

    const Scalar step_diff = alpha_min - alpha_avg;
    const Scalar step_diff_tol = (tol2 + bracket_tol_ * (alpha_b - alpha_a));

    // 2009/02/11: rabartl: Above, I changed from (tol2-0.5*(alpha_b-alpha_a)) which is
    // actually in Brent's netlib code!  This gives a negative tolerence when
    // the solution alpha_min is near a minimum so you will max out the iters because
    // a possitive number can never be smaller than a negative number.  The
    // above convergence criteria makes sense to me.

    tblout.outputField(iteration);
    tblout.outputField(alpha_a);
    tblout.outputField(alpha_min);
    tblout.outputField(alpha_b);
    tblout.outputField(phi_min);
    tblout.outputField(alpha_b - alpha_a);
    tblout.outputField(step_diff);
    tblout.outputField(step_diff_tol);
    tblout.nextRow();

    // If the difference between current point and the middle of the shrinking
    // interval [alpha_a, alpha_b] is relatively small, then terminate the
    // algorithm.  Also, terminate the algorithm if this difference is small
    // relative to the size of alpha.  Does this make sense?  However, don't
    // terminate on the very first iteration because we have to take at least
    // one step.
    if (
      ST::magnitude(step_diff) <= step_diff_tol
      && iteration > 0
      )
    {
      foundMin = true;
      break;
    }
    // 2009/02/11: rabartl: Above, I added the iteration > 0 condition because
    // the original version that I was given would terminate on the first
    // first iteration if the initial guess for alpha happened to be too close
    // to the midpoint of the bracketing interval!  Is that crazy or what!

    if (ST::magnitude(e) > tol1 || iteration < 2) {

      const Scalar r = (alpha_min - alpha_w) * (phi_min - phi_v);
      Scalar q = (alpha_min - alpha_v) * (phi_min - phi_w);
      Scalar p = (alpha_min - alpha_v) * q - (alpha_min - alpha_w) * r;
      q = 2.0 * (q - r);
      if (q > ST::zero())
        p = -p;
      q = ST::magnitude(q);
      const Scalar etemp = e;
      e = d;

      if ( ST::magnitude(p) >= ST::magnitude(0.5 * q * etemp)
        || p <= q * (alpha_a - alpha_min)
        || p >= q * (alpha_b - alpha_min)
        )
      {
        e = (alpha_min >= alpha_avg ? alpha_a - alpha_min : alpha_b - alpha_min);
        d = INV_GOLD2 * e;
      }
      else {
        d = p/q;
        u = alpha_min + d;
        if (u - alpha_a < tol2 || alpha_b - u < tol2) 
           // sign(tol1,alpha_avg-alpha_min)
          d = ( alpha_avg - alpha_min > ST::zero()
            ? ST::magnitude(tol1)
            : -ST::magnitude(tol1) );
      }

    }
    else {

      e = (alpha_min >= alpha_avg ? alpha_a - alpha_min : alpha_b - alpha_min);
      d = INV_GOLD2 * e;

    }
    
    u = ( ST::magnitude(d) >= tol1
      ? alpha_min + d
      : alpha_min + (d >= 0 ? ST::magnitude(tol1) : -ST::magnitude(tol1))
      ); 
    
    const Scalar phi_eval_u = computeValue<Scalar>(phi, u);

    if (phi_eval_u <= phi_min) {

      if (u >= alpha_min)
        alpha_a = alpha_min;
      else
        alpha_b = alpha_min;

      alpha_v = alpha_w;
      phi_v = phi_w;
      alpha_w = alpha_min;
      phi_w = phi_min;
      alpha_min = u;
      phi_min = phi_eval_u;

    }
    else {

      if (u < alpha_min)
        alpha_a = u;
      else
        alpha_b = u;

      if (phi_eval_u <= phi_w || alpha_w == alpha_min) {
        alpha_v = alpha_w;
        phi_v = phi_w;
        alpha_w = u;
        phi_w = phi_eval_u;
      }
      else if (phi_eval_u <= phi_v || alpha_v == alpha_min || alpha_v == alpha_w) {
        alpha_v = u;
        phi_v = phi_eval_u;
      }

    }
  }

  alpha_m = alpha_min;
  phi_m = phi_min;
  if (!is_null(numIters))
    *numIters = iteration;
  
  if (foundMin) {
    *out <<"\nFound the minimum alpha="<<alpha_m<<", phi(alpha)="<<phi_m<<"\n";
  }
  else {
    *out <<"\nExceeded maximum number of iterations!\n";
  }

  *out << "\n";

  return foundMin;

}
Example #25
0
/**
 * Calculates the turn rate and the derived features.
 * Determines the current flight mode (cruise/circling).
 */
void
GlideComputerAirData::Turning()
{
  // You can't be circling unless you're flying
  if (!Basic().flight.Flying || !time_advanced())
    return;

  // JMW limit rate to 50 deg per second otherwise a big spike
  // will cause spurious lock on circling for a long time
  fixed Rate = max(fixed(-50), min(fixed(50), Basic().TurnRate));

  // average rate, to detect essing
  // TODO: use rotary buffer
  static fixed rate_history[60];
  fixed rate_ave = fixed_zero;
  for (int i = 59; i > 0; i--) {
    rate_history[i] = rate_history[i - 1];
    rate_ave += rate_history[i];
  }
  rate_history[0] = Rate;
  rate_ave /= 60;

  // Make the turn rate more smooth using the LowPassFilter
  Rate = LowPassFilter(LastCalculated().SmoothedTurnRate, Rate, fixed(0.3));
  SetCalculated().SmoothedTurnRate = Rate;

  // Determine which direction we are circling
  bool LEFT = false;
  if (negative(Rate)) {
    LEFT = true;
    Rate *= -1;
  }

  // Calculate circling time percentage and call thermal band calculation
  PercentCircling(Rate);

  // Force cruise or climb mode if external device says so
  bool forcecruise = false;
  bool forcecircling = false;
  if (SettingsComputer().EnableExternalTriggerCruise && !Basic().gps.Replay) {
    forcecircling = triggerClimbEvent.test();
    forcecruise = !forcecircling;
  }

  switch (Calculated().TurnMode) {
  case CRUISE:
    // If (in cruise mode and beginning of circling detected)
    if ((Rate >= MinTurnRate) || (forcecircling)) {
      // Remember the start values of the turn
      SetCalculated().TurnStartTime = Basic().Time;
      SetCalculated().TurnStartLocation = Basic().Location;
      SetCalculated().TurnStartAltitude = Basic().NavAltitude;
      SetCalculated().TurnStartEnergyHeight = Basic().EnergyHeight;
      SetCalculated().TurnMode = WAITCLIMB;
    }
    if (!forcecircling)
      break;

  case WAITCLIMB:
    if (forcecruise) {
      SetCalculated().TurnMode = CRUISE;
      break;
    }
    if ((Rate >= MinTurnRate) || (forcecircling)) {
      if (((Basic().Time - Calculated().TurnStartTime) > CruiseClimbSwitch)
          || forcecircling) {
        // yes, we are certain now that we are circling
        SetCalculated().Circling = true;

        // JMW Transition to climb
        SetCalculated().TurnMode = CLIMB;

        // Remember the start values of the climbing period
        SetCalculated().ClimbStartLocation = Calculated().TurnStartLocation;
        SetCalculated().ClimbStartAlt = Calculated().TurnStartAltitude
            + Calculated().TurnStartEnergyHeight;
        SetCalculated().ClimbStartTime = Calculated().TurnStartTime;

        // set altitude for start of circling (as base of climb)
        OnClimbBase(Calculated().TurnStartAltitude);

        // consider code: InputEvents GCE - Move this to InputEvents
        // Consider a way to take the CircleZoom and other logic
        // into InputEvents instead?
        // JMW: NO.  Core functionality must be built into the
        // main program, unable to be overridden.
        OnSwitchClimbMode(true, LEFT);
      }
    } else {
      // nope, not turning, so go back to cruise
      SetCalculated().TurnMode = CRUISE;
    }
    break;

  case CLIMB:
    if ((Rate < MinTurnRate) || (forcecruise)) {
      // Remember the end values of the turn
      SetCalculated().TurnStartTime = Basic().Time;
      SetCalculated().TurnStartLocation = Basic().Location;
      SetCalculated().TurnStartAltitude = Basic().NavAltitude;
      SetCalculated().TurnStartEnergyHeight = Basic().EnergyHeight;

      // JMW Transition to cruise, due to not properly turning
      SetCalculated().TurnMode = WAITCRUISE;
    }
    if (!forcecruise)
      break;

  case WAITCRUISE:
    if (forcecircling) {
      SetCalculated().TurnMode = CLIMB;
      break;
    }
    if((Rate < MinTurnRate) || forcecruise) {
      if (((Basic().Time - Calculated().TurnStartTime) > ClimbCruiseSwitch)
          || forcecruise) {
        // yes, we are certain now that we are cruising again
        SetCalculated().Circling = false;

        // Transition to cruise
        SetCalculated().TurnMode = CRUISE;
        SetCalculated().CruiseStartLocation = Calculated().TurnStartLocation;
        SetCalculated().CruiseStartAlt = Calculated().TurnStartAltitude;
        SetCalculated().CruiseStartTime = Calculated().TurnStartTime;

        OnClimbCeiling();

        OnSwitchClimbMode(false, LEFT);
      }
    } else {
      // nope, we are circling again
      // JMW Transition back to climb, because we are turning again
      SetCalculated().TurnMode = CLIMB;
    }
    break;

  default:
    // error, go to cruise
    SetCalculated().TurnMode = CRUISE;
  }
}
Example #26
0
void MusRC::DrawBeamOriginal(  MusDC *dc, MusLayer *layer, MusStaff *staff )
{
	struct MusLayerElement *chk;
	static struct fb {
		unsigned _liaison : 1;	/* temoin pour liaison: si ON, il y a
                                 de la liaison dans l'air et beam doit
                                 doit appeler liaison_note. Cfr.liais_note()*/
		unsigned mrq_port : 2;	/* ON si changement in yy; necessaire
                                 pour decider beams lorsque 2 portees */
		unsigned mq_val   : 1;	/* marqueur de changement de valeur*/
		unsigned fl_cond : 1;	/* flags concernant partage portees */
		unsigned flsht    : 3;	/* garde le pnt->_shport */
		unsigned dir	  : 3;	/* marqueur direction queues */
		unsigned _grp	  : 1;	/* marqueur de groupes rythmiques */
	}	fb;
	int iHauteur=0;
	float fPente = 0.0;
	int ct;			/* compteur d'entree */
	int _ct;		/* compte d'entree moins 1 */
	int cpte_stop;	/* compteur de st_rl */
	unsigned st_rl[NbFRACTURES];	/* garde les ruptures de beams */
	int _yy[2];		/* garde dernier yy pour test mrq_port*/
	static int _ybeam[NbREL];	/* garde les sommets de queues  */
	int shortest, valref;	/* garde valeur la plus breve
                             * m_dur. de reference */
	double high;
	double low;		/* gardent les y extremes */
	double dx[2];			/* rayon / 2 */
	double y_moy;		/* calcul de moyenne y pour dir */
	double s_x=0.0, s_y=0.0, s_xy=0.0, s_x2=0.0, s_y2=0.0;	/* sommes pour la regress. */
	double xr;				/* variables de travail */
	double delt_y, barre_y, ecart, y1;
	double sy_dec_moy, sy_dec[2];
	double fbarre_y;
	int mx_i[MAX_MIF], mx_f[MAX_MIF], my_i[MAX_MIF], my_f[MAX_MIF];
	char m_i[MAX_MIF];	/* pour stocker les prov des marqueurs */
	int fx1,fx2,fy1,fy2;		/* coord. */
	float milieu;
    
	int i, j, t, h, k, si;		/* compteurs de boucles */
	int _mif, decalage;
	int valtest;			/* travail */
	int apax;	 	/* test pour valeur breve isolee en debut  de groupes */
	//int provshp=0;
	int deltabar, deltanbbar, deltablanc;
    
	if (!calcBeam)	/* eviter side-effect de circuit... */
	{	fb._liaison = OFF;
		fb._grp = OFF;			/* reinitialisation du test (static) */
	}
	if (layer->beamListPremier == NULL) return;
	chk = layer->beamListPremier;
    //	bch.markchrd = shortest = fb.mq_val = valref = ct = cpte_stop = fb.mrq_port = OFF;
	bch.markchrd = 0;
	shortest = 0;
	fb.mq_val = 0;
	valref = ct = cpte_stop = 0;
	fb.mrq_port = OFF;
	high = y_moy = sy_up = sy_dec_moy = 0.0;
	for (i=0; i<NbFRACTURES; i++)
		st_rl[i] = 0;
	/***if (e_t->_shport) { provshp = e_t->_shport; shportee (0);}***/
    /* retablir a la fin si provshp existe */
    
	low = chk->m_y_drawing + staff->m_y_drawing;	/* initialiser */
    k = ((MusNote*)chk->m_layerElement)->m_colored ? ((MusNote*)chk->m_layerElement)->m_dur+1 : ((MusNote*)chk->m_layerElement)->m_dur;
	valref = k;		/* m_dur test conservee */
    //	valref = chk->m_dur;		/* m_dur test conservee */
	fb.flsht = 0;
    
	if (staff->notAnc) {
		dx[0] = dx[1] = 0.0;
    } 
    else
    {	
        dx[0] =  m_layout->m_noteRadius[staff->staffSize][0] - ((m_layout->m_noteRadius[staff->staffSize][0] * m_layout->m_env.m_stemCorrection) / 20);
        dx[1] =  m_layout->m_noteRadius[staff->staffSize][1] - ((m_layout->m_noteRadius[staff->staffSize][1] * m_layout->m_env.m_stemCorrection) / 20);
        dx[0] -= (m_layout->m_env.m_stemWidth)/2;
        dx[1] -= (m_layout->m_env.m_stemWidth)/2;
    }
	_yy[0] = staff->m_y_drawing;	
    
    /***
     if (calcBeam)	// eviter side-effect de circuit...
     {	extern_q_auto = chk->m_stemLen;
     extern_queue =  chk->m_stemDir;
     }
     ***/
    
    extern_q_auto = ((MusNote*)chk->m_layerElement)->m_stemLen;
    extern_queue =  ((MusNote*)chk->m_layerElement)->m_stemDir;
    
	do
	{
		if (chk->IsNote() || (((MusNote*)chk->m_layerElement)->m_beam[0] & BEAM_INITIAL) || (((MusNote*)chk->m_layerElement)->m_beam[0] & BEAM_TERMINAL))
			k = ((MusNote*)chk->m_layerElement)->m_colored ? ((MusNote*)chk->m_layerElement)->m_dur+1 : ((MusNote*)chk->m_layerElement)->m_dur;
        
        // if (chk->type == NOTE && /*chk->sil == _NOT &&*/ k > DUR_4)
		if (chk->IsNote() || (((MusNote*)chk->m_layerElement)->m_beam[0] & BEAM_INITIAL) || (((MusNote*)chk->m_layerElement)->m_beam[0] & BEAM_TERMINAL) && k > DUR_4)
		{	(crd+ct)->chk = chk;
			/* garantir uniformite des flags */
            
			if (!calcBeam)	/* on ne se limite pas au calcul des queues */
			{	
                ((MusNote*)chk->m_layerElement)->m_stemLen = extern_q_auto;
				if (!extern_q_auto)	((MusNote*)chk->m_layerElement)->m_stemDir = extern_queue;
				if ( !fb._liaison && (((MusNote*)chk->m_layerElement)->m_slur[0] & SLUR_TERMINAL)) {
					fb._liaison = ON;
                }
                /***if (chk->grp==END) {	
                 fb._grp = ON; 
                 group.fin = chk;
                 }***/
			}
			/***if (!fb.mrq_port && chk->_shport) {
             fb.mrq_port = chk->_shport;
             }***/
            
			(crd+ct)->a = chk->m_x_abs + chk->m_layerElement->m_hOffset - m_layout->m_env.m_stemWidth / 2;		/* enregistrement des coord. */
			(crd+ct)->vlr = k;
			if (((MusNote*)chk->m_layerElement)->m_breakSec && ct)
			/* enregistr. des ruptures de beaming; des la 2e note;(autrement idiot)*/
				*(st_rl + (cpte_stop++)) = ct;
            
			/***if (extern_q_auto && chk->chord)
             {	bch.markchrd=ON;
             fb.flsht = fb.flsht ? fb.flsht : chk->_shport;
             }***/
            if (chk->IsNote())	// Çviter de prendre en compte silences
            {			shortest = max (k,shortest);
                if (!fb.mq_val && k != valref)
                    fb.mq_val = ON; /* plus d'une valeur est presente*/
                valref = min (k,valref);
            }
			ct++;
		}
		if (((MusNote*)chk->m_layerElement)->m_beam[0] & BEAM_TERMINAL) 
            break;
		chk = layer->GetNext(chk);
		if (chk == NULL) { 
            layer->beamListPremier = NULL;
            return;
        }
	}	while (ct < NbREL);
    
    // SECURITE : EVITER DE BARRER UN ACCORD ISOLE...
	if (chk->IsNote() && (((MusNote*)chk->m_layerElement)->m_chord & CHORD_TERMINAL)  && (chk->m_x_abs == layer->beamListPremier->m_x_abs))
	{	chk = layer->beamListPremier;
		do {	
            ((MusNote*)chk->m_layerElement)->m_beam[0] = 0;
            chk = layer->GetNext(chk);
        }	while (chk && chk->IsNote() && !((MusNote*)chk->m_layerElement)->m_chord & CHORD_TERMINAL);
		layer->beamListPremier = NULL;
		return;
	}
    
    wxLogDebug("ct %d", ct );
    
	_ct = ct - 1;		/* compte d'entree moins 1 */
    
	/* ici, verifier la provenance (haut/bas) des queues en cas de
     partage entre portees, et repasser la liste */
    /***
     if (fb.mrq_port)
     // le y le plus haut est dans _yy[0] 
     {	if (fb.mrq_port==1)
     {	_yy[0] = (this != phead) ? staff->ptr_pp->m_y_drawing : staff->m_y_drawing; 
     _yy[1] = staff->m_y_drawing;
     }
     else
     {	_yy[1] = (this != ptail) ? staff->ptr_fp->m_y_drawing : staff->m_y_drawing; 
     _yy[0] = staff->m_y_drawing;
     }
     }
     ***/
	for (i = 0; i < ct; i++)
	{	switch (fb.mrq_port)
		{	case 0: crd[i].prov = OFF;
                (crd+i)->b = crd[i].chk->m_y_drawing+staff->m_y_drawing;
                break;
			case 1: if (crd[i].chk->m_layerElement->m_staffShift)
            {	crd[i].prov = ON;
                (crd+i)->b = crd[i].chk->m_y_drawing + _yy[0];
            }
            else
            {	crd[i].prov = OFF;
                (crd+i)->b = crd[i].chk->m_y_drawing + _yy[1];
            }
                break;
			case 2: if (crd[i].chk->m_layerElement->m_staffShift)
            {	crd[i].prov = OFF;
                (crd+i)->b = crd[i].chk->m_y_drawing + _yy[1];
            }
            else
            {	crd[i].prov = ON;
                (crd+i)->b = crd[i].chk->m_y_drawing + _yy[0];
            }
		}
		high= max ((double)(crd+i)->b,high);		/* enregistrement des extremes */
		low = min ((double)(crd+i)->b,low);
        /* lie au choix, plus bas, d'introduire l'accelerateur pour sy_up...
         if ((crd+i)->b==high) highIndice = i;
         if ((crd+i)->b==low) lowIndice = i;
         */
		y_moy += crd[i].b;
	}
    /***
     if (provshp)
     shportee (provshp);
     ***/
    
	if (ct<2) {
        layer->beamListPremier = NULL;
		return;		/* test erreur input */
    }
    
    
	fb.dir = OFF;
	if (extern_q_auto && (!fb.mrq_port)) /*** || (bch.inpt && bch.markchrd))) ***/
	/* direction queues: auto = moyenne */
	/* bch.inpt: le flot de donnees a ete envoye par input et non rd_objet */
	{	
        milieu = _yy[0] - (m_layout->m_staffSize[staff->staffSize] + m_layout->m_interl[staff->staffSize] * 2);
		y_moy /= ct;
		if ( y_moy <  milieu )
			fb.dir = ON;
        
		if (bch.inpt && bch.markchrd)
		/* entree de input: de l'accord est dans l'air */
		{	if (!fb.flsht)
            return;  //(fb.dir+1);
        else
            return; //(fb.flsht+2);
            /* ce sera la valeur de bch.beam_chrd retournee a input; beam() sera
             rappelee par corrchrd() qui se sert de bch. ... */
		}
	}
	else
		fb.dir = extern_queue;	// si mrq_port, dir tjrs egal a m_stemDir
    
    if (crd[_ct].chk->m_layerElement->m_cueSize == false)
    {
        deltanbbar = m_layout->m_beamWidth[staff->staffSize];
        deltablanc = m_layout->m_beamWhiteWidth[staff->staffSize];
    }
    else
    {	deltanbbar = max (2, (m_layout->m_beamWidth[staff->staffSize]/2));
        deltablanc = max (2, (m_layout->m_beamWhiteWidth[staff->staffSize]-1));
    }
	deltabar = deltanbbar + deltablanc;
    
    
    /* Calcul des sommes et facteurs s_y, s_xy necessaires a la regression.
     La regression se base sur les sommets des queues, calculÇs en ajoutant un
     Çcart standard fonction de la valeur la plus breve enregistree. Direction
     connue, donc ajout ou retrait de l'ecart, et correction du x d'origine en
     fonction de la direction.*/
    
    /***
     if (crd[_ct].chk->existDebord)
     {	ptdebord = (Debord *)chk->pdebord;
     ptdebord ++;	// pointe sur valeurs
     ptBeamEd = (BeamEdit *)ptdebord;
     iHauteur = ptBeamEd->iHauteur;
     fPente = ptBeamEd->fPente;
     BeamEd = *ptBeamEd;
     }
     else ***/
    {	
        iHauteur = 0;
        fPente = 0.0;
    }
    
    /***
     if (fb.mrq_port && extern_q_auto)
     // deux portees concernees (partage), en mode automatique 
     {	ecart = e_t->m_layout->m_interl[staff->staffSize]*6;
     for (i=0; i<ct; i++)
     {	if ((crd+i)->prov)
     {	(crd+i)->a -= dx[crd[i].chk->dimin];
     *(_ybeam+i) = crd[i].b - ecart;
     crd[i].chk->m_stemDir = 0;
     }
     else
     {	(crd+i)->a += dx[crd[i].chk->dimin];
     *(_ybeam+i) = crd[i].b + ecart;
     crd[i].chk->m_stemDir = 1;
     }
     s_y += _ybeam[i];
     s_x += crd[i].a;
     s_x2 += crd[i].a * crd[i].a;
     s_xy += crd[i].a * _ybeam[i];
     }
     }
     else ***/
    
	// une seule portee; on tient compte de la direction precedemment calculee*/
	{	
        ecart = ((shortest-DUR_8)*(deltabar));
        
		if (crd[_ct].chk->m_layerElement->m_cueSize)
			ecart += m_layout->m_halfInterl[staff->staffSize]*5;
		else
            //   Le 24 Septembre 1993: obtenir des DUR_8 reliees a la hauteur des separees 
			ecart += (shortest > DUR_8) ? m_layout->m_interl[staff->staffSize]*hauteurBarreMoyenne : m_layout->m_interl[staff->staffSize]*(hauteurBarreMoyenne+0.5);
        
		if (!fb.dir && !staff->notAnc)
		{	dx[0] = - dx[0];
			dx[1] = - dx[1];
		}
        /***
         if (crd[_ct].chk->existDebord) {
         ecart = m_layout->m_interl[0]*2;
         if (!fb.mrq_port) extern_q_auto= 0;
         }
         ***/
        
		ecart = (fb.dir ? ecart : -ecart);
        
		y_moy += ecart;
		if (extern_q_auto && ((fb.dir && y_moy <  milieu) || (!fb.dir && y_moy > milieu)) )
			ecart += milieu-y_moy;
        
		for (i=0; i<ct; i++)
		{	*(_ybeam+i) = crd[i].b + ecart;
			(crd+i)->a +=  dx[crd[i].chk->m_layerElement->m_cueSize];
			s_y += _ybeam[i];
 			s_y2 += _ybeam[i] * _ybeam[i];
			s_x += crd[i].a;
			s_x2 += crd[i].a * crd[i].a;
			s_xy += crd[i].a * _ybeam[i];
            if ( crd[i].chk->IsNote() ) {
                ((MusNote*)crd[i].chk->m_layerElement)->m_stemDir = fb.dir;
            }
		}
        
	}
    
	y1 = ct * s_xy - s_x * s_y;
	xr = ct * s_x2 - s_x * s_x;
    
	if (y1 && xr)	// securite: eviter division par 0 si deux x identiques
		dB = y1 / xr;
	else
		dB = 0.0;
	/* Correction esthetique : */
	if (fabs(dB) < m_layout->m_beamMinSlope ) dB = 0.0;
	if (fabs(dB) > m_layout->m_beamMaxSlope ) dB = (dB>0) ? m_layout->m_beamMaxSlope : - m_layout->m_beamMaxSlope;
	/* pente correcte: entre 0 et env 0.4 (0.2 a 0.4) */
    
    if (fPente)
        dB += fPente;
    
	dA = (s_y - dB * s_x) / ct;
    
    
	h = cpte_stop ? 1 : (!fb.mq_val ? (shortest - DUR_4) : 1); /***((fb.mrq_port && extern_q_auto)?(valref-DUR_4):1));***/
    /* nombre de barres a dessiner */
    
    
	/* flag condition: pour eviter tests complexes repetes in boucles;
	 * concerne les cas de partages entre portees. Vrai si pas de stop-rel
	 * (i.e. possibilite de plusieurs barres communes traversantes) */
    
	fb.fl_cond = OFF;
    
    /***
     if (fb.mrq_port && extern_q_auto)
     fb.fl_cond = ON;	// independamment de mq_val
     ***/
    
	if (fb.fl_cond)
	/*valeur pour allonger queues si partage entre portees et mode autom.*/
	{
		i = deltabar * h - deltablanc;	/* nombre de points de dec */
		j = i / 2;
		sy_dec[0] = j;
		sy_dec[1] = -sy_dec[0];
        
		if ( i % 2)
			sy_dec[1] -= 1;
		sy_dec_moy = sy_dec[0] + abs (sy_dec[1]);
	}
    
    if (iHauteur)
        dA += iHauteur;
    
	/* calcul du ybeam des queues */
	for ( i=0; i<ct; i++ )
	{	xr = *(_ybeam+i);	/* xr, variable de travail */
		*(_ybeam+i)= dA + sy_up + dB * crd[i].a;
		if (fb.fl_cond)
			*(_ybeam+i) += sy_dec [crd[i].prov];
		
		/* test pour garantir l'absence de recoupement */
        if (!iHauteur)
            if (!fb.mrq_port || !extern_q_auto)
            {	if ((fb.dir && xr > *(_ybeam+i)) || (!fb.dir && xr < *(_ybeam+i)))
            {	sy_up += xr - *(_ybeam+i);
                i = -1;	/* on refait la boucle avec un sy_up */
            }
            }	
        
        
	}
    
	if (calcBeam) return;
    
    
    
	/* dessin de la barre pilote et des queues */
    
	for (i=0; i<ct; i++)
	{
		if (fb.fl_cond)	/* esth: eviter que queues depassent barres */
		{	if (crd[i].prov)	/* venant du haut, m_stemDir en bas */
        {	/***fy1 = *(_ybeam+i)+v_pnt;***/	/* on raccourcit m_stemDir */
            fy2 = crd[i].b-m_layout->m_verticalUnit2[staff->staffSize];
        }
        else
        {	/***fy1 = *(_ybeam+i)-e_t->v_pnt;***/	/* on allonge m_stemDir */
            fy2 = crd[i].b+m_layout->m_verticalUnit2[staff->staffSize];
        }
		}
		else	// on tient compte de l'Çpaisseur qui fait des "bosses"
		{	if (fb.dir)	// m_stemDir en haut
        {	fy1 = *(_ybeam+i) - m_layout->m_env.m_stemWidth;
            fy2 = crd[i].b+m_layout->m_verticalUnit2[staff->staffSize];
        }
        else
        {	fy1 = *(_ybeam+i) + m_layout->m_env.m_stemWidth;
            fy2 = crd[i].b-m_layout->m_verticalUnit2[staff->staffSize];
        }
		}
		if ((crd+i)->chk->IsNote() && ((MusNote*)(crd+i)->chk)->m_headshape != SANSQUEUE)
		{	
            v_bline (dc,fy2, fy1, crd[i].a, m_layout->m_env.m_stemWidth);
            
            // ICI, bon endroit pour enfiler les STACCATOS - ne sont traitÈs ici que ceux qui sont opposÈs ‡ la tÍte (les autres, in wgnote.cpp)
			if (((MusNote*)(crd+i)->chk)->m_artic
                && (!((MusNote*)(crd+i)->chk)->m_chord || (((MusNote*)(crd+i)->chk)->m_chord & CHORD_TERMINAL)))
                // les cas non traitÈs par note()
            /*			{	if (fb.dir || (fb.mrq_port && m_stemLen && !crd[i].prov))
             putStacc (dc,crd[i].a-dx[crd[i].chk->dimin],fy1+e_t->m_layout->m_interl[staff->staffSize]-staff->m_y_drawing, 0,crd[i].chk->typStac);
             else
             putStacc (dc,crd[i].a-dx[crd[i].chk->dimin],fy1-e_t->m_layout->m_interl[staff->staffSize]-staff->m_y_drawing, -1,crd[i].chk->typStac);
             }
             */
			{	
                /***if (fb.mrq_port && extern_q_auto)
                 {	if (crd[i].prov)
                 putStacc (dc,crd[i].a+dx[crd[i].chk->dimin],fy1-e_t->m_layout->m_interl[staff->staffSize]-staff->m_y_drawing, -1,crd[i].chk->typStac);
                 else
                 putStacc (dc,crd[i].a-dx[crd[i].chk->dimin],fy1+e_t->m_layout->m_interl[staff->staffSize]-staff->m_y_drawing, 0,crd[i].chk->typStac);
                 }
                 else if (fb.dir)
                 putStacc (dc,crd[i].a-dx[crd[i].chk->dimin],fy1+e_t->m_layout->m_interl[staff->staffSize]-staff->m_y_drawing, 0,crd[i].chk->typStac);
                 else
                 putStacc (dc,crd[i].a-dx[crd[i].chk->dimin],fy1-e_t->m_layout->m_interl[staff->staffSize]-staff->m_y_drawing, -1,crd[i].chk->typStac);
                 ***/
			}
            
		}
        
	}
    
    // NOUVEAU
    // Correction des positions x extremes en fonction de l'Çpaisseur des queues
	(*crd).a -= (m_layout->m_env.m_stemWidth-1) / 3;
	(crd+_ct)->a += (m_layout->m_env.m_stemWidth-1) / 3;
    
	delt_y = (!fb.dir || fb.fl_cond ) ? 1.0 : -1.0;
	/* on choisit une direction pour faire le premier paquet horizontal */
    
	fy1 = *_ybeam; fy2 = *(_ybeam+_ct);
    
    
	if (fb.fl_cond)
    /* reequilibrage du tir horizontal: on aligne les beams sur les queues
     qui ont ete allongees selon leur direction pour couvrir l'epaisseur */
        
	{
		if (!crd[0].prov) fy1 -=  sy_dec_moy;
		if (!crd[_ct].prov) fy2 -= sy_dec_moy;
	}
    
	fx1 = (*crd).a; fx2 = (crd+_ct)->a;
    
    
	/* dessin des barres supplementaires jusqu'a concurrence de la valeur
	 *  minimum commune a tout le groupe: i.e. une seule s'il y a des "stoprel"
	 *  (fragmentation de beaming), ou sinon valref (ou h).
     */
	/* chk->cone est le flag des cones d'acc. et ralent. */
	//s_y = crd[0].chk->cone ? 0.0 : delt_y; // removed in ax2
	//s_y2 = (crd+_ct)->chk->cone ? 0.0 : delt_y; // removed in ax2
	s_y = delt_y; // removed in ax2
	s_y2 = delt_y; // removed in ax2
    
	for (j=0; j<h ; j++)
	{
		decalage = hGrosseligne (dc,fx1,fy1,fx2,fy2, deltanbbar*delt_y /***, workColor2***/);
		fy1 += decalage; fy2 += decalage;
        
        /* ici, redescendre  de l'epaisseur de la barre s'il y a accele */
		if (!s_y)
			fy1 += (deltanbbar * delt_y) * -1;
		else
			fy1 += s_y*deltablanc;
		if (!s_y2)
			fy2 += (deltanbbar * delt_y) * -1;
		else
			fy2 += s_y2*deltablanc;
	}
    
	/* calcul des x en cas de beaming multiple */
	/* parcours horizontal ajoutant barres en fonction de m_dur la plus 
     breve (shortest), controle par boucle while; la premiere boucle for
     controle le nombre d'etapes horizontales du parcours (par le nombre
     de commandes '+' enregistrees); la deuxieme boucle for teste pour
     chaque paquet entre deux '+' les valeurs; elle construit une array de 
     marqueurs partitionnant les sous-groupes; la troisieme boucle for est
     pilotee par l'indice de l'array; elle dessine horizontalement les barres 
     de chaque sous-groupe en suivant les marqueurs */ 
    
    
	/* cpte_stop=0 ? pas de rupture de beaming*/
    
    if (fb.mq_val || cpte_stop)	/* deuxieme partie du test */
    {
        valtest = DUR_8 + h;
        
        if ( fb.fl_cond )
        {	barre_y = deltablanc + sy_dec_moy;
            /* = decalage entre bout de m_stemDir et position acquise des barres */
        }
        else	/* pas de partage entre portees */
            
            barre_y = deltabar;
        
        /* h contient nombre de barres communes deja dessinees */
        if (fb.dir)	/* queues ascendantes: on descend */
            barre_y = -barre_y;
        
        while (valtest <= shortest)
        {	t = 0; si = 0;
            for (i=0; i<=cpte_stop; i++)	/* 1e boucle for */
            {	h = (*(st_rl+si) ? *(st_rl+si) : ct);
                /* var. test controlant 2e boucle for suivante
                 * en fonction du compteur de "+" */
                /*ici, t=j, i.e. increment des pos. de notes. On s'occupe maintenant de
                 l'ensemble des valeurs contenues dans un groupe marque par cpte_stop. C'est
                 la qu'il faut changer les signes des valeurs delta d'increment vertical.*/
                
                for(k=0; k<MAX_MIF; k++)	/* initialisation*/
                {	mx_i[k]=my_i[k]=mx_f[k]=my_f[k]=0;}
                
                for (j=t,_mif=0,m_i[_mif]=0; j < h; j++)	/* 2e boucle. */
                {	/* j<h : st_rl est trop loin de un cran */
                    
                    /* Ici, dÇcision si SILENCE doit ou non avoir des barres; si oui, ligne
                     suivante (condition: il doit etre pris aussi dans les crd plus haut):*/
                    if (((crd+j)->vlr) >= (unsigned int)valtest)	
                    /*	si NON, alors: */
                        // if (((crd+j)->vlr) >= valtest && (crd+j)->chk->sil == _NOT)	
                    {
                        /*place marqueurs pour m_dur.egales/superieures
                         * a valtest en cours */
                        mx_f[_mif] = crd[j].a; 
                        my_f[_mif] = *(_ybeam+j);
                        if(!mx_i[_mif])
                        {	mx_i[_mif] = crd[j].a;
                            my_i[_mif] = *(_ybeam+j);
                            if (!_mif) apax = j;
                            if (!crd[j].prov)
                            /* enregistre les cas ou delta y est neg.*/
                                m_i[_mif] = 1;
                        }
                    }
                    /* rupture de chaine: on passe a un 2e groupe
                     * de marqueurs */
                    else if(mx_i[_mif])
                    {	_mif++;	/*incr. s'il y a un marq.*/
                        m_i[_mif] = 0;
                    }
                }
                
                fbarre_y = barre_y;	/* stockage */
                for (k=0; k<=min((mx_f[_mif]?_mif:(_mif-1)),MAX_MIF); k++)
                {
                    /* "constantes" de corr. definissant origine du calcul des
                     * y, dans les cas de partage entre portees automatiques;
                     * (construction anterieure en montant si fl_cond) */
                    if ( fb.fl_cond)
                    {	barre_y = abs(fbarre_y); delt_y = abs (delt_y);
                        
                        if (m_i[k])		/* i.e. portee inf. (!crd[j].prov) */
                        {	barre_y = -barre_y;
                            delt_y = -delt_y;
                            sy_up = sy_dec[0];	/* valeur positive */
                        }
                        
                        else
                            sy_up = sy_dec[1];	/* valeur negative */
                        
                    }
                    
                    
                    /* on passe en revue, horizontalement, les marqueurs
                     * enregistres pour ce  groupe, en s'assurant que le
                     * max MAX_MIF n'est pas depasse */
                    if (mx_i[k] == mx_f[k])		/* une seule position concernee */
                    {
                        if (apax == t && k==0 && mx_i[k] != crd[_ct].a)	/* au debut du paquet */
                        {	fy1 = my_i[k] + barre_y;
                            mx_f[k] = mx_i[k] + m_layout->m_ledgerLine[staff->staffSize][0];
                            fy2 = dA + sy_up + barre_y + dB * mx_f[k];
                            
                            decalage= hGrosseligne (dc,mx_i[k],fy1,mx_f[k],fy2,deltanbbar*delt_y /***, workColor2***/ );
                            fy1 += decalage; fy2 += decalage;
                            
                        }
                        else		/* corps ou fin de paquet */
                        {	fy2 = my_i[k] + barre_y;
                            mx_i[k] -= m_layout->m_ledgerLine[staff->staffSize][0];
                            fy1 = dA + sy_up + barre_y + dB * mx_i[k];
                            decalage= hGrosseligne (dc,mx_i[k],fy1,mx_f[k],fy2,deltanbbar*delt_y /***,workColor2***/);
                            fy1 += decalage; fy2 += decalage;
                            
                        }
                    }
                    else if (mx_i[k])		/* s'il y a un marqueur */
                    {	fy1 = my_i[k] + barre_y;
                        fy2 = my_f[k] + barre_y;
                        decalage= hGrosseligne (dc,mx_i[k],fy1,mx_f[k],fy2,deltanbbar*delt_y /***,workColor2***/);
                        fy1 += decalage; fy2 += decalage;
                        
                    }				
                }	/* fin de boucle testant sous-ensembles marques _mif*/
                
                if ( fb.fl_cond)	/* retablissement des valeurs positives */
                {	barre_y = abs(fbarre_y);
                    delt_y =  abs(delt_y);
                }
                
                if (*st_rl)
                {	si++; t = j;} 
                else t = 0;
            }			/* fin de premiere boucle for */
            
            valtest += 1;	/* increments de valeur et d'espace */
            barre_y += delt_y*deltabar;
        }			/* fin de boucle while */
    }				/*fermeture de la deuxieme partie du test */
    
	/***beamPremier = layer->beamListPremier;***/
	layer->beamListPremier = NULL;
    
    /***
     if (fb._grp)	// group.fin)
     {	e_t->rel = OFF; 
     rythmeInf(dc);
     }
     ***/
    
    
	if (fb._liaison)
		return;	
    
    /*	1111, code retourne pour appeler liais_note (NULL) apres beam(): on
     evite ainsi le risque d'appel recursif de beam. C'est le code de la
	 liaison "retardee": la direction des
     queues n'etait pas encore connue de liais_note lorsque la liaison a
     ete demandee, puisqu' elle est calculee (en mode automatique) par
     la presente fonction (et placee dans le bit m_stemDir); le code NULL
     permet un test d'association avec variable "attente" in
     liais_note (attente est engendree par coincidence rel && m_stemLen inter-
     disant le choix de la direction de liaison); ainsi NULL && attente 
     permettent d'entrer dans l'algoritme */ 
    
	return;	
}				/* fermeture de la fonction */
Example #27
0
template<typename T> T _min(T a, T b, T c, T d) { return min(_min(a,b,d),c); }
void HtmlDocument::parseHead(void)
{
	char *pBodyStart = strstr(m_pData, "<body");
	if (pBodyStart == NULL)
	{
		pBodyStart = strstr(m_pData, "<BODY");
	}
	if (pBodyStart != NULL)
	{
		string htmlHead(m_pData, pBodyStart - m_pData);
		regex_t titleRegex, httpEquivRegex;
		regmatch_t pTitleMatches[3];
		regmatch_t pHttpEquivMatches[3];
		int titleMatches = 3, httpEquivMatches = 3;

		// Look for a title
		if (regcomp(&titleRegex, "<title([^>]*)>([^<>]*)</title", REG_EXTENDED|REG_ICASE) == 0)
		{
			if ((regexec(&titleRegex, htmlHead.c_str(), titleMatches,
					pTitleMatches, REG_NOTBOL|REG_NOTEOL) == 0) &&
				(pTitleMatches[titleMatches - 1].rm_so != -1))
			{
				string title = htmlHead.substr(pTitleMatches[2].rm_so,
					pTitleMatches[2].rm_eo - pTitleMatches[2].rm_so);

				if (title.empty() == false)
				{
					// Override the title
					m_title = title;
				}
			}
		}
		// ...and a Content-Type
		if (regcomp(&httpEquivRegex, "<meta http-equiv=([^>]*) content=([^>]*)>", REG_EXTENDED|REG_ICASE) == 0)
		{
			if ((regexec(&httpEquivRegex, htmlHead.c_str(), httpEquivMatches,
					pHttpEquivMatches, REG_NOTBOL|REG_NOTEOL) == 0) &&
				(pHttpEquivMatches[httpEquivMatches - 1].rm_so != -1))
			{
				string name = StringManip::removeQuotes(
					htmlHead.substr(pHttpEquivMatches[1].rm_so,
					pHttpEquivMatches[1].rm_eo - pHttpEquivMatches[1].rm_so));
				string content = StringManip::removeQuotes(
					htmlHead.substr(pHttpEquivMatches[2].rm_so,
					pHttpEquivMatches[2].rm_eo - pHttpEquivMatches[2].rm_so));

				if ((content.empty() == false) &&
					(strncasecmp(name.c_str(), "Content-Type",
						min((int)name.length(), 12)) == 0))
				{
					// Override the type
					m_type = content;
				}
			}
		}
#ifdef DEBUG
		cout << "HtmlDocument::parseHead: extracted title " << m_title <<
			", type " << m_type << endl;
#endif

		regfree(&titleRegex);
		regfree(&httpEquivRegex);
	}
}
Example #29
0
void Topology::Paint(HDC hdc, RECT rc) {

  if (!shapefileopen) return;

  bool nolabels=false;
  if (scaleCategory==10) {
	// for water areas, use scaleDefault
	if ( MapWindow::zoom.Scale()>scaleDefaultThreshold) {
		return;
	}
	// since we just checked category 10, if we are over scale we set nolabels
	if ( MapWindow::zoom.Scale()>scaleThreshold) nolabels=true;
  } else 
  if (MapWindow::zoom.Scale() > scaleThreshold) return;

  // TODO code: only draw inside screen!
  // this will save time with rendering pixmaps especially
  // checkVisible does only check lat lon , not screen pixels..
  // We need to check also screen.

  HPEN  hpOld;
  HBRUSH hbOld;
  HFONT hfOld;

  if (hPen) {
    hpOld = (HPEN)SelectObject(hdc,  hPen);
    hbOld = (HBRUSH)SelectObject(hdc, hbBrush);
  } else {
    hpOld = NULL;
    hbOld = NULL;
  }
  hfOld = (HFONT)SelectObject(hdc, MapLabelFont);

  // get drawing info
    
  int iskip = 1;
  
  // attempt to bugfix 100615 polyline glitch with zoom over 33Km
  // do not skip points, if drawing coast lines which have a scaleThreshold of 100km!
  // != 5 and != 10
  if (scaleCategory>10) { 
  if (MapWindow::zoom.Scale()>0.25*scaleThreshold) {
    iskip = 2;
  } 
  if (MapWindow::zoom.Scale()>0.5*scaleThreshold) {
    iskip = 3;
  }
  if (MapWindow::zoom.Scale()>0.75*scaleThreshold) {
    iskip = 4;
  }
  }

  #if TOPOFASTLABEL
  // use the already existing screenbounds_latlon, calculated by CalculateScreenPositions in MapWindow2
  rectObj screenRect = MapWindow::screenbounds_latlon;
  #else
  rectObj screenRect = MapWindow::CalculateScreenBounds(0.0);
  #endif

  static POINT pt[MAXCLIPPOLYGON];
  bool labelprinted=false;

  for (int ixshp = 0; ixshp < shpfile.numshapes; ixshp++) {
    
    XShape *cshape = shpCache[ixshp];

    if (!cshape || cshape->hide) continue;    

    shapeObj *shape = &(cshape->shape);

    switch(shape->type) {


      case(MS_SHAPE_POINT):{

	#if 101016
	// -------------------------- NOT PRINTING ICONS ---------------------------------------------
	bool dobitmap=false;
	if (scaleCategory<90 || (MapWindow::zoom.Scale()<2)) dobitmap=true;
	// first a latlon overlap check, only approximated because of fastcosine in latlon2screen
	if (checkVisible(*shape, screenRect))
		for (int tt = 0; tt < shape->numlines; tt++) {
			for (int jj=0; jj< shape->line[tt].numpoints; jj++) {
				POINT sc;
				MapWindow::LatLon2Screen(shape->line[tt].point[jj].x, shape->line[tt].point[jj].y, sc);
				if (dobitmap) {
					// bugfix 101212 missing case for scaleCategory 0 (markers)
					if (scaleCategory==0||cshape->renderSpecial(hdc, sc.x, sc.y,labelprinted)) 
						MapWindow::DrawBitmapIn(hdc, sc, hBitmap);
				} else {
					cshape->renderSpecial(hdc, sc.x, sc.y,labelprinted);
				}
			}
		}
	}

	#else
	// -------------------------- PRINTING ICONS ---------------------------------------------
	#if (TOPOFAST)
	// no bitmaps for small town over a certain zoom level and no bitmap if no label at all levels
	bool nobitmap=false, noiconwithnolabel=false;
	if (scaleCategory==90 || scaleCategory==100) {
		noiconwithnolabel=true;
		if (MapWindow::MapScale>4) nobitmap=true;
	}
	#endif

	//#if TOPOFASTLABEL
	if (checkVisible(*shape, screenRect))
		for (int tt = 0; tt < shape->numlines; tt++) {
			for (int jj=0; jj< shape->line[tt].numpoints; jj++) {
				POINT sc;
				MapWindow::LatLon2Screen(shape->line[tt].point[jj].x, shape->line[tt].point[jj].y, sc);
	
				#if (TOPOFAST)
				if (!nobitmap)
				#endif
				#if 101016
				// only paint icon if label is printed too
				if (noiconwithnolabel) {
					if (cshape->renderSpecial(hdc, sc.x, sc.y,labelprinted))
						MapWindow::DrawBitmapIn(hdc, sc, hBitmap);
				} else {
					MapWindow::DrawBitmapIn(hdc, sc, hBitmap);
					cshape->renderSpecial(hdc, sc.x, sc.y,labelprinted);
				}
				#else
				MapWindow::DrawBitmapIn(hdc, sc, hBitmap);
				cshape->renderSpecial(hdc, sc.x, sc.y);
				#endif
			}
		}

	}
	#endif // Use optimized point icons 1.23e
	break;

    case(MS_SHAPE_LINE):

      if (checkVisible(*shape, screenRect))
        for (int tt = 0; tt < shape->numlines; tt ++) {
          
          int minx = rc.right;
          int miny = rc.bottom;
          int msize = min(shape->line[tt].numpoints, MAXCLIPPOLYGON);

	  MapWindow::LatLon2Screen(shape->line[tt].point,
				   pt, msize, 1);
          for (int jj=0; jj< msize; jj++) {
            if (pt[jj].x<=minx) {
              minx = pt[jj].x;
              miny = pt[jj].y;
            }
	  }

          ClipPolygon(hdc, pt, msize, rc, false);
          cshape->renderSpecial(hdc,minx,miny,labelprinted);
        }
      break;
      
    case(MS_SHAPE_POLYGON):

	// if it's a water area (nolabels), print shape up to defaultShape, but print
	// labels only up to custom label levels
	if ( nolabels ) {
		if (checkVisible(*shape, screenRect)) {
			for (int tt = 0; tt < shape->numlines; tt ++) {
				int minx = rc.right;
				int miny = rc.bottom;
				int msize = min(shape->line[tt].numpoints/iskip, MAXCLIPPOLYGON);
				MapWindow::LatLon2Screen(shape->line[tt].point, pt, msize*iskip, iskip);
				for (int jj=0; jj< msize; jj++) {
					if (pt[jj].x<=minx) {
						minx = pt[jj].x;
						miny = pt[jj].y;
					}
				}
				ClipPolygon(hdc,pt, msize, rc, true);
			}
		}
	} else 
	if (checkVisible(*shape, screenRect)) {
		for (int tt = 0; tt < shape->numlines; tt ++) {
			int minx = rc.right;
			int miny = rc.bottom;
			int msize = min(shape->line[tt].numpoints/iskip, MAXCLIPPOLYGON);
			MapWindow::LatLon2Screen(shape->line[tt].point, pt, msize*iskip, iskip);
			for (int jj=0; jj< msize; jj++) {
				if (pt[jj].x<=minx) {
					minx = pt[jj].x;
					miny = pt[jj].y;
				}
			}
			ClipPolygon(hdc,pt, msize, rc, true);
			cshape->renderSpecial(hdc,minx,miny,labelprinted);          
		}
	}
	break;
      
    default:
      break;
    }
  }
bool CorrespondTemplates::computeRigidAlignment(TriangleMesh * originalMesh, TriangleMesh * alignedMesh, g_NodeContainer contToBeAligned)
{
	long int i, numberOfNodes, dimension, dimensionH, lwork, info, determinant;
	double alpha, beta;
	char job, trans;
	bool returnval;
	numberOfNodes = originalMesh->getNumberOfNodes();
	dimension = 3;
	dimensionH = 4;
	job = 'A';
	trans = 'N';
	alpha = 1.0;
	beta = 0.0;
	lwork = 2*numberOfNodes;
	double * work = new double[lwork];
	double * A = new double[numberOfNodes * dimensionH];
	double * b = new double[numberOfNodes * dimension];
	double * S = new double[dimension];
	double * U = new double[dimension*dimension];
	double * VT = new double[dimension*dimension];
	double * R = new double[dimensionH*dimension];

	returnval = true;

	//populate the arrays A and b:
	for(i = 0; i < numberOfNodes; i++)
	{
		A[i] = originalMesh->nodes()[i]->coordinate().x();
		A[numberOfNodes + i] = originalMesh->nodes()[i]->coordinate().y();
		A[2*numberOfNodes + i] = originalMesh->nodes()[i]->coordinate().z();
		A[3*numberOfNodes + i] = 1.0;
		b[i] = alignedMesh->nodes()[i]->coordinate().x();
		b[numberOfNodes + i] = alignedMesh->nodes()[i]->coordinate().y();
		b[2*numberOfNodes + i] = alignedMesh->nodes()[i]->coordinate().z();
	}
	//compute an estimate of R:
	clapack::dgels_(&trans, &numberOfNodes, &dimensionH, &dimension, A, &numberOfNodes, b, &numberOfNodes, work, &lwork, &info);
	if(info != 0)
	{
		cout<<"Problem with estimating R "<<info<<endl;
		goto align_EXIT;
	}
	//make sure that R is a valid matrix (orthonormal): b contains R
	delete [] work;
	lwork = max(3 * min(dimension, dimensionH) + max(dimension, dimensionH), 5*min(dimension, dimensionH));
	work = new double[lwork];
	//only copy 3 by 3 submatrix to R:
	for(i = 0; i < dimension; i++)
	{
		R[i] = b[i];
		R[dimension + i] = b[numberOfNodes + i];
		R[2*dimension + i] = b[2*numberOfNodes + i];
	}
	//copy the modified version back to b (as help storage) and then to R in the correct order
	R[10] = R[8]; R[9] = R[7]; R[8] = R[6];
	R[6] = R[5]; R[5] = R[4]; R[4] = R[3];
	R[3] = b[3]; R[7] = b[numberOfNodes+3]; R[11] = b[2*numberOfNodes+3];

	//transform the coordinates:
	numberOfNodes = contToBeAligned.numberOfItems();
	delete [] A;
	A = new double[numberOfNodes * dimensionH];
	//populate the array A:
	for(i = 0; i < numberOfNodes; i++)
	{
		A[i] = contToBeAligned[i]->coordinate().x();
		A[numberOfNodes + i] = contToBeAligned[i]->coordinate().y();
		A[2*numberOfNodes + i] = contToBeAligned[i]->coordinate().z();
		A[3*numberOfNodes + i] = 1.0;
	}
	//do the rigid transformation and set it to part:
	clapack::dgemm_(&trans, &trans, &numberOfNodes, &dimension, &dimensionH, &alpha, A, &numberOfNodes, R, &dimensionH, &beta,
		b, &numberOfNodes);
	for(i = 0; i < numberOfNodes; i++)
	{
		contToBeAligned[i]->coordinate(g_Vector(b[i], b[numberOfNodes + i], b[2*numberOfNodes + i]));
	}

align_EXIT:
	delete [] work;
	delete [] A;
	delete [] b;
	delete [] S;
	delete [] U;
	delete [] VT;
	delete [] R;

	return returnval;
}