docs: public float z_value(Vector3 q) {
  		if(q==null || this.halfplane) throw new RuntimeException("*** ERR wrong parameters, can't approximate the z value ..***: "+q);
  		/* incase the query point is on one of the points */
  		if(q.x==a.x & q.y==a.y) return a.z;
  		if(q.x==b.x & q.y==b.y) return b.z;
  		if(q.x==c.x & q.y==c.y) return c.z;
  
  		/* 
  		 *  plane: aX + bY + c = Z:
  		 *  2D line: y= mX + k
  		 *  
  		 */
  		float x=0,x0 = q.x, x1 = a.x, x2=b.x, x3=c.x;
  		float y=0,y0 = q.y, y1 = a.y, y2=b.y, y3=c.y;
  		float z=0, m01=0,k01=0,m23=0,k23=0;
  
  		float r = 0;
  
  		// 0 - regular, 1-horizontal , 2-vertical.
  		int flag01 = 0;
  		if(x0!=x1) {
  			m01 = (y0-y1)/(x0-x1);
  			k01 = y0 - m01*x0;
  			if (m01 ==0) {
  				flag01 = 1;
  			}
  		} else { // 2-vertical.
  			flag01 = 2;//x01 = x0
  		}
  		int flag23 = 0;
  		if(x2!=x3) {
  			m23 = (y2-y3)/(x2-x3);
  			k23 = y2 - m23*x2;
  			if (m23 ==0) {
  				flag23 = 1;
  			}
  		}
  		else { // 2-vertical.
  			flag23 = 2;//x01 = x0
  		}
  
  		if (flag01 ==2 ) {
  			x = x0;
  			y = m23*x + k23;
  		}
  		else {
  			if(flag23==2) {
  				x = x2;
  				y = m01*x + k01;
  			}
  			else {  // regular case 
  				x=(k23-k01)/(m01-m23);
  				y = m01*x+k01;
  
  			}
  		}
  		if(flag23==2) {
  			r=(y2-y)/(y2-y3);
  		} else {
  			r=(x2-x)/(x2-x3);
  		}
  
  		z = b.z + (c.z-b.z)*r;
  		if(flag01==2) {
  			r=(y1-y0)/(y1-y);
  		} else {
  			r=(x1-x0)/(x1-x);
  		}
  		float qZ = a.z + (z-a.z)*r;
  		return qZ;
  	}