docs: public final void addEdge(double x1, double y1, double x2, double y2) {
  		if (y1 == y2)
  			return;
  			
  		int dir = 1;
  		if (y1 > y2) {
  			double temp;
  			temp = x1; x1 = x2; x2 = temp;
  			temp = y1; y1 = y2; y2 = temp;
  			dir = -1;
  		}
  		
  		if (y2 < 0 || y1 >= height_)
  			return;
  
  		if (x1 < 0 && x2 < 0)
  		{
  			x1 = -1; x2 = -1;
  		}
  		else if (x1 >= width_ && x2 >= width_)
  		{
  			x1 = width_; x2 = width_;
  		}
  		
  		//clip to extent
  		double dxdy = (x2 - x1) / (y2 - y1);
  
  		if (y2 > height_) {
  			y2 = height_;
  			x2 = dxdy * (y2 - y1) + x1;
  		}
  		
  		if (y1 < 0) {
  			x1 = dxdy * (0 - y1) + x1;
  			y1 = 0;
  		}
  
  		//do not clip x unless it is too small or too big
  		int bigX = Math.max(width_ + 1, 0x7fffff);
  		if (x1 < -0x7fffff) {
  		    //from earlier logic, x2 >= -1, therefore dxdy is not 0
  			y1 = (0 - x1) / dxdy + y1;
  			x1 = 0;
  		}
  		else if (x1 > bigX) {
  			//from earlier logic, x2 <= width_, therefore dxdy is not 0
  			y1 = (width_ - x1) / dxdy + y1;
  			x1 = width_;
  		}
  
  		if (x2 < -0x7fffff) {
  			//from earlier logic, x1 >= -1, therefore dxdy is not 0
  			y2 = (0 - x1) / dxdy + y1;
  			x2 = 0;
  		}
  		else if (x2 > bigX) {
  			//from earlier logic, x1 <= width_, therefore dxdy is not 0
  			y2 = (width_ - x1) / dxdy + y1;
  			x2 = width_;
  		}
  		
  		int ystart = (int)y1;
  		int yend = (int)y2;
  		if (ystart == yend)
  			return;
  		
  		Edge e = new Edge();
  		
  		e.x = (long)(x1 * 4294967296.0);
  		e.y = ystart;
  		e.ymax = yend;
  		e.dxdy = (long)(dxdy * 4294967296.0);
  		e.dir = dir;
  		
  		if (ySortedEdges_ == null) {
  			ySortedEdges_ = new Edge[height_];
  		}
  
  		e.next = ySortedEdges_[e.y];
  		ySortedEdges_[e.y] = e;
  		
  		if (e.y < minY_)
  			minY_ = e.y;
  		
  		if (e.ymax > maxY_)
  			maxY_ = e.ymax;
  		
  		numEdges_++;
  	}