热门标签 | HotTags
当前位置:  开发笔记 > 人工智能 > 正文

CforGraphic:删格绘制直线和多边形

       最近年底没什么事情,要过年了嘛,放个大年假。我又捡起基础数学书看了,本来一直在看微分定积分偏微分计算,不过目前对于我来说应用场景不多,比如定积分和偏微分,在求面体积和

        最近年底没什么事情,要过年了嘛,放个大年假。我又捡起基础数学书看了,本来一直在看微分定积分偏微分计算,不过目前对于我来说应用场景不多,比如定积分和偏微分,在求面体积和数值分析方面大有可为,领域偏向于工业和研究领域,我还没想到怎么应用到我的日常开发中,如果我做教学软件就好了,数学施教类应该用的挺多(当然高级别的着色效果也用到微积分,主要还是我太水,知识深度和应用深度都还不够,估计还得要几年吧,反正我也不急,慢慢混,哈哈)。

        刚刚拿着我的三角尺和自动铅笔听小说发呆,突然想起来怎么用shader写一个绘制三角形的功能,或者我们就通用一点,写个绘制多边形的功能。平时我们用数学描叙一个三角形或者多边形,就描叙其顶点,眨一看挺简单的。

       不过图形学中,我们目前使用光删渲染管线,要实际显示在像素矩阵显示屏上,不仅仅是描叙数学符号而已。一个最实际的问题:如果一个网格的顶点和三角面通过MVP和透视除法和视图变化到屏幕像素矩阵,怎么绘制出来,我们假设屏幕二维坐标系中已经变换好了三(n)个顶点的坐标,怎么绘制出来三角(多边)形,这个也是删格化的处理方式。

      

       我们前面已经知道显示屏绘制就是逐行逐列扫描,那么意味着我们可以判断像素点(0,0)到(m,n)是否在多边形内即可,当然我们肯定要优化一下算法的,判断从全屏幕改为多边形的外接矩形。

        前面我们也写过了判断点在多边形中的计算方法,这里为了顺便扩展一下数学计算,我们用另外的判断方法:判断点在线段的两侧的哪一侧,我们假设P点在多边形内部,那么P点在多边形任意一条边(顺时针或逆时针)的同一侧,画个图:

                   

        假设我们按照顺时针,那么P点就在任意一条线段的右侧。

        那么我们只需要判断点于直线的两侧关系了,再来一张图:

      

       可以看出几种判断方法,如果P在OE线段所在直线的右侧:

       1.角POX小于角EOX

       2.OE和OP的差积朝向纸内(右手定则)

       3.建立OE的直线方程L:Ax+By+C=0,将P.x和P.y带入L,得到结果D>0或D<0则表示P在哪两侧(以x轴为参考,一四象限内:D<0在右侧,二三象限内:D>0则在右侧,但是如果P于E不在同一象限,则判断情况根据y轴正负划分)

       4.OP的斜率OE的斜率,余下不同象限多种判断情况)

       这样我们就建立了计算方法了(我就用向量差积z分量去判断吧),下面开始写shader:


