如何根据线的方向移动点。

huangapple go评论70阅读模式
英文:

How to move the Point according the line orientation

问题

我正在使用React THREEJS和一些其他库(DREI,Meshline等)来绘制线条和文本等。现在我正在绘制一条线,我必须同时显示长度标签。应该是这样的。

如何根据线的方向移动点。

现在我必须添加一个选项来根据线的方向移动标签位置。例如:

  • 垂直线应该在X轴上有(左/右)移动
  • 水平线应该在Y轴上有(上/下)移动

我已经计算了向量点(P1/P2)的中间位置。

const P1 = new THREE.Vector3(-300.79, -296.96, 0);
const P2 = new THREE.Vector3(101.49,  -8.43, 0);

const disX = (P2.x + P1.x) / 2;
const disY = (P2.y + P1.y) / 2;

const P3 = new THREE.Vector3(disX, disY, 0);

你能给我提供一些建议吗?

英文:

I am using React THREEJS and some other libraries (DREI, Meshline, etc) to draw the Lines and Text, etc. Right Now I am drawing a line and I have to show the length label along with the line. It will be something like this.

如何根据线的方向移动点。

Now I have to add an option to move the label position according to line orientation. For example

  • Vertical Line should have movement (Left/Right) X-AXIS
  • Horizontal Line should have (Top/Bottom) Y-AXIS

I have already calculated the middle position of the Vector Points (P1/P2).

  const P1 = new THREE.Vector3(-300.79, -296.96, 0);
  const P2 = new THREE.Vector3(101.49,  -8.43, 0);

  const disX = (P2.x + P1.x) / 2;
  const disY = (P2.y + P1.Y) / 2;

  const P3 = new THREE.Vector3(disX, disY, 0);

Can you please suggest to me any solution?

答案1

得分: 1

当您知道两点的坐标时,其方向向量 (dir) 的法线 (norm) 是 norm(-dir.y, dir.x);

英文:

When you know coordinates of two points, the normal (norm) to the vector of their direction (dir) is norm(-dir.y, dir.x);

Here is an example (not the ultimate solution):

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

body{
  overflow: hidden;
  margin: 0;
}

<!-- language: lang-html -->

&lt;script async src=&quot;https://ga.jspm.io/npm:es-module-shims@1.6.3/dist/es-module-shims.js&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;importmap&quot;&gt;
  {
    &quot;imports&quot;: {
      &quot;three&quot;: &quot;https://unpkg.com/three@0.153.0/build/three.module.js&quot;,
      &quot;three/addons/&quot;: &quot;https://unpkg.com/three@0.153.0/examples/jsm/&quot;
    }
  }
&lt;/script&gt;
&lt;script type=&quot;module&quot;&gt;
import * as THREE from &quot;three&quot;;
console.clear();

let scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);

let frustumSize = 10;
let aspect = innerWidth / innerHeight;
let camera = new THREE.OrthographicCamera(frustumSize * aspect / - 2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, 1, 100);
camera.position.set(0, 0, 10);
camera.lookAt(scene.position);
let renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener(&quot;resize&quot;, (event) =&gt; {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
});

let pts = [
  new THREE.Vector2(-3, 3),
  new THREE.Vector2(-3, -2),
  new THREE.Vector2(2, -3),
  new THREE.Vector2(3, 3.5)
];

for(let i = 0; i &lt; pts.length; i++){
  let p1 = pts[i];
  setPoint(p1);
  if (i == pts.length - 1) continue;
  let p2 = pts[i+1];
  setLine(p1, p2);
  
  let midP = new THREE.Vector3().lerpVectors(p1, p2, 0.5);
  let shift = new THREE.Vector2().subVectors(p2, p1).normalize();
  let angle = shift.angle();
  
  let swapX = shift.x;
  let swapY = shift.y;
  shift.set(-swapY, swapX).negate().setLength(0.5);
  
  let distance = p1.distanceTo(p2);
  setMarker(midP, shift, angle, distance);
}

function setPoint(pos){
  let g = new THREE.RingGeometry(0.5, 1, 32);
  let m = new THREE.MeshBasicMaterial({color: &quot;teal&quot;});
  let o = new THREE.Mesh(g, m);
  o.scale.setScalar(0.1);
  o.position.set(pos.x, pos.y, 0.01);
  scene.add(o);
}

function setLine(pos1, pos2){
  let g = new THREE.BufferGeometry().setFromPoints([pos1, pos2]);
  let m = new THREE.LineBasicMaterial({color: &quot;maroon&quot;});
  let l = new THREE.Line(g, m);
  scene.add(l);
}

function setMarker(pos, shift, angle, distance){
  let g = new THREE.PlaneGeometry(4, 1);
  let m = new THREE.MeshBasicMaterial({
    color: &quot;black&quot;,
    transparent: true,
    map: getDistanceTexture(distance)
  });
  let o = new THREE.Mesh(g, m);
  o.position.set(pos.x + shift.x, pos.y + shift.y, 0);
  o.rotation.z = angle;
  o.scale.setScalar(1);
  scene.add(o);
}

function getDistanceTexture(value){
  let text = value.toFixed(1) + &quot;m&quot;;
  let c = document.createElement(&quot;canvas&quot;);
  c.width = 64 * 4;
  c.height = 64;
  let ctx = c.getContext(&quot;2d&quot;);
  ctx.textAlign = &quot;center&quot;;
  ctx.textBaseline = &quot;middle&quot;;
  ctx.font = &quot;60px Arial&quot;;
  ctx.fillStyle = &quot;white&quot;;
  ctx.fillText(text, 64 * 2, 64 / 2);
  let ct = new THREE.CanvasTexture(c);
  return ct;
}
renderer.setAnimationLoop((_) =&gt; {
  renderer.render(scene, camera);
});

&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月16日 14:23:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76487434.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定