倾斜,调整大小并旋转矩形以完美适合三角形 [英] Skew, size and rotate a rectangle to fit triangle perfectly

查看:129
本文介绍了倾斜,调整大小并旋转矩形以完美适合三角形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个矩形的一半-对角分开-以适合三角形。
旋转效果很好,矩形的大小也是如此。但是,一旦我尝试倾斜它,一切都会变得混乱。基本上我想模拟3D表面。

I'm trying to make half of a rectangle - devided diagonally - to fit inside a triangle. Rotation works well, so does sizing of the rectangle. But once I try to skew it, it all gets messed up. Basically I want to simulate a 3D surface.

这意味着我必须找到abc角,其中b是中心点。然后将此角度作为偏斜应用于矩形。但是由于某些原因,它无法正常工作。

That means I have to find the angle of abc, where b is the center point. And then apply this angle as a skew to the rectangle. But for some reason that doesn't work as intended.

以下是我要完成的工作的简单说明:

Here is a simple illustration of what I want to accomplish:

看看小提琴,您可能会了解更多: http://jsfiddle.net/p7g7Y/11/
编辑:至少正确的宽度: http://jsfiddle.net/p7g7Y/12/

You will probably understand more once you take a look at the fiddle: http://jsfiddle.net/p7g7Y/11/ Got the width right at least: http://jsfiddle.net/p7g7Y/12/

您需要查看的代码在第63-95行。
尝试注释掉转换,您会发现旋转和大小效果很好。

The piece of code you need to look at is at line 63 - 95. Try comment out the transform, and you will see that rotation and size works well.

function triangle(a, b, c){

context.save();

//Draw the triangle
context.beginPath();
context.moveTo(a[0], a[1]);
context.lineTo(b[0], b[1]);
context.lineTo(c[0], c[1]);
context.lineTo(a[0], a[1]);
context.closePath();
context.stroke();

//Lets find the distance between a and b to set height of the image
var imgHeight = lineDistance(a, b);

//And the width b to c
var imgWidth = lineDistance(b, c);

//Now we gotta skew it acording to the rad between ba and bc
var skewAngle = find_angle(a,c,b); //Find angle and make it rad

//Find the angle of b to a line
var theta = Math.atan2(a[1] - b[1], a[0] - b[0]);
context.translate(a[0], a[1]); //Set origin of rotation
context.rotate(theta + 1.57079633); //Had to rotate it some more 1.57079633 = 90deg
context.transform(1, skewAngle, 0, 1, 0, 0);

context.rect( 0, 0, imgHeight, imgWidth);
context.stroke();

context.restore();
}

如果不清楚,请询问!我希望对此有所帮助!

If anything is unclear, please ask! I would love some help on this!

推荐答案

如果更一般地解决问题,会更容易:查找 a b c d e f ,这样

It's easier if you solve the problem more generally: find a, b, c, d, e and f so that

  // (x0, y0) maps to (x_0, y_0)
  a*x0 + b*y0 + c = x_0
  d*x0 + e*y0 + f = y_0

  // (x1, y1) maps to (x_1, y_1)
  a*x1 + b*y1 + c = x_1
  d*x1 + e*y1 + f = y_1

  // (x2, y2) maps to (x_2, y_2)
  a*x2 + b*y2 + c = x_2
  d*x2 + e*y2 + f = y_2

此6x6线性系统由两个独立的3x3线性系统组成:

This 6x6 linear system is composed of two independent 3x3 linear systems:

  a*x0 + b*y0 + c = x_0
  a*x1 + b*y1 + c = x_1
  a*x2 + b*y2 + c = x_2

  d*x0 + e*y0 + f = y_0
  d*x1 + e*y1 + f = y_1
  d*x2 + e*y2 + f = y_2

求解它们会给您6个数字,以传递给 setTransform 映射任何三个poi nts到其他三个点。

Solving them gives you the 6 numbers to pass to setTransform to map any three points to other three points.

delta = x0*y1 + y0*x2 + x1*y2 - y1*x2 - y0*x1 - x0*y2

delta_a = x_0*y1 + y0*x_2 + x_1*y2 - y1*x_2 - y0*x_1 - x_0*y2
delta_b = x0*x_1 + x_0*x2 + x1*x_2 - x_1*x2 - x_0*x1 - x0*x_2
delta_c = x0*y1*x_2 + y0*x_1*x2 + x_0*x1*y2 - x_0*y1*x2 - y0*x1*x_2 - x0*x_1*y2

delta_d = y_0*y1 + y0*y_2 + y_1*y2 - y1*y_2 - y0*y_1 - y_0*y2
delta_e = x0*y_1 + y_0*x2 + x1*y_2 - y_1*x2 - y_0*x1 - x0*y_2
delta_f = x0*y1*y_2 + y0*y_1*x2 + y_0*x1*y2 - y_0*y1*x2 - y0*x1*y_2 - x0*y_1*y2

a = delta_a / delta
b = delta_b / delta
c = delta_c / delta
d = delta_d / delta
e = delta_e / delta
f = delta_f / delta

有关3d纹理映射的完整说明使用2d画布上下文,请参见此更详细的答案

For a full description of 3d texture mapping using 2d canvas context see this more detailed answer.

这篇关于倾斜,调整大小并旋转矩形以完美适合三角形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