草庐IT

javascript - 给定矩形上两个对 Angular 线相对的点,如何计算另外两个点

coder 2024-07-24 原文

我试图在从右上角拖动时调整 div 元素的大小 或左下角。

为了计算新的宽度和高度,我需要知道另一个 矩形上的两个点

如何只给定两个点和旋转度数来获得这个值?

请查看我添加的图片以充分理解此问题 另外,div 也可以旋转(原点居中)

  • 澄清我的问题: 目的是通过将鼠标光标从右上角拖动到左下角来调整 div 的大小。然后调整图像大小,使宽度成为 mouseX 到左侧的距离。高度将从 mouseY 到底部。为此,我需要在鼠标光标移动时计算左上角和右下角。 谢谢。

最佳答案

知道两个相对的 Angular 点作为绝对坐标和 Angular 。 (x1,y1)-(x3,y3) 本质上是代表矩形对 Angular 线的旋转线,因此我们可以做:

  • 找到线段的中点和长度(中点到 Angular )
  • 围绕中点“取消旋转”两个点
  • 使用 abs() 和 diffs 来获取宽度和高度

基本代码

// find center point (origin) using linear interpolation
var mx = x1 + (x3 - x1) * 0.5,
    my = y1 + (y3 - y1) * 0.5,
    cos = Math.cos(-angle), sin = Math.sin(-angle);

// unrotate known points (using negative of known angle)
var x1u = cos * (x1-mx) - sin * (y1-my) + mx,
    y1u = sin * (x1-mx) + cos * (y1-my) + my,
    x3u = cos * (x3-mx) - sin * (y3-my) + mx,
    y3u = sin * (x3-mx) + cos * (y3-my) + my;

// Get width and height:
var width  = Math.abs(x3u - x1u),
    height = Math.abs(y3u - y1u);

要获得缺失 Angular 的点,只需旋转由未旋转的点混合而成的新点:

cos = Math.cos(angle);
sin = Math.sin(angle);

// Use known coordinates for the new points:
var x2u = x1u, 
    y2u = y3u,
    x4u = x3u, 
    y4u = y1u;

// rotate new points using angle
var x2 = cos * (x2u-mx) - sin * (y2u-my) + mx,
    y2 = sin * (x2u-mx) + cos * (y2u-my) + my,
    x4 = cos * (x4u-mx) - sin * (y4u-my) + mx,
    y4 = sin * (x4u-mx) + cos * (y4u-my) + my;

绘图演示

该演示将计算“缺失”点、宽度和高度,并显示每一步的结果。输入 Angular 是为了验证它无论如何都有效。

var ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "#e00";
document.querySelector("input").addEventListener("change", update);

function update() {

// Test rect: 50,25 - 350, 175, center: 200,200, W: 300, H: 150

// generate x1,y1 - x3,y3 known points so we have something to work with:
var value = typeof this.value !== "undefined" ? +this.value : 30,
    angle = value * Math.PI / 180,
    x1 = Math.cos(angle) * (50-200) - Math.sin(angle) * (275-200) + 200,
    y1 = Math.sin(angle) * (50-200) + Math.cos(angle) * (275-200) + 200,
    x3 = Math.cos(angle) * (350-200) - Math.sin(angle) * (125-200) + 200,
    y3 = Math.sin(angle) * (350-200) + Math.cos(angle) * (125-200) + 200;

// Initial Visuals: rotated rect, known corner points
ctx.clearRect(0,0,400,400);
ctx.strokeStyle = "#000";
ctx.translate(200,200);
ctx.rotate(angle);
ctx.translate(-200,-200);
ctx.strokeRect(50, 125, 300, 150);
ctx.setTransform(1,0,0,1,0,0);

ctx.fillStyle = "#e00";
ctx.fillRect(x1-2, y1-2, 4, 4); ctx.fillText("x1,y1", x1+5, y1);
ctx.fillRect(x3-2, y3-2, 4, 4); ctx.fillText("x3,y3", x3+5, y3);

// Step 1: find center point (origin)
var mx = x1 + (x3 - x1) * 0.5,
    my = y1 + (y3 - y1) * 0.5;

ctx.fillRect(mx-2, my-2, 4, 4);   // draw center point

// unrotate known points (negative angle)
var x1u = Math.cos(-angle) * (x1-mx) - Math.sin(-angle) * (y1-my) + mx,
    y1u = Math.sin(-angle) * (x1-mx) + Math.cos(-angle) * (y1-my) + my,
    x3u = Math.cos(-angle) * (x3-mx) - Math.sin(-angle) * (y3-my) + mx,
    y3u = Math.sin(-angle) * (x3-mx) + Math.cos(-angle) * (y3-my) + my;

ctx.fillStyle = "#00c";
ctx.fillRect(x1u-2, y1u-2, 4, 4); ctx.fillText("x1u,y1u", x1u+5, y1u-5);
ctx.fillRect(x3u-2, y3u-2, 4, 4); ctx.fillText("x3u,y3u", x3u+5, y3u);

// To get width and height:
var width = Math.abs(x3u - x1u),
    height = Math.abs(y3u - y1u);

ctx.fillText("Size: " + ((width+0.5)|0) + " x " + ((height+0.5)|0), 0, 10);
  
// Mix known coordinates 
var x2u = x1u, y2u = y3u,
    x4u = x3u, y4u = y1u;

// show unrotated points
ctx.fillStyle = "#0c0";
ctx.fillRect(x2u-2, y2u-2, 4, 4); ctx.fillText("x2u,y2u", x2u+5, y2u-5);
ctx.fillRect(x4u-2, y4u-2, 4, 4); ctx.fillText("x4u,y4u", x4u+5, y4u);

// draw lines between unrotated points to show we have an actual rectangle
ctx.strokeStyle = "#777"; ctx.beginPath();
ctx.moveTo(x1u, y1u); ctx.lineTo(x2u, y2u);
ctx.lineTo(x3u, y3u); ctx.lineTo(x4u, y4u);
ctx.closePath(); ctx.stroke();

// rotate new points using angle
var x2 = Math.cos(angle) * (x2u-mx) - Math.sin(angle) * (y2u-my) + mx,
    y2 = Math.sin(angle) * (x2u-mx) + Math.cos(angle) * (y2u-my) + my,
    x4 = Math.cos(angle) * (x4u-mx) - Math.sin(angle) * (y4u-my) + mx,
    y4 = Math.sin(angle) * (x4u-mx) + Math.cos(angle) * (y4u-my) + my;

// show new coordinates
ctx.fillStyle = "#f0f";
ctx.fillRect(x2-2, y2-2, 4, 4); ctx.fillText("x2,y2", x2+5, y2);
ctx.fillRect(x4-2, y4-2, 4, 4); ctx.fillText("x4,y4", x4+5, y4);
}
update();
<script src="https://cdn.rawgit.com/epistemex/slider-feedback/master/sliderfeedback.min.js"></script>
Angle: <input type=range min=0 max=360 value=30><br><canvas width=400 height=400></canvas>

关于javascript - 给定矩形上两个对 Angular 线相对的点,如何计算另外两个点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29573653/

有关javascript - 给定矩形上两个对 Angular 线相对的点,如何计算另外两个点的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