0

0

从二维点阵中高效检索圆形区域点并实现动画效果

心靈之曲

心靈之曲

发布时间:2025-09-08 12:13:20

|

938人浏览过

|

来源于php中文网

原创

从二维点阵中高效检索圆形区域点并实现动画效果

本教程详细介绍了如何从预定义的二维点阵中,高效地检索出位于特定圆形区域内的点。文章将阐述基于距离的筛选方法,包括性能优化技巧,并进一步指导如何利用这些点实现中心向外扩散或消失的动画效果。同时,还将介绍使用三角函数生成圆周点的方法,以辅助理解和实现更复杂的圆形图案。

1. 理解点阵数据结构

在处理二维图形和动画时,我们经常需要管理大量的离散点。本场景中,点被组织成一个二维网格(或点阵),并存储在一个三维数组 point_matrix 中。

point_matrix 的结构如下: point_matrix[xn][yn][0] 存储对应网格点在屏幕上的 x 坐标。 point_matrix[xn][yn][1] 存储对应网格点在屏幕上的 y 坐标。 其中,xn 和 yn 分别是点在网格中的逻辑索引。

初始点阵的生成代码示例如下:

int constant = 60; // 点之间的间距
int width = 1080; // 画布宽度
int height = 1920; // 画布高度

// 计算填充,使点阵居中
int padding_X = (int) Math.floor((width % constant) / 2f);
if (padding_X == 0) {
    padding_X = (int) Math.floor(constant / 2);
}
int padding_Y = (int) Math.floor((height % constant) / 2f);
if (padding_Y == 0) {
    padding_Y = (int) Math.floor(constant / 2);
}

// 计算网格的最大索引
int max_xn = Math.round((width - (padding_X * 2)) / constant);
int max_yn = Math.round((height - (padding_Y * 2)) / constant);

// 初始化点阵存储
// point_matrix[网格x索引][网格y索引][0:x坐标, 1:y坐标]
int[][][] point_matrix = new int[max_xn + 1][max_yn + 1][2];

// 填充点阵
for (int yn = 0; yn <= max_yn; yn++) {
    int y = (int) (padding_Y + (yn * constant));
    for (int xn = 0; xn <= max_xn; xn++) {
        int x = (int) (padding_X + (xn * constant));
        point_matrix[xn][yn][0] = x;
        point_matrix[xn][yn][1] = y;
        // 实际应用中,这里可能会进行绘制或其他操作
        // canvas.setPixel(x, y, Color.parseColor("#ffffff"));
    }
}

2. 中心点与距离计算

要检索圆形区域内的点,首先需要确定圆心坐标和半径。圆心可以是画布的几何中心,也可以是点阵的逻辑中心。

确定圆心: 如果以画布中心为圆心:centerX = width / 2; centerY = height / 2; 如果以点阵的中心点为圆心:centerX = point_matrix[max_xn / 2][max_yn / 2][0]; centerY = point_matrix[max_xn / 2][max_yn / 2][1];

距离计算(欧几里得距离): 任意点 (x, y) 到圆心 (cx, cy) 的距离 d 可以通过勾股定理计算: d = sqrt((x - cx)^2 + (y - cy)^2)

性能优化:使用平方距离 在判断一个点是否在某个半径 R 范围内时,我们实际上只需要比较 d 和 R 的大小。由于 sqrt 运算相对耗时,我们可以比较它们的平方: d^2 = (x - cx)^2 + (y - cy)^2 如果 d^2

/**
 * 计算点 (x, y) 到中心 (cx, cy) 的平方距离。
 * @param x 点的x坐标
 * @param y 点的y坐标
 * @param cx 中心的x坐标
 * @param cy 中心的y坐标
 * @return 平方距离
 */
public static long calculateSquaredDistance(int x, int y, int cx, int cy) {
    long dx = x - cx;
    long dy = y - cy;
    return dx * dx + dy * dy;
}

3. 检索指定半径内的点

有了距离计算方法,检索指定半径内的点就变得简单直接。我们只需遍历 point_matrix 中的所有点,对每个点计算其到圆心的平方距离,并与目标半径的平方进行比较。

倍塔塞司
倍塔塞司

AI职业规划、AI职业测评、定制测评、AI工具等多样化职业类AI服务。

下载
import java.util.ArrayList;
import java.util.List;

// 假设 point_matrix, max_xn, max_yn, width, height 已定义

