Rather than trying to make the dots behave to fully hide/show based on whether there are wholly or part within the masked regions, it is far simpler to control the masks so that they only ever cover whole dot regions. This can be done using the Modulo function to calculate the distance to the nearest boundary and adjust the edge to that boundary. In this way the mask edge will 'jump' to a suitable position where it will not cut any of the dots.
Consider the following material nodes :

The Object coordinates from the Empty (Texture Coordinate node near the top) are used to produce the mask by applying an Absolute operation followed by a Less Than on each of the channels. The result is combined using Minimum to produce the mask. Note that the Vector Math node is used for Absolute to perform the same operation on each channel of the vector. In this way, moving the Empty moves the mask and changing the values in the Less Than nodes will affect the Width and Height of the mask around that point of the Empty. Note that for this to work the Empty must have the same Rotation and Scale as the main mesh (otherwise the coordinate systems won’t work).
In addition, a modulo (*see below) operation is applied to the Object coordinates. This will return the remainder of dividing the coordinates by the desired 'pitch' (size) of the grid. By Subtracting this from the coordinates used for the mask we effectively offset the boundary of the mask to the edge of the grid defined by the 'dot pitch'. The result of the Modulo is also used to indicate the position within each grid cell and this is used (by scaling (Divide), offsetting (Subtract 0.5) and getting the Length to determine the distance from the centre of a circle to generate each 'dot' (controlled by the other Less Than node).
The result of the mask and the 'dot' is combined via a Multiply node to produce only complete dots within the mask.
Note : The standard Modulo function handles negative values by outputting a negative result. This is not suited to generating a grid in this way but the Modulo, Add, Modulo operations correct for this (see https://blender.stackexchange.com/a/122489/29586 for an explanation of this).
Here's the result of moving the Empty.

The Value node can be adjusted to set the 'dot pitch', the X and Y Less Than nodes to adjust the mask Width and Height respectively, and the Length Less Than node to adjust the 'dot size'. The empty can then be used to position the mask and only complete dots will be shown.
In order to support multiple masks, simply replicate the 'top row' of nodes (from the Texture Coordinate of the Empty to the Multiply used to merge with the dots) for each 'Empty' in use - and combine each row with a Maximum node.