Shader "Custom/GridDrawImageEffectShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma exclude_renderers d3d11 gles
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
uniform vector points[8];
uniform int pointCount;
//isright是否正确
//只计算差积z分量就ok
bool isRight(float2 o, float2 e, float2 p)
{
float3 oe = float3(e.x - o.x, e.y - o.y, 0);
float3 op = float3(p.x - o.x, p.y - o.y, 0);
float z = oe.x * op.y - oe.y * op.x;
if (z <0)
return true;
return false;
}
float minfloat(float farr[8],int len)
{
float min = 10000;
for(int i =0;i {
if(min>farr[i])
{
min = farr[i];
}
}
return min;
}
float maxfloat(float farr[8],int len)
{
float max = 0;
for(int i =0;i {
if(max {
max = farr[i];
}
}
return max;
}
//uv pixel是否在外接矩形内
bool isRectangle(float2 uv)
{
float2 pp = float2(uv.x * _ScreenParams.x,uv.y*_ScreenParams.y);
float xarr[8];
float yarr[8];
for(int i = 0;i

right || pp.ytop)
{
return false;
}
return true;
}
//顺时针判断uv pixel是否在多边形内
bool isInside(float2 uv)
{
float2 pp = float2(uv.x * _ScreenParams.x,uv.y*_ScreenParams.y);
for(int i = 0;i

        c#代码(相当于提交dc):


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GridEffect : MonoBehaviour
{
[SerializeField] private Material material;
void Start()
{
List points = new List
{
new Vector4(400,80,0,0),
new Vector4(200,300,0,0),
new Vector4(500,800,0,0),
new Vector4(700,400,0,0),
new Vector4(600,70,0,0),
};
material.SetInt("pointCount", points.Count);
material.SetVectorArray("points", points.ToArray());
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source, destination, material);
}
}

       效果如下:

 

        解释一下:

        1.计算点与线段两侧关系

       2.计算外接矩形,绘制外接矩形蓝色

       3.逐行逐列扫描uv(也就是像素)绘制多边形绿色

       这个也是删格化的常用算法之一(我代码肯定写的不如大佬们高效,哈哈)。

       下面继续,既然多边形绘制完毕,再尝试一下线段,其实线段的绘制和多边形一样就是删格化绘制,不同的是, 线段只有两个顶点,我们需要将顶点扩展成矩形,因为是删格化所以我们线段有宽度(不仅仅只是数学符号),就可以计算出线段组成的矩形的四个顶点,如图:

 

       从P0P1两点扩展出adcb顺时针四个矩形顶点,求出四个点的坐标然后再绘制多边形区域就行了,计算垂线以前也算过,不清楚的话可以返回之前查看,这里直接上代码:


void Start()
{

Vector4 from = new Vector4(400, 80, 0, 0);
Vector4 to = new Vector4(700, 400, 0, 0);
Vector4 sta = new Vector4(from.x, from.y);
Vector4 end = new Vector4(to.x, to.y);
float k = (end.y - sta.y) / (end.x - sta.x);
float m = halfWidth / Mathf.Sqrt(1 + k * k);
float n = Mathf.Abs(k) * halfWidth / Mathf.Sqrt(1 + k * k);
#if UNITY_EDITOR
Debug.LogFormat("n={0} m={1}", n, m);
#endif
Vector4 a = sta + new Vector4(-n, m);
Vector4 b = sta + new Vector4(n, -m);
Vector4 c = end + new Vector4(n, -m);
Vector4 d = end + new Vector4(-n, m);
#if UNITY_EDITOR
Debug.LogFormat("a={0} b={1} c={2} d={3}", a, b, c, d);
#endif
//顺时针
List points = new List
{
a,d,c,b
};
material.SetInt("pointCount", points.Count);
material.SetVectorArray("points", points.ToArray());
}

         这里我直接用c# start计算直线顶点了,如果需要动态变化就使用update或者shader中计算,不然就不需要消耗那么多性能,效果如图:

   

         这些二维计算有助于我们理解删格化,同时应用范围也算是挺广的,ok,继续撸数学。

      

            





  • 点赞



  • 收藏



  • 分享




    • 文章举报






羊羊2035
发布了100 篇原创文章 · 获赞 101 · 访问量 10万+
私信

关注

推荐阅读
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • JavaScript设计模式之策略模式(Strategy Pattern)的优势及应用
    本文介绍了JavaScript设计模式之策略模式(Strategy Pattern)的定义和优势,策略模式可以避免代码中的多重判断条件,体现了开放-封闭原则。同时,策略模式的应用可以使系统的算法重复利用,避免复制粘贴。然而,策略模式也会增加策略类的数量,违反最少知识原则,需要了解各种策略类才能更好地应用于业务中。本文还以员工年终奖的计算为例,说明了策略模式的应用场景和实现方式。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 词袋模型的通俗介绍
    词,袋, ... [详细]
  • 在2022年,随着信息化时代的发展,手机市场上出现了越来越多的机型选择。如何挑选一部适合自己的手机成为了许多人的困扰。本文提供了一些配置及性价比较高的手机推荐,并总结了选择手机时需要考虑的因素,如性能、屏幕素质、拍照水平、充电续航、颜值质感等。不同人的需求不同,因此在预算范围内找到适合自己的手机才是最重要的。通过本文的指南和技巧,希望能够帮助读者节省选购手机的时间。 ... [详细]
  • 从高级程序员到CTO的4次能力跃迁!如何选择适合的技术负责人?
    本文讲解了从高级程序员到CTO的4次能力跃迁,以及如何选择适合的技术负责人。在初创期、发展期、成熟期的每个阶段,创业公司需要不同级别的技术负责人来实现复杂功能、解决技术难题、提高交付效率和质量。高级程序员的职责是实现复杂功能、编写核心代码、处理线上bug、解决技术难题。而技术经理则需要提高交付效率和质量。 ... [详细]
  • Learning to Paint with Model-based Deep Reinforcement Learning
    本文介绍了一种基于模型的深度强化学习方法,通过结合神经渲染器,教机器像人类画家一样进行绘画。该方法能够生成笔画的坐标点、半径、透明度、颜色值等,以生成类似于给定目标图像的绘画。文章还讨论了该方法面临的挑战,包括绘制纹理丰富的图像等。通过对比实验的结果,作者证明了基于模型的深度强化学习方法相对于基于模型的DDPG和模型无关的DDPG方法的优势。该研究对于深度强化学习在绘画领域的应用具有重要意义。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
author-avatar
粪青12_601
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有