Reverse color of overlapping points?

Perhaps:

Graphics[FilledCurve[{
   {Line@close@CirclePoints[{0, 0}, 1, 30]}, 
   {Line@close@CirclePoints[{1, 1}, 1, 30]}
  }]]

enter image description here

More generally:

close[path_List] := Append[path, First@path];

drawIt[points_List, r_: 2] := 
  FilledCurve[{Line@close@CirclePoints[#, r, 40]} & /@ points];

SeedRandom[0];
Graphics[drawIt[RandomReal[{-20, 20}, {20, 2}]]]

enter image description here


Here's a refinement of Michael's FilledCurve idea, where I use BSplineCurve to generate the circles instead of Line. The following function creates a BSplineCurve that renders as a circle with center c and radius r, where r is measure in points, and not plot coordinates (using points means that the shape of the circle is unaffected by changes in the AspectRatio of a graphic):

splineCircle[c_, r_] := BSplineCurve[
    Table[Offset[r {Cos[n Pi/4], Sin[n Pi/4]} If[OddQ[n], Sec[Pi/4], 1], c], {n, 0, 8}],
    SplineDegree -> 2,
    SplineKnots -> {0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4},
    SplineWeights -> {1, 1/Sqrt[2], 1, 1/Sqrt[2], 1, 1/Sqrt[2], 1, 1/Sqrt[2], 1}
]

Using the above primitive, we can construct the desired output using FilledCurve:

overlappedPoints[pts_, size_] := FilledCurve @ Map[
    {splineCircle[#, size]}&,
    pts
]

Simple example:

Graphics[overlappedPoints[{{0, 0}, {.1, .1}}, 50], PlotRange->{{-.5,.5},{-.5,.5}}]

enter image description here

More points (using @Michael's example):

SeedRandom[0];
pts = RandomReal[{-20, 20}, {20, 2}];
g = Graphics[
    {
    overlappedPoints[pts, 9]
    },
    ImageSize->200
]

enter image description here

Here's how the graphic changes with changing aspect ratio:

GraphicsRow[
    {Show[g, AspectRatio->1/2], g, Show[g, AspectRatio->2]},
    ImageSize->600,
    Frame->All
]

enter image description here

And a fairly large example (with 1000 points):

SeedRandom[0];
pts = RandomReal[{-20, 20}, {1000, 2}];
g = Graphics[
    {
    overlappedPoints[pts, 7]
    },
    ImageSize->500
]

enter image description here

Addendum

If you want to be able to specify the overlap colors, a small change to my original code will allow you to do this:

overlappedPoints[pts_,size_]:={
    Red,
    Map[Disk[#, Offset[size]]&,pts],
    Black,
    FilledCurve@Map[{splineCircle[#,size]}&,pts]
}

For example:

SeedRandom[0];
pts = RandomReal[{-20,20},{20,2}];
g = Graphics[{overlappedPoints[pts,9]}, ImageSize->200, AspectRatio->1/2]

enter image description here

where I also changed the aspect ratio to show that the points don't get elongated when the aspect ratio is changed. This approach is pretty quick even for a 1000 points.

SeedRandom[0];
pts = RandomReal[{-20,20},{1000,2}];
Graphics[{overlappedPoints[pts,7]},ImageSize->500] //AbsoluteTiming

enter image description here


Another way using regions.

If we have two regions defined by disks

R = {r1, r2} = {Disk[{0, 0}, 2], Disk[{1, 1}, 2]};
Graphics[R]

Overlapping regions

we can effectively paint their intersection.

Show[
  Graphics[R], 
  MeshPrimitives[
    DiscretizeRegion[RegionIntersection @@ R],
    2
  ] /. reg : Polygon[_] :> {EdgeForm[White], White, reg} // Graphics, 
 PlotRange -> All
]

Region with the intersection in White

and, while it's almost painfully slow, for a general set of points.

overlaps[pts : {{_, _} ..}, r_: 1] := Block[
  {regs},
  regs = Disk[#, r] & /@ pts;
  Show[
    Graphics[regs],
    Graphics[
      Join @@ (
        MeshPrimitives[DiscretizeRegion@#, 2] & /@ DeleteCases[
          RegionIntersection @@@ Join @@ Table[
            regs[[{j, k}]],
            {j, Length@regs},
            {k, Range[Length@regs]~Complement~{j}}
          ],
          EmptyRegion[2]
         ]
      ) /. reg : Polygon[_] :> {EdgeForm[White], White, reg}
    ],
   PlotRange -> All
  ]
]

SeedRandom[1234]
overlaps[RandomReal[{0, 10}, {15, 2}]]

Many different regions with white intersections