Locating the point of intersection within a polygon with itself

I am attempting to identify instances of self-intersection in a polygon in order to prevent users from creating them. Users are only permitted to draw the polygon on a plane formed by connecting the coplanar points they plot in 3D space.

My initial approach involved aligning these points parallel to the X-Z plane and then checking for intersections between line segments. While I could successfully detect intersections in 2D, rotating these points did not maintain their shape or alignment with the XZ axis, leading to issues during intersection testing.

Before rotation: https://i.sstatic.net/Yr35i.png

After rotation https://i.sstatic.net/LaFUE.png

This is my current rotation method.

const angle = pos.angleTo(new THREE.Vector3(0, 1, 0)) // pos here represents the position vector of the circle
const rotationMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(1, 0, 0), -angle); // rotate around x Axis
rotationMatrix.makeRotationAxis(new THREE.Vector3(0, 0, 1), -angle) // rotate around z axis
circle.applyMatrix4(rotationMatrix);

The goal is to rotate the vertices so that they align parallel to the XZ axes without distorting their original shape. As a newcomer to three.js, I believe there may be something crucial missing from my implementation.

How can I accurately rotate the vertices to achieve parallel alignment with the XZ axes while preserving the shape?

Answer №1

My goal was to determine the self-intersection of a polygon to prevent users from creating polygons with self-intersections. To achieve this, I implemented a method that involves projecting the polygon onto a 2D coordinate system and checking for any intersecting line segments.

To project vectors in 3D, you can utilize the Vector3.project(camera) function, which returns the projection in xy coordinates. Subsequently, you can employ line-segment intersection algorithms to detect intersections.

Below is a brief code snippet demonstrating this process:

function projectFromCamera(vertices, camera) {
  const projection = vertices.map((p) => p.clone().project(camera));
  return projection.map((p) => new THREE.Vector2(p.x, p.y));
}

/**
 * Checks if the last line segment intersects with any other segment
 *
 * @param {THREE.Vector3 []} vertices
 * @param {THREE.Camera} camera
 * @returns
 */
export function isPointIntersectingPolygon(vertices, camera) {
  const projection = projectFromCamera(vertices, camera);

  let intersecting = false;
  for (let x = 0; x < projection.length - 3; x++) {
    intersecting = checkLineIntersection(
      projection.at(-2),
      projection.at(-1),
      projection[x],
      projection[x + 1],
    );
    if (intersecting) break;
  }

  return intersecting;
}

/**
 * Checks if the polygon is self-intersecting
 *
 * @param {THREE.Vector3} vertices
 * @param {THREE.Camera} camera
 * @returns
 */
export function checkPolygonSelfIntersecting(vertices, camera) {
  const projection = projectFromCamera(vertices, camera);

  let intersecting = isPointIntersectingPolygon(vertices, camera);

  console.log("actual projection: ", projection, intersecting);

  for (let x = 1; x < projection.length - 2; x++) {
    intersecting = checkLineIntersection(
      projection.at(0),
      projection.at(-1),
      projection[x],
      projection[x + 1],
    );
    console.log("intersecting: ", x, intersecting);
    
    if (intersecting) break;
  }

  return intersecting;
}

//credits: https://jsfiddle.net/justin_c_rounds/Gd2S2/light/
function checkLineIntersection(v1, v2, v3, v4) {
  // algorithm to check for line intersection

  let line1StartX = v1.x;
  let line1StartY = v1.y;
  let line1EndX = v2.x;
  let line1EndY = v2.y;
  let line2StartX = v3.x;
  let line2StartY = v3.y;
  let line2EndX = v4.x;
  let line2EndY = v4.y;

  let denominator,
    a,
    b,
    numerator1,
    numerator2,
    result = {
      x: null,
      y: null,
      onLine1: false,
      onLine2: false,
    };

  // calculation logic for intersection
  ...

  return result.onLine1 && result.onLine2;
}

For a complete example of polygon area calculation using Three.js, visit the demo on CodeSandbox (press Shift key to start drawing).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Lock the three.js camera to the top-down orientation of a vehicle

In my project utilizing Three.js, I have successfully implemented a camera that follows a car. The orbit camera feature is enabled, but I also want to allow users to switch to a top-down view (which is already functioning). However, in this top-down view, ...

Tips for managing the react-bootstrap carousel using personalized buttons

In order to have control over carousel slides using custom buttons, I managed to achieve this with reference to this Example. Below is the code implementation: import React, { useState } from "react"; import { Carousel, Button, Container, Row } ...

