在肩膀和手之间创建肘关节
Creating an elbow joint between shoulder and hand
我一直在尝试制作一个函数,returns 肘关节的位置基于臂段长度以及肩膀和手的位置。但是,尽管我尽了最大努力,我的方法还是行不通!
这是我到目前为止尝试过的方法:
var x = 0;
var y = 0;
var r = 0;
while(dist(x, y, p1x, p1y) > segLength-1 && dist(x, y, p1x, p1y) < segLength+1 && dist(x, y, p2x, p2y) > segLength-1 && dist(x, y, p2x, p2y) < segLength + 1){
r ++;
x = 200 + (cos(r) * segLength);
y = 200 + (sin(r) * segLength);
}
我知道在这个距离上有两个不同的点,我想选择最有意义的一个作为肘关节(通常是下一个)
我正在使用 Khan Academy 的 Processing 环境,所以我不能使用 ES6 语法(遗憾)。
Circle-circle intersection points
帮助了我。
下面是工作代码,做我最初想要它做的事情(画一只手臂)
// from stack overflow
//{
// Let EPS (epsilon) be a small value
var EPS = 0.0000001;
// Let a point be a pair: (x, y)
function Point(x, y) {
this.x = x;
this.y = y;
}
// Define a circle centered at (x,y) with radius r
function Circle(x,y,r) {
this.x = x;
this.y = y;
this.r = r;
}
// Due to double rounding precision the value passed into the Math.acos
// function may be outside its domain of [-1, +1] which would return
// the value NaN which we do not want.
function acossafe(x) {
if (x >= +1.0){return 0;}
if (x <= -1.0){return 360;}
return Math.acos(x);
}
// Rotates a point about a fixed point at some angle 'a'
function rotatePoint(fp, pt, a) {
var x = pt.x - fp.x;
var y = pt.y - fp.y;
var xRot = x * Math.cos(a) + y * Math.sin(a);
var yRot = y * Math.cos(a) - x * Math.sin(a);
return new Point(fp.x+xRot,fp.y+yRot);
}
// Given two circles this method finds the intersection
// point(s) of the two circles (if any exists)
function circleCircleIntersectionPoints(c1, c2) {
var r, R, d, dx, dy, cx, cy, Cx, Cy;
if (c1.r < c2.r) {
r = c1.r; R = c2.r;
cx = c1.x; cy = c1.y;
Cx = c2.x; Cy = c2.y;
} else {
r = c2.r; R = c1.r;
Cx = c1.x; Cy = c1.y;
cx = c2.x; cy = c2.y;
}
// Compute the vector <dx, dy>
dx = cx - Cx;
dy = cy - Cy;
// Find the distance between two points.
d = Math.sqrt( dx*dx + dy*dy );
// There are an infinite number of solutions
// Seems appropriate to also return null
if (d < EPS && abs(R-r) < EPS){return [];}
// No intersection (circles centered at the
// same place with different size)
else if (d < EPS){
return [];
}
var x = (dx / d) * R + Cx;
var y = (dy / d) * R + Cy;
var P = new Point(x, y);
// Single intersection (kissing circles)
if (abs((R+r)-d) < EPS || abs(R-(r+d)) < EPS){return [P];}
// No intersection. Either the small circle contained within
// big circle or circles are simply disjoint.
if ( (d+r) < R || (R+r < d) ){return [];}
var C = new Point(Cx, Cy);
var angle = acossafe((r*r-d*d-R*R)/(-2.0*d*R));
var pt1 = rotatePoint(C, P, +angle);
var pt2 = rotatePoint(C, P, -angle);
return [pt1, pt2];
}
//}\
function drawArm(startX, startY, endX, endY, segLength){
var Circle_1 = new Circle(startX, startY, segLength);
var Circle_2 = new Circle(endX, endY, segLength);
noFill();
/*
strokeWeight(2);
ellipse(Circle_1.x, Circle_1.y, Circle_1.r*2, Circle_1.r*2);
ellipse(Circle_2.x, Circle_2.y, Circle_2.r*2, Circle_2.r*2);
*/
var points = circleCircleIntersectionPoints(Circle_1, Circle_2);
/*
for(var i = 0; i<points.length; i++){
strokeWeight(8);
point(points[i].x, points[i].y);
}
*/
points.sort(function(a, b){
return b.y - a.y;
});
line(startX, startY, points[0].x, points[0].y);
line(endX, endY, points[0].x, points[0].y);
}
draw = function() {
background(255, 255, 255);
drawArm(50, 200, 200, 200, 100);
};
- 可以进行一些小的修改以防止错误
我一直在尝试制作一个函数,returns 肘关节的位置基于臂段长度以及肩膀和手的位置。但是,尽管我尽了最大努力,我的方法还是行不通!
这是我到目前为止尝试过的方法:
var x = 0;
var y = 0;
var r = 0;
while(dist(x, y, p1x, p1y) > segLength-1 && dist(x, y, p1x, p1y) < segLength+1 && dist(x, y, p2x, p2y) > segLength-1 && dist(x, y, p2x, p2y) < segLength + 1){
r ++;
x = 200 + (cos(r) * segLength);
y = 200 + (sin(r) * segLength);
}
我知道在这个距离上有两个不同的点,我想选择最有意义的一个作为肘关节(通常是下一个)
我正在使用 Khan Academy 的 Processing 环境,所以我不能使用 ES6 语法(遗憾)。
Circle-circle intersection points 帮助了我。
下面是工作代码,做我最初想要它做的事情(画一只手臂)
// from stack overflow
//{
// Let EPS (epsilon) be a small value
var EPS = 0.0000001;
// Let a point be a pair: (x, y)
function Point(x, y) {
this.x = x;
this.y = y;
}
// Define a circle centered at (x,y) with radius r
function Circle(x,y,r) {
this.x = x;
this.y = y;
this.r = r;
}
// Due to double rounding precision the value passed into the Math.acos
// function may be outside its domain of [-1, +1] which would return
// the value NaN which we do not want.
function acossafe(x) {
if (x >= +1.0){return 0;}
if (x <= -1.0){return 360;}
return Math.acos(x);
}
// Rotates a point about a fixed point at some angle 'a'
function rotatePoint(fp, pt, a) {
var x = pt.x - fp.x;
var y = pt.y - fp.y;
var xRot = x * Math.cos(a) + y * Math.sin(a);
var yRot = y * Math.cos(a) - x * Math.sin(a);
return new Point(fp.x+xRot,fp.y+yRot);
}
// Given two circles this method finds the intersection
// point(s) of the two circles (if any exists)
function circleCircleIntersectionPoints(c1, c2) {
var r, R, d, dx, dy, cx, cy, Cx, Cy;
if (c1.r < c2.r) {
r = c1.r; R = c2.r;
cx = c1.x; cy = c1.y;
Cx = c2.x; Cy = c2.y;
} else {
r = c2.r; R = c1.r;
Cx = c1.x; Cy = c1.y;
cx = c2.x; cy = c2.y;
}
// Compute the vector <dx, dy>
dx = cx - Cx;
dy = cy - Cy;
// Find the distance between two points.
d = Math.sqrt( dx*dx + dy*dy );
// There are an infinite number of solutions
// Seems appropriate to also return null
if (d < EPS && abs(R-r) < EPS){return [];}
// No intersection (circles centered at the
// same place with different size)
else if (d < EPS){
return [];
}
var x = (dx / d) * R + Cx;
var y = (dy / d) * R + Cy;
var P = new Point(x, y);
// Single intersection (kissing circles)
if (abs((R+r)-d) < EPS || abs(R-(r+d)) < EPS){return [P];}
// No intersection. Either the small circle contained within
// big circle or circles are simply disjoint.
if ( (d+r) < R || (R+r < d) ){return [];}
var C = new Point(Cx, Cy);
var angle = acossafe((r*r-d*d-R*R)/(-2.0*d*R));
var pt1 = rotatePoint(C, P, +angle);
var pt2 = rotatePoint(C, P, -angle);
return [pt1, pt2];
}
//}\
function drawArm(startX, startY, endX, endY, segLength){
var Circle_1 = new Circle(startX, startY, segLength);
var Circle_2 = new Circle(endX, endY, segLength);
noFill();
/*
strokeWeight(2);
ellipse(Circle_1.x, Circle_1.y, Circle_1.r*2, Circle_1.r*2);
ellipse(Circle_2.x, Circle_2.y, Circle_2.r*2, Circle_2.r*2);
*/
var points = circleCircleIntersectionPoints(Circle_1, Circle_2);
/*
for(var i = 0; i<points.length; i++){
strokeWeight(8);
point(points[i].x, points[i].y);
}
*/
points.sort(function(a, b){
return b.y - a.y;
});
line(startX, startY, points[0].x, points[0].y);
line(endX, endY, points[0].x, points[0].y);
}
draw = function() {
background(255, 255, 255);
drawArm(50, 200, 200, 200, 100);
};
- 可以进行一些小的修改以防止错误