- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在制作绘图应用程序。我创建了一个类 Polygon
。它的 constructor
将接收三个参数,这些将是它的属性:
我已经尝试了一整天了,但我找不到正确的解决方案。
const canvas = document.querySelector('canvas');
const c = canvas.getContext('2d');
let isMouseDown = false;
let tool = 'polygon';
let savedImageData;
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
const mouse = {x:null,y:null}
let mousedown = {x:null,y:null}
const toDegree = val => val * 180 / Math.PI
class Polygon {
constructor(points, rotation, angles){
this.points = points;
this.rotation = rotation;
//if angles are given then convert them to radian
if(angles){
this.angles = angles.map(x => x * Math.PI/ 180);
}
//if angles array is not given
else{
/*get the angle for a regular polygon for given points.
3-points => 60
4-points => 90
5-points => 108
*/
let angle = (this.points - 2) * Math.PI/ this.points;
//fill the angles array with the same angle
this.angles = Array(points).fill(angle)
}
let sum = 0;
this.angles = this.angles.map(x => {
sum += x;
return sum;
})
}
draw(startx, starty, endx, endy){
c.beginPath();
let rx = (endx - startx) / 2;
let ry = (endy - starty) / 2;
let r = Math.max(rx, ry)
c.font = '35px cursive'
let cx = startx + r;
let cy = starty + r;
c.fillRect(cx - 2, cy - 2, 4, 4); //marking the center
c.moveTo(cx + r, cy);
c.strokeText(0, cx + r, cy);
for(let i = 1; i < this.points; i++){
//console.log(this.angles[i])
let dx = cx + r * Math.cos(this.angles[i] + this.rotation);
let dy = cy + r * Math.sin(this.angles[i] + this.rotation);
c.strokeStyle = 'red';
c.strokeText(i, dx, dy, 100);
c.strokeStyle ='black';
c.lineTo(dx, dy);
}
c.closePath();
c.stroke();
}
}
//update();
c.beginPath();
c.lineWidth = 1;
document.addEventListener('mousemove', function(e){
//Getting the mouse coords according to canvas
const canvasData = canvas.getBoundingClientRect();
mouse.x = (e.x - canvasData.left) * (canvas.width / canvasData.width);
mouse.y = (e.y - canvasData.top) * (canvas.height / canvasData.height);
if(tool === 'polygon' && isMouseDown){
drawImageData();
let pol = new Polygon(5, 0);
pol.draw(mousedown.x, mousedown.y, mouse.x, mouse.y);
}
})
function saveImageData(){
savedImageData = c.getImageData(0, 0, canvas.width, canvas.height);
}
function drawImageData(){
c.putImageData(savedImageData, 0, 0)
}
document.addEventListener('mousedown', () => {
isMouseDown = true;
mousedown = {...mouse};
if(tool === 'polygon'){
saveImageData();
}
});
document.addEventListener('mouseup', () => isMouseDown = false);
<canvas></canvas>
在上面的代码中,我试图制作一个五边形,但它不起作用。
最佳答案
以下代码片段包含一个函数 polygonFromSidesOrAngles
返回定义输入参数定义的单位多边形的点集。 sides
, 或 angles
两个参数都是可选的,但必须有一个参数
sides
给定然后计算 Angular 以使所有边长相等的完整多边形angles
给定则假定边数为 Angular 数。 Angular 为 0-360 度返回的是定义多边形点的单位圆上的一组点。第一点在坐标 {x : 1, y: 0}
处从原点开始。
返回的点没有旋转,因为它被假定为渲染函数的函数。
多边形上的所有点距原点(0,0)1个单位距离
点的形式是包含x
的对象和 y
由函数 point
定义的属性和 polarPoint
我没有查找算法,而是根据假设从 (1,0) 到单位圆上以所需 Angular 一条线将在与 (1,0) 的正确距离处截取圆。截取点用于计算与原点的弧度 Angular 。然后使用该 Angular 来计算该 Angular 所代表的总 Angular 比率。
执行此操作的函数是 calcRatioOfAngle(angle, sides)
返回 Angular 作为 Math.PI * 2
的比率 (0-1)
这是一种相当长手的方法,可能会显着减少
由于您的问题不清楚应该如何处理无效参数,如果函数无法继续,该函数将抛出范围错误。
Math.PI2 = Math.PI * 2;
Math.TAU = Math.PI2;
Math.deg2Rad = Math.PI / 180;
const point = (x, y) => ({x, y});
const polarPoint = (ang, dist) => ({x: Math.cos(ang) * dist, y: Math.sin(ang) * dist});
function polygonFromSidesOrAngles(sides, angles) {
function calcRatioOfAngle(ang, sides) {
const v1 = point(Math.cos(ang) - 1, Math.sin(ang));
const len2 = v1.x * v1.x + v1.y * v1.y;
const u = -v1.x / len2;
const v2 = point(v1.x * u + 1, v1.y * u);
const d = (1 - (v2.y * v2.y + v2.x * v2.x)) ** 0.5 / (len2 ** 0.5);
return Math.atan2(v2.y + v1.y * d, v2.x + 1 + v1.x * d) / (Math.PI * (sides - 2) / 2);
}
const vetAngles = angles => angles.reduce((sum, ang) => sum += ang, 0) === (angles.length - 2) * 180;
var ratios = [];
if(angles === undefined) {
if (sides < 3) { throw new RangeError("Polygon must have more than 2 side") }
const rat = 1 / sides;
while (sides--) { ratios.push(rat) }
} else {
if (sides === undefined) { sides = angles.length }
else if (sides !== angles.length) { throw new RangeError("Numbers of sides does not match number of angles") }
if (sides < 3) { throw new RangeError("Polygon must have more than 2 side") }
if (!vetAngles(angles)) { throw new RangeError("Set of angles can not create a "+sides+" sided polygon") }
ratios = angles.map(ang => calcRatioOfAngle(ang * Math.deg2Rad, sides));
ratios.unshift(ratios.pop()); // rotate right to get first angle at start
}
var ang = 0;
const points = [];
for (const rat of ratios) {
ang += rat;
points.push(polarPoint(ang * Math.TAU, 1));
}
return points;
}
渲染多边形的函数。它包括旋转,因此您无需为要渲染多边形的每个 Angular 创建一组单独的点。
半径是到中心点的距离x,y
到任何多边形顶点。
function drawPolygon(ctx, poly, x, y, radius, rotate) {
ctx.setTransform(radius, 0, 0, radius, x, y);
ctx.rotate(rotate);
ctx.beginPath();
for(const p of poly.points) { ctx.lineTo(p.x, p.y) }
ctx.closePath();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.stroke();
}
下面呈现一组测试多边形以确保代码按预期工作。多边形从顶部开始旋转,然后顺时针渲染。
该示例已删除对输入参数的审查。
const ctx = can.getContext("2d");
can.height = can.width = 512;
Math.PI2 = Math.PI * 2;
Math.TAU = Math.PI2;
Math.deg2Rad = Math.PI / 180;
const point = (x, y) => ({x, y});
const polarPoint = (ang, dist) => ({x: Math.cos(ang) * dist, y: Math.sin(ang) * dist});
function polygonFromAngles(sides, angles) {
function calcRatioOfAngle(ang, sides) {
const x = Math.cos(ang) - 1, y = Math.sin(ang);
const len2 = x * x + y * y;
const u = -x / len2;
const x1 = x * u + 1, y1 = y * u;
const d = (1 - (y1 * y1 + x1 * x1)) ** 0.5 / (len2 ** 0.5);
return Math.atan2(y1 + y * d, x1 + 1 + x * d) / (Math.PI * (sides - 2) / 2);
}
var ratios = [];
if (angles === undefined) {
const rat = 1 / sides;
while (sides--) { ratios.push(rat) }
} else {
ratios = angles.map(ang => calcRatioOfAngle(ang * Math.deg2Rad, angles.length));
ratios.unshift(ratios.pop());
}
var ang = 0;
const points = [];
for(const rat of ratios) {
ang += rat;
points.push(polarPoint(ang * Math.TAU, 1));
}
return points;
}
function drawPolygon(poly, x, y, radius, rot) {
const xdx = Math.cos(rot) * radius;
const xdy = Math.sin(rot) * radius;
ctx.setTransform(xdx, xdy, -xdy, xdx, x, y);
ctx.beginPath();
for (const p of poly) { ctx.lineTo(p.x, p.y) }
ctx.closePath();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.stroke();
}
const segs = 4;
const tests = [
[3], [, [45, 90, 45]], [, [90, 10, 80]], [, [60, 50, 70]], [, [40, 90, 50]],
[4], [, [90, 90, 90, 90]], [, [90, 60, 90, 120]],
[5], [, [108, 108, 108, 108, 108]], [, [58, 100, 166, 100, 116]],
[6], [, [120, 120, 120, 120, 120, 120]], [, [140, 100, 180, 100, 100, 100]],
[7], [8],
];
var angOffset = -Math.PI / 2; // rotation of poly
const w = ctx.canvas.width;
const h = ctx.canvas.height;
const wStep = w / segs;
const hStep = h / segs;
const radius = Math.min(w / segs, h / segs) / 2.2;
var x,y, idx = 0;
for (y = 0; y < segs && idx < tests.length; y ++) {
for (x = 0; x < segs && idx < tests.length; x ++) {
drawPolygon(polygonFromAngles(...tests[idx++]), (x + 0.5) * wStep , (y + 0.5) * hStep, radius, angOffset);
}
}
canvas {
border: 1px solid black;
}
<canvas id="can"></canvas>
关于javascript - 如何使用给定的 Angular 绘制不规则形状的多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57933404/
我是 TensorFlow 菜鸟。我已经从 deeppose 的开源实现中训练了一个 TensorFlow 模型,现在必须针对一组新图像运行该模型。 该模型是在大小为 100 * 100 的图像上训练
我正在尝试以这种方式设置节点的大小: controller[shape=circle,width=.5,label="Controller",style=filled,fillcolor="#8EC1
是否有 VBA 代码可以在选择的每个单元格周围添加文本框。文本框应该是单元格的大小(类似于边框)? 最佳答案 您可以使用 .AddTextbox方法。循环遍历您选择的单元格,并使用单元格的尺寸属性来设
我有一个变量 a尺寸 (1, 5) 我想“平铺”的次数与我的小批量的大小一样多。例如,如果小批量大小为 32,那么我想构造一个张量 c维度为 (32, 5),其中每一行的值与原始 (1, 5) 变量
我在使用 javaFX 时遇到问题。我想每 1000 毫秒在应用程序窗口中显示一次时间。 public class Main extends Application { StackPane root
所以我目前正在创建这个 API。这个登录类应该只创建一个场景,其中包含制作 GUI 所需的所有框。我遇到的问题是,单击时我的形状不会执行任何操作。我有事件监听器,但它不起作用。 import
我正在用 python turtle 画一些东西,我使用了形状函数,但是形状 overdraw 了它们之前的其他形状(我可以看到形状在移动),并且我只得到了最后一个形状: `up() goto(-20
我正在读取多个 .csv 文件作为具有相同形状的 panda DataFrame。对于某些索引,某些值为零,因此我想选择具有相同形状的每个索引的值,并为相同的索引放置零值并删除零以成为相同的形状: a
我有一个简单的二维网格,格式为 myGrid[x,y] 我正在尝试找到一种方法来找到围绕选定网格的周长,这样我就有了一个可供选择的形状。 这是我的意思的一个例子: 这里的想法是找到所有相关的“角”,也
我有一个网络层,用于调用多个端点。我想减少重复代码的数量,并认为也许我可以将响应模型作为端点的一部分传递。 这个想法是不需要多个仅因响应而不同的函数,我可以调用我的网络层并根据路径进行设置。 我看到的
我正在创建一个自定义 ImageView,它将我的图像裁剪成六边形并添加边框。我想知道我的方法是否正确,或者我是否以错误的方式这样做。有很多自定义库已经在执行此操作,但开箱即用的库中没有一个具有我正在
我正在编写一些代码,这些代码需要识别一些基于节点云的相当基本的几何图形。我会对检测感兴趣: 板(简单有界平面) 圆柱体(两个节点循环) 半圆柱(圆弧+直线+圆弧+直线) 圆顶(n*loop+top n
我有这个形状: http://screencast.com/t/9UUhAXT5Wu 但边界在截止点处没有跟随它 - 我该如何解决? 这是我当前 View 的代码: self.view.backgro
我现在脑震荡,所以我想问一个非常简单的问题。 目前,我正在尝试打印出这样的开头 当输入为 7 时,输出为 * ** * ** * ** * 这里是我的代码,它打印 14 次而不是 7 次,或者当我输入
我想生成如下设计。计划选项卡顶部的"new"。我使用的属性适用于 chrome 和 mozilla,但在 Edge 中出现故障。 以下是我在 chrome 中应用的样式: a.subnav__item
我想要一个带有两种颜色边框轮廓的 shape 元素。我可以使用 solid 元素做一个单一的颜色轮廓,但这只允许我画一条线。我尝试在我的形状中使用两个 stroke 元素,但这也不起作用。 有没有办法
我需要为屏幕上的形状着色任何我想要的颜色。我目前正在尝试使用 UIImage 来执行此操作,我想根据自己的需要重新着色。据我所知,执行此操作的唯一方法是获取 UIImage 的各个像素,这需要更多我想
因此,经过多年的 OOP,我从我的一门大学类(class)中得到了一个非常简单的家庭作业,以实现一个简单的面向对象的结构。 要求的设计: 实现面向对象的解决方案以创建以下形状: 椭圆、圆形、正方形、矩
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我想知道是否可以使用类似于以下的 div 制作复杂的形状: 它基本上是一个四 Angular 向内收缩的圆 Angular 正方形。目标是使用背景图像来填充它。我可以使用具有以下 SVG 路径的剪辑蒙
我是一名优秀的程序员,十分优秀!