<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="/scripts/mathematicsAndPhysics/linearAlgebra/matrix/gl-matrix/2.7.1/dist/gl-matrix.js"></script>
<script src="../../../../scripts/mathematicsAndPhysics/geometry/shape-points/2.0.1/shapPoints.js"></script>
<script src="../../../../scripts/mathematicsAndPhysics/bezierCurve/jsbezier/0.9.3/jsbezier.js"></script>
<script src="../../../../scripts/mathematicsAndPhysics/bezierCurve/bezierjs/2.2.15/bezierjs.js"></script>
<title></title>
<style>
#canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="canvas">
</canvas>
<script>
var canvas = document.getElementById('canvas')
canvas.width = 1000;
canvas.height = 1000;
var ctx = canvas.getContext('2d');
// 创建一个
var rotate = 20 / 180 * Math.PI;
var rectSize=vec2.fromValues(100,100)
var rectPosition = vec2.fromValues(100, 100);
var rectRotatePosition = vec2.rotate(vec2.create(), rectPosition, [0, 0], rotate)
// 创建一个矩阵
var m = mat2d.create();
m = mat2d.translate(mat2d.create(), m, [100, 100]);// 位移
m = mat2d.scale(mat2d.create(), m, [1, 1]);// 缩放
m = mat2d.rotate(mat2d.create(), m, rotate);// 旋转20
var m2=mat2d.multiply(mat2d.create(),mat2d.create(),[2,0,0,2,100,100])
// 创建一个矩形
ctx.fillStyle = 'red';
ctx.setTransform.apply(ctx, m)
ctx.fillRect(rectPosition[0], rectPosition[1], rectSize[0], rectSize[1]);
// ctx.setTransform.apply(ctx, mat2d.create())
// 创建一个圆
ctx.beginPath();
ctx.arc(400, 100, 50, 0, Math.PI * 2);
ctx.fill();
function drawPoints(points,fill) {
ctx.moveTo(points[0], points[1])
for (var i = 2; i < points.length; i += 2) {
ctx.lineTo(points[i], points[i + 1])
}
if (fill) {
ctx.fill();
return;
}
ctx.stroke()
}
//创建一个三次贝塞尔图形
var heartPoints = [];
function heart() {
var ops = {
x: 100,
y: 50,
width: 30,
height: 30
}, x = ops.x, y = ops.y, w = ops.width, h = ops.height;
ctx.beginPath();
ctx.moveTo(x, y);
heartPoints.push([{
x: x,
y:y
}, {
x: x + w / 2,
y: y - h * 2 / 3
}, {
x: x + w * 2,
y: y + h / 3
}, {
x: x,
y:y+h
}])
heartPoints.push([{
x: x,
y: y+h
}, {
x: x - w * 2,
y: y + h / 3
}, {
x: x - w / 2,
y: y - h * 2 / 3
}, {
x: x,
y: y
}])
ctx.bezierCurveTo(
x + w / 2, y - h * 2 / 3,
x + w * 2, y + h / 3,
x, y + h
);
ctx.bezierCurveTo(
x - w * 2, y + h / 3,
x - w / 2, y - h * 2 / 3,
x, y
);
window.isCurve = function (x2, y2) {
ctx.beginPath();
ctx.moveTo(x, y);
ctx.bezierCurveTo(
x + w / 2, y - h * 2 / 3,
x + w * 2, y + h / 3,
x, y + h
);
ctx.bezierCurveTo(
x - w * 2, y + h / 3,
x - w / 2, y - h * 2 / 3,
x, y
);
if (ctx.isPointInPath(x2, y2)) {
return true;
}
return false;
}
ctx.fill();
// 曲线转成直线
var p1=heartPoints[0].reduce(function(a,b){
return a.concat(b.x,b.y);
}, [])
var p2 = heartPoints[1].reduce(function (a, b) {
return a.concat(b.x, b.y);
}, [])
var p1Points = shapPoints.bezierCurveTo.apply(null, p1)
var p2Points = shapPoints.bezierCurveTo.apply(null, p2)
console.log(p1Points)
//drawPoints(p1Points, true)
// drawPoints(p2Points, true)
var heartBezierPoints = [];
var heartLinePoints = [];
var p4 = p1Points.concat(p2Points);
for (var i = 0,length=p4.length; i < length; i+=2) {
heartLinePoints.push([p4[i], p4[i + 1]])
}
window.heartLinePoints = heartLinePoints;
var b = new bezierjs(heartPoints[0])
var b2 = new bezierjs(heartPoints[1])
var b3 = new bezierjs.PolyBezier([b, b2]);
}
heart();
function Polygon(points) {
ctx.moveTo(points[0][0], points[0][1]);
for (var i = 1, l = points.length; i < l; i++) {
ctx.lineTo(points[i][0], points[i][1]);
}
}
var p2=vec2.fromValues(600,100)
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.lineWidth = 2;
var points=[[600,100],[700,100],[750,150],[700,200],[600,200],[550,150]];
Polygon(points);
ctx.closePath();
ctx.stroke();
function contian(a, b) {
var x = 0;
return a[0] - b[0] <= x && a[1] - b[1] <= x;
}
function windingLine(x0, y0, x1, y1, x, y) {
if ((y > y0 && y > y1) || (y < y0 && y < y1)) {
return 0;
}
// Ignore horizontal line
if (y1 === y0) {
return 0;
}
var dir = y1 < y0 ? 1 : -1;
var t = (y - y0) / (y1 - y0);
//当交点为两条多边形线的连接点时避免缠绕误差
// Avoid winding error when intersection point is the connect point of two line of polygon
if (t === 1 || t === 0) {
dir = y1 < y0 ? 0.5 : -0.5;
}
var x_ = t * (x1 - x0) + x0;
// If (x, y) on the line, considered as "contain".
return x_ === x ? Infinity : x_ > x ? dir : 0;
}
function isAroundEqual(a, b) {
return Math.abs(a - b) < EPSILON;
}
var EPSILON = 1e-8;
function isAroundEqual(a, b) {
return Math.abs(a - b) < EPSILON;
}
function contain(points, x, y) {
var w = 0;x
var p = points[0];
if (!p) {
return false;
}
for (var i = 1; i < points.length; i++) {
var p2 = points[i];
w += windingLine(p[0], p[1], p2[0], p2[1], x, y);
p = p2;
}
var p0 = points[0];
// 第一个点与最后一个点,值相差differ 大于0.00000001,再
if (!isAroundEqual(p[0], p0[0]) || !isAroundEqual(p[1], p0[1])) {
w += windingLine(p[0], p[1], p0[0], p0[1], x, y);
}
return w !== 0;
}
//
function linearRingContainsXY(flatCoordinates, offset, end, stride, x, y) {
// http://geomalgorithms.com/a03-_inclusion.html
/**
版权所有(C / / 2000年softsurfer丹,2012年《星期日泰晤士报
的这段代码可能会用到的自由……和改性的任何用途
提供版权通知,这是与包含它。
softsurfer让好的保单在这个方法的代码,和不能被举行
liable任何房或imagined损伤的功能从它的使用。
用户的这段代码必须验证的正确性的方法及其应用。
*/
let wn = 0;
let x1 = flatCoordinates[end - stride];
let y1 = flatCoordinates[end - stride + 1];
for (; offset < end; offset += stride) {
const x2 = flatCoordinates[offset];
const y2 = flatCoordinates[offset + 1];
if (y1 <= y) {
if (y2 > y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) > 0) {
wn++;
}
} else if (y2 <= y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) < 0) {
wn--;
}
x1 = x2;
y1 = y2;
}
return wn !== 0;
}
function linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y) {
if (ends.length === 0) {
return false;
}
if (!linearRingContainsXY(flatCoordinates, offset, ends[0], stride, x, y)) {
return false;
}
for (let i = 1, ii = ends.length; i < ii; ++i) {
if (linearRingContainsXY(flatCoordinates, ends[i - 1], ends[i], stride, x, y)) {
return false;
}
}
return true;
}
// 绕线算法
function isContainPoint(points,x,y) {
var r=0;
for (var i = 0, length=points.length; i < length; i++) {
var j = (i + 1) % length;
var x2 = points[i][0], y2 = points[i][1];
var x3 = points[j][0], y3 = points[j][1];
//
// 判断点是否在两点之间
if (y >= y2 && y <= y3 && x < ((x3 - x2) * (y - y2) / (y3 - y2) + x2)) {
r++;
} else if (y <= y2 && y >= y3 && x < ((x3 - x2) * (y - y2) / (y3 - y2) + x2)) {
r--;
}
}
return r!=0;
}
function pointInPolygon(vertices, x, y) {
var a, b, i, j;
var xpi, ypi, xpj, ypj;
var c = false;
for (i = 0; i < vertices.length; i++) {
j = (i + 1) % vertices.length;
a = vertices[i];
b = vertices[j];
xpi = a[0];
ypi = a[1];
xpj = b[0];
ypj = b[1];
if ((((ypi <= y) && (y < ypj)) || ((ypj <= y) && (y < ypi))) &&
(x < (xpj - xpi) * (y - ypi) / (ypj - ypi) + xpi)) {
c = !c;
}
}
return c;
}
// x 100 y 100 150 150 x 200 y 200
//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com/math/is-point-in-poly [rev. #0]
function isPointInPoly(poly, x,y) {
var c = false;
for (var i = -1, l = poly.length, j = l - 1; ++i < l; j = i) {
var px = poly[i][0];
var py = poly[i][1];
var px2 = poly[j][0];
var py2 = poly[j][1];
if (((py <= y && y < py2) || (py2 <= y &&y < py))&& (x< (px2- px) * (y - py) / (py2 - py) + px)){
c = !c;
}
}
return c;
}
function isPointInPath(x, y, poly){
var num = poly.length;
var i = 0;
var j = num - 1;
var c = false;
for(;i<num;i++){
if (((poly[i][1] > y) != (poly[j][1] > y)) &&
(x < poly[i][0] + (poly[j][0] - poly[i][0]) * (y - poly[i][1]) /
(poly[j][1] - poly[i][1]))) {
c = true;
}
j = i
}
return c
}
document.addEventListener('click', function (e) {
var x = e.pageX - canvas.offsetLeft, y = e.pageY - canvas.offsetTop;
var invertM = mat2d.invert(mat2d.create(), m);// 逆阵
var xy2 = vec2.transformMat2d(vec2.create(), vec2.fromValues(x, y), m)
// 计算当前图形位置
var xy4 = vec2.transformMat2d(vec2.create(), rectPosition, m)
// 当前鼠标位置
var xy3 = vec2.transformMat2d(vec2.create(), vec2.fromValues(x, y), invertM)
// 正方形
if (contian(rectPosition, xy3) && contian(xy3, vec2.add(vec2.create(), rectPosition, rectPosition)))
{
console.log('rect命中');
}
// 贝塞尔曲线
// console.log('bezier', jsBezier._distanceFromCurve({ x: xy3[0], y: xy3[1] }, heartPoints[0]))
if (isCurve(x, y)) {
console.log('heartLine命2中');
}
if (pointInPolygon(heartLinePoints, xy3[0], xy3[1])) {
console.log('heartLine命中');
}
// 圆形
if (vec2.distance([400, 100], xy3) <= 50) {
console.log('circle命中');
}
// 多边形
if (contain(points, xy3[0], xy3[1])) {
console.log('polygon命中');
}
if (pointInPolygon(points, xy3[0], xy3[1])) {
console.log('polygon3命中');
}
if (isPointInPoly(points, xy3[0], xy3[1])) {
console.log('polygon4命中');
}
if (isContainPoint(points, xy3[0], xy3[1])) {
console.log('polygon5命中');
}
var p2 = points.reduce(function (a, b) { return a.concat(b); }, []);
if (linearRingsContainsXY(p2,0, [p2.length], 2, xy3[0], xy3[1])) {
console.log('polygon2命中');
}
// console.log(x, y, invertM);
})
</script>
</body>
</html>
文章浏览阅读241次。QQ 1274510382Wechat JNZ_aming商业联盟 QQ群538250800技术搞事 QQ群599020441解决方案 QQ群152889761加入我们 QQ群649347320共享学习 QQ群674240731纪年科技aming网络安全 ,深度学习,嵌入式,机器强化,生物智能,生命科学。叮叮叮:产品已上线 —>关注 官方认证-微信公众号——济南纪年信息科技有限公司民生项目:商城加盟/娱乐交友/创业商圈/外包兼职开发-项目发布/安全项目:态.._uniapp 实现关系图谱
文章浏览阅读375次。Created by Jerry Wang on Jul 29, 2014 Go to start of metadata在做middleware相关的scenario操作时,有时候需要evaluate其他user的authorization check log,例如在CRM tcode SMW01里发现BDoc state为validation error,点击show error butto..._查看authorization
文章浏览阅读9.9w次。IMSI国际移动用户识别码(International Mobile Subscriber Identification Number)是区别移动用户的标志,储存在SIM卡中,可用于区别移动用户的有效信息。IMSI是15位的十进制数,其结构为:MCC+MNC+MSIN1.MCCMCC(Mobile Country Code,移动国家码)MCC的资源由国际电联(ITU)统一分配和管理,唯一..._imsi mcc
文章浏览阅读515次。一、id="transfer1"的标签绑定事件$('#transfer1').bind('aEvent',function(event,v1){ v1=v1.substring(1,v1.length-1); var v2=eval("(" + v1 + ")"); layui.use(['transfer', 'layer', 'util'], function(){ var...
文章浏览阅读69次。 近几个月来,不断有网友请我为他们看一下他们的求职简历,因为他们说他们找工作好久了,可一直没有找到,甚至连个通知面试的电话都没有,于是开始怀疑是简历的问题。 尽管不是专门从事人事方面的,但笔者在这方面还是稍有研究,毕竟以前也有过类似的经历,而且还有过比较多的成功面试经验。为此下面谈一下自己的看法。关于面试简历的书写注意事项在我的《网管员面试宝典》一书中已有较详细介绍,在此仅对几个关键注意..._您看我的简历合适吗
文章浏览阅读2.2k次。原文: [AR/VR教程] SteamVR Unity工具包(三):控制器交互 可交互对象(VRTK_InteractableObject)可交互对象脚本被添加到需要用(如控制器)来交互的任何游戏对象上。可用脚本参数如下Touch Interactions 触摸交互· Highlight On Touch:如果勾选,这个对象在控制器触摸它时就_steamvr 稳定unity包
文章浏览阅读3w次,点赞36次,收藏273次。simulink建模之电机模型文章目录simulink建模之电机模型0.前言1.原理分析2.具体步骤2.1第一步:最大扭矩和功率模块2.1.1在恒功率区通过转速查表得出力矩值2.2第二步:电机效率模块2.3第三步:求电流3.总结0.前言由于纯电动车开发越来越火,而对于电机的控制就相当于传统燃油车的发动机的控制,并且电机在生活中使用特别广泛,因此电机仿真模型在整车仿真中具有重要的意义。1.原..._simulink电机模型
文章浏览阅读218次。python 类型转换很简单 想转什么类型只需要在,要转的类型(转的类型) 即可具体的如下x = 10x = type(x)# 确认当前x的类型 打印结果:<type 'int'>print (x)# int 转 String 类型y = str(x)y =type(y)# 确认当前y的类型 打印结果:<type 'str'>print (y)# String 转 int 类型x = "10"y =int(x)y =type(y)# 确认当前y_python y=str(x)
文章浏览阅读315次。错误1:Failed to find Build Tools revision 25.0.3方法:File->settings->Android SDK->SDK Tools点击右下角show Package Details 勾选你需要的版本下载即可,如我这里就是25.0.3..._one or more plugins require a higher android sdk version.
文章浏览阅读4.7k次,点赞3次,收藏6次。#生成并设置好粒子系统#在面板空白处右击打开菜单,并在向量场中选中整体向量场#在整体向量场的细节面板中找到整体向量场的缩放,此处需设置为1#在必需的细节面板中找到使用局部空间,确保此处处于为启用状态#点击下图中红框内的边界旁的三角号,找到并选中设置固定边界,然后保存#作用的效果如下等待后续更新。。。[1]:https://docs.unrealengine.com/zh-CN/Engine/Rendering/ParticleSystems/VectorFields/index.h_ue4怎样让粒子一开始就发射
文章浏览阅读1.6k次。Linux编程点击右侧关注,免费入门到精通!作者丨独木舟的木https://www.jianshu.com/p/fb471ca68a1b步骤进度条效果参考iOS UIKi..._ios 步骤进度条
文章浏览阅读4.6w次,点赞41次,收藏117次。一:何为Promise?为了直观一点,首先我们采用console.dir(Promise)看一下它的结构组成。从上面的图片中我们可以到,Promise其实是一个构造函数,它有resolve,reject,race等静态方法;它的原型(prototype)上有then,catch方法,因此只要作为Promise的实例,都可以共享并调用Promise.prototype上面的方法(t..._promise((resolve, reject)