public class PointRetrieval {

    // 定义一个简单的点类,用于存储坐标
    static class Point {
        int x;
        int y;
        int gridX; // 原始网格X索引
        int gridY; // 原始网格Y索引

        public Point(int x, int y, int gridX, int gridY) {
            this.x = x;
            this.y = y;
            this.gridX = gridX;
            this.gridY = gridY;
        }

        @Override
        public String toString() {
            return "(" + x + ", " + y + ") [Grid: " + gridX + "," + gridY + "]";
        }
    }

    /**
     * 从点阵中检索指定半径内的所有点。
     *
     * @param pointMatrix 存储点的三维数组
     * @param maxGridX    点阵的最大X索引
     * @param maxGridY    点阵的最大Y索引
     * @param centerX     圆心的X坐标
     * @param centerY     圆心的Y坐标
     * @param radius      检索半径
     * @return 位于指定半径内的点列表
     */
    public static List getPointsInRadius(int[][][] pointMatrix, int maxGridX, int maxGridY,
                                                int centerX, int centerY, int radius) {
        List pointsInRadius = new ArrayList<>();
        long radiusSquared = (long) radius * radius; // 预计算半径的平方

        for (int xn = 0; xn <= maxGridX; xn++) {
            for (int yn = 0; yn <= maxGridY; yn++) {
                int pointX = pointMatrix[xn][yn][0];
                int pointY = pointMatrix[xn][yn][1];

                long distSquared = calculateSquaredDistance(pointX, pointY, centerX, centerY);

                if (distSquared <= radiusSquared) {
                    pointsInRadius.add(new Point(pointX, pointY, xn, yn));
                }
            }
        }
        return pointsInRadius;
    }

    // 假设 calculateSquaredDistance 方法已定义

    public static void main(String[] args) {
        // 示例:使用前文定义的点阵生成逻辑
        int constant = 60;
        int width = 1080;
        int height = 1920;

        int padding_X = (int) Math.floor((width % constant) / 2f);
        if (padding_X == 0) padding_X = (int) Math.floor(constant / 2);
        int padding_Y = (int) Math.floor((height % constant) / 2f);
        if (padding_Y == 0) padding_Y = (int) Math.floor(constant / 2);

        int max_xn = Math.round((width - (padding_X * 2)) / constant);
        int max_yn = Math.round((height - (padding_Y * 2)) / constant);

        int[][][] point_matrix = new int[max_xn + 1][max_yn + 1][2];
        for (int yn = 0; yn <= max_yn; yn++) {
            int y = (int) (padding_Y + (yn * constant));
            for (int xn = 0; xn <= max_xn; xn++) {
                int x = (int) (padding_X + (xn * constant));
                point_matrix[xn][yn][0] = x;
                point_matrix[xn][yn][1] = y;
            }
        }

        // 确定圆心和半径
        int centerX = width / 2;
        int centerY = height / 2;
        int targetRadius = 300; // 示例半径

        List points = getPointsInRadius(point_matrix, max_xn, max_yn, centerX, centerY, targetRadius);

        System.out.println("Found " + points.size() + " points within radius " + targetRadius + " from center (" + centerX + "," + centerY + "):");
        // points.forEach(System.out::println); // 打印所有点
    }
}

4. 实现圆形扩散/消失动画

要实现点从中心向外以圆形模式逐渐消失的动画效果,我们需要将点根据其到中心的距离进行分组。

分层半径区间: 我们可以定义一系列递增的半径区间,例如 [0, r1), [r1, r2), [r2, r3) 等。然后,将每个点归类到其所属的半径区间。

import java.util.Map;
import java.util.TreeMap; // 使用TreeMap保持半径区间的顺序

// 假设 Point 类和 calculateSquaredDistance 方法已定义

public class CircularAnimation {