What is the process for connecting controls to Canvas sprites?

Any input is EXTREMELY helpful! To put it shortly, I'm in need of assistance with utilizing HTML5/CSS3 buttons to manage sprite animations on my canvas. These buttons are responsible for controlling the direction and speed of the sprites independentl ...

Using jQuery to retrieve the id with [id^=''] when making an AJAX request, then populating and generating a table based on the retrieved data

In my jQuery code, I am using AJAX to fetch data and then creating a simple table with that data. Here is an example: $.ajax({ method: 'GET', url: '/analyzePage/searchTag/' + tagName, contentType: false, processData: fa ...

merge a pair of scopes within Angular

I have a dilemma with merging two different scopes. Can someone suggest the most efficient method to achieve this? Here are details of the scopes in question; the second one originates from a service. The initial scope retrieves information from the datab ...

A method to retrieve the content of an input field and assign it to an onclick event

I encountered an issue with an ajax function that requires the lat and lng variables. Here is a simple HTML code snippet: <fieldset> <legend>Geocoding Services</legend> Latitude:<br><input type="text" id="lat" value="42.3600077 ...

Node.js server encountering a cross-domain error

As a beginner exploring node.js, I am embarking on setting up my very first installation. In my server.js file, I am defining a new server with the following code: var app = require('http').createServer(handler), io = require('socket.io&a ...

Performing a jQuery ajax request by passing data obtained from iterating through elements

Is it possible to iterate through elements and send the element value within the data: {} parameter of $.ajax()? For example: $result = pg_query($connection, "select * from tbl_salary_deductions"); while($row = pg_fetch_assoc($result)) { ...

Determine which link the user has clicked on using JavaScript

One of the challenges I'm facing is determining which link users are clicking on a specific page and sending that information to the server via AJAX. Although I have the AJAX functionality in place, I am struggling with capturing the link click data. ...

Iterating Through Multiple Dimensions

I am facing a challenge with creating rules from three arrays that I have. The task is to generate every possible combination of entries from each array, but I am struggling with the logic required to write a function for this purpose. For example: var ar ...

What is the best way to insert a button at the end of the last row in the first column and also at the

I am working on a JavaScript project that involves creating a table. My goal is to dynamically add buttons after the last row of the first column and also at the top of the last column. for (var i = 0; i < responseData.length; i++) { fo ...

Incorporate a binary document into a JSPdf file

I am currently utilizing JsPDF to export HTML content into a downloadable PDF. Explore the following example which involves taking some HTML content and generating a downloaded PDF file using JsPdf import React from "react"; import { render } fro ...

"Scotchy McScotchface's to-do list application powered

How is the index.html (frontend Angular) being triggered? The tutorial mentioned that by including one of the following routes in route.js, the frontend gets called app.get('*', function(req, res) { res.sendfile('./public/index.html&ap ...

Errors caused by Typescript transpilation only manifest on the production server

During the process of updating my node version and dependencies on both machines, I came across an issue where building my app in production on one machine resulted in an error, while building it on my main machine did not. I found that the errors disappe ...

"Complete with Style: Expand Your Horizons with Material-UI

The Autocomplete feature in Material UI is not expanding to the full width of the TextField element. Any suggestions on how to fix this issue? https://i.sstatic.net/3ccdp.png https://i.sstatic.net/KdkrO.png ...

Spirit.py navigates using javascript

Having trouble with Ghost.py. The website I'm trying to crawl uses javascript for paginated links instead of direct hrefs. When I click on the links, selectors are the same on each page so Ghost doesn't wait since the selector is already present. ...

Transforming the text to be "unreadable"

I find myself in a rather odd predicament where I must display my name and contact details on a webpage. Although I am comfortable with sharing this information, I would prefer that it remain unreadable to robots or other unauthorized sources. Essentially ...

Implementing a special class for the currently selected navigation item as a solution to the Bootstrap limitation

I'm currently developing a website using Bootstrap, and I want to add a custom style to active navigation items by creating a backdrop effect instead of just changing the text color. Initially, I started with white text color for testing purposes, bu ...

What is the best way to save my photo on the server?

Currently, I am developing an application using Phonegap that is specific for Android, iOS, and Windows phone platforms. As part of the app functionality, I am utilizing the Camera API to capture images on the user's device. However, at the moment, th ...

Error encountered when serving tiles using Node JS and Leaflet from the same domain

I have been utilizing the script found at: to run my web application that overlays tile layers from: However, for the past two days, I have been experiencing an issue where tiles are being called in places where they were not previously, causing slow til ...