@@ -62,6 +62,7 @@ import {
6262 DEFAULT_POINT_CONNECTION_INT_POINTS_TOLERANCE ,
6363 DEFAULT_SHOW_POINT_CONNECTIONS ,
6464 DEFAULT_POINT_OUTLINE_WIDTH ,
65+ MIN_POINT_SIZE ,
6566 DEFAULT_POINT_SIZE ,
6667 DEFAULT_POINT_SIZE_SELECTED ,
6768 DEFAULT_POINT_SIZE_MOUSE_DETECTION ,
@@ -328,6 +329,8 @@ const createScatterplot = (initialProperties = {}) => {
328329 ? [ ...pointSize ]
329330 : [ pointSize ] ;
330331
332+ let minPointScale = MIN_POINT_SIZE / pointSize [ 0 ] ;
333+
331334 if ( pointConnectionColor === 'inherit' ) {
332335 pointConnectionColor = [ ...pointColor ] ;
333336 } else {
@@ -1038,6 +1041,7 @@ const createScatterplot = (initialProperties = {}) => {
10381041
10391042 if ( isStrictlyPositiveNumber ( + newPointSize ) ) pointSize = [ + newPointSize ] ;
10401043
1044+ minPointScale = MIN_POINT_SIZE / pointSize [ 0 ] ;
10411045 encodingTex = createEncodingTexture ( ) ;
10421046 computePointSizeMouseDetection ( ) ;
10431047 } ;
@@ -1163,8 +1167,16 @@ const createScatterplot = (initialProperties = {}) => {
11631167 const getModel = ( ) => model ;
11641168 const getProjectionViewModel = ( ) =>
11651169 mat4 . multiply ( pvm , projection , mat4 . multiply ( pvm , camera . view , model ) ) ;
1166- const getPointScale = ( ) =>
1167- 1 + Math . log2 ( max ( 1.0 , camera . scaling ) ) * window . devicePixelRatio ;
1170+ const getPointScale = ( ) => {
1171+ if ( camera . scaling > 1 )
1172+ return (
1173+ ( Math . asinh ( max ( 1.0 , camera . scaling ) ) / Math . asinh ( 1 ) ) *
1174+ window . devicePixelRatio
1175+ ) ;
1176+
1177+ return max ( minPointScale , camera . scaling ) * window . devicePixelRatio ;
1178+ } ;
1179+ // 1 + Math.log2(max(1.0, camera.scaling)) * window.devicePixelRatio;
11681180 const getNormalNumPoints = ( ) => numPoints ;
11691181 const getIsColoredByZ = ( ) => + ( colorBy === 'valueZ' ) ;
11701182 const getIsColoredByW = ( ) => + ( colorBy === 'valueW' ) ;
@@ -1191,22 +1203,22 @@ const createScatterplot = (initialProperties = {}) => {
11911203 // Adopted from the fabulous Ricky Reusser:
11921204 // https://observablehq.com/@rreusser /selecting-the-right-opacity-for-2d-point-clouds
11931205 // Extended with a point-density based approach
1194- const pointScale = getPointScale ( ) ;
1195- const smallestPointSize = pointSize . length === 1 ? pointSize [ 0 ] : pointSize ;
1196- const p = smallestPointSize * pointScale ;
1206+ const pointScale = getPointScale ( true ) ;
1207+ const p = pointSize [ 0 ] * pointScale ;
11971208
11981209 // Compute the plot's x and y range from the view matrix, though these could come from any source
11991210 const s = ( 2 / ( 2 / camera . view [ 0 ] ) ) * ( 2 / ( 2 / camera . view [ 5 ] ) ) ;
12001211
12011212 // Viewport size, in device pixels
12021213 const H = context . viewportHeight ;
1214+ const W = context . viewportWidth ;
12031215
12041216 // Adaptation: Instead of using the global number of points, I am using a
12051217 // density-based approach that takes the points in the view into context
12061218 // when zooming in. This ensure that in sparse areas, points are opaque and
12071219 // in dense areas points are more translucent.
12081220 let alpha =
1209- ( ( opacityByDensityFill * H * H ) / ( numPointsInView * p * p ) ) * min ( 1 , s ) ;
1221+ ( ( opacityByDensityFill * W * H ) / ( numPointsInView * p * p ) ) * min ( 1 , s ) ;
12101222
12111223 // In performanceMode we use squares, otherwise we use circles, which only
12121224 // take up (pi r^2) of the unit square
@@ -1215,7 +1227,7 @@ const createScatterplot = (initialProperties = {}) => {
12151227 // If the pixels shrink below the minimum permitted size, then we adjust the opacity instead
12161228 // and apply clamping of the point size in the vertex shader. Note that we add 0.5 since we
12171229 // slightly inrease the size of points during rendering to accommodate SDF-style antialiasing.
1218- const clampedPointDeviceSize = max ( smallestPointSize , p ) + 0.5 ;
1230+ const clampedPointDeviceSize = max ( MIN_POINT_SIZE , p ) + 0.5 ;
12191231
12201232 // We square this since we're concerned with the ratio of *areas*.
12211233 // eslint-disable-next-line no-restricted-properties
0 commit comments