    /**
     * 将点按距离中心点的半径区间进行分组。
     *
     * @param pointMatrix 点阵
     * @param maxGridX    点阵最大X索引
     * @param maxGridY    点阵最大Y索引
     * @param centerX     圆心X坐标
     * @param centerY     圆心Y坐标
     * @param radiusStep  每个半径区间的步长
     * @param maxRadius   最大考虑半径
     * @return 一个Map,键为半径区间的起始值,值为该区间内的点列表
     */
    public static Map> groupPointsByRadiusInterval(
            int[][][] pointMatrix, int maxGridX, int maxGridY,
            int centerX, int centerY, int radiusStep, int maxRadius) {

        // 使用TreeMap确保半径区间有序
        Map> pointsByRadiusInterval = new TreeMap<>();

        for (int xn = 0; xn <= maxGridX; xn++) {
            for (int yn = 0; yn <= maxGridY; yn++) {
                int pointX = pointMatrix[xn][yn][0];
                int pointY = pointMatrix[xn][yn][1];

                long distSquared = calculateSquaredDistance(pointX, pointY, centerX, centerY);
                double distance = Math.sqrt(distSquared); // 这里需要实际距离来分组

                if (distance <= maxRadius) {
                    // 计算点所属的半径区间起始值
                    int intervalStart = (int) (Math.floor(distance / radiusStep) * radiusStep);
                    pointsByRadiusInterval
                            .computeIfAbsent(intervalStart, k -> new ArrayList<>())
                            .add(new PointRetrieval.Point(pointX, pointY, xn, yn));
                }
            }
        }
        return pointsByRadiusInterval;
    }

    public static void main(String[] args) throws InterruptedException {
        // ... (点阵生成代码与上文相同) ...
        int constant = 60;
        int width = 1080;
        int height = 1920;

        int padding_X = (int) Math.floor((width % constant) / 2f);
        if (padding_X == 0) padding_X = (int) Math.floor(constant / 2);
        int padding_Y = (int) Math.floor((height % constant) / 2f);
        if (padding_Y == 0) padding_Y = (int) Math.floor(constant / 2);

        int max_xn = Math.round((width - (padding_X * 2)) / constant);
        int max_yn = Math.round((height - (padding_Y * 2)) / constant);

        int[][][] point_matrix = new int[max_xn + 1][max_yn + 1][2];
        for (int yn = 0; yn <= max_yn; yn++) {
            int y = (int) (padding_Y + (yn * constant));
            for (int xn = 0; xn <= max_xn; xn++) {
                int x = (int) (padding_X + (xn * constant));
                point_matrix[xn][yn][0] = x;
                point_matrix[xn][yn][1] = y;
            }
        }

        int centerX = width / 2

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
php中三维数组怎样求和
php中三维数组怎样求和

php中三维数组求和的方法:1、创建一个php示例文件;2、定义一个名为“$total”的变量,用于记录累加的结果。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

96

2024.02.23

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

539

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

21

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

31

2026.01.06

PHP 高并发与性能优化
PHP 高并发与性能优化

本专题聚焦 PHP 在高并发场景下的性能优化与系统调优,内容涵盖 Nginx 与 PHP-FPM 优化、Opcode 缓存、Redis/Memcached 应用、异步任务队列、数据库优化、代码性能分析与瓶颈排查。通过实战案例(如高并发接口优化、缓存系统设计、秒杀活动实现),帮助学习者掌握 构建高性能PHP后端系统的核心能力。

102

2025.10.16

PHP 数据库操作与性能优化
PHP 数据库操作与性能优化

本专题聚焦于PHP在数据库开发中的核心应用,详细讲解PDO与MySQLi的使用方法、预处理语句、事务控制与安全防注入策略。同时深入分析SQL查询优化、索引设计、慢查询排查等性能提升手段。通过实战案例帮助开发者构建高效、安全、可扩展的PHP数据库应用系统。

90

2025.11.13

JavaScript 性能优化与前端调优
JavaScript 性能优化与前端调优

本专题系统讲解 JavaScript 性能优化的核心技术,涵盖页面加载优化、异步编程、内存管理、事件代理、代码分割、懒加载、浏览器缓存机制等。通过多个实际项目示例,帮助开发者掌握 如何通过前端调优提升网站性能,减少加载时间,提高用户体验与页面响应速度。

30

2025.12.30

php环境变量如何设置
php环境变量如何设置

本合集详细讲解PHP环境变量的设置方法,涵盖Windows、Linux及常见服务器环境配置技巧,助你快速掌握环境变量的正确配置。阅读专题下面的文章了解更多详细内容。

0

2026.01.31

php图片如何上传
php图片如何上传

本合集涵盖PHP图片上传的核心方法、安全处理及常见问题解决方案,适合初学者与进阶开发者。阅读专题下面的文章了解更多详细内容。

2

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.1万人学习

C# 教程
C# 教程

共94课时 | 8.1万人学习

Java 教程
Java 教程

共578课时 | 54.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号