Hi everyone!
Please help me to solve this thing. How to calculate distance from point to (closest point of) shape/curve/type?
if you use PVector ( and vertext for draw )
and calc all in absolut coordinates ( never use translate rotate shear scale )
it is easy.
// https://discourse.processing.org/t/calculate-distance-from-point-to-closest-point-of-shape/7201
// Calculate distance from point to (closest point of) shape
// -1- make a ellipse by a PVector array
// -2- draw it by vertex
// -3- move it by PVector ( not translate....)
// -4- make mouse PVector
// -5- calc min distance between mouse and obj PVector array
// -6- draw obj and line ( obj(nearest) , mouse )
int steps = 360;
PVector[] myobj = new PVector[steps];
float ang,my_ra = 100, my_rb = 50;
PVector mouse = new PVector(0,0);
int nearest = 0;
void make_obj(float posX, float posY) {
for (int i =0;i<steps;i++) {
ang = TWO_PI*i/float(steps);
myobj[i]= new PVector(
my_ra * sin(ang),
my_rb * cos(ang)
);
}
// move it
PVector moveto = new PVector(posX,posY);
for (int i =0;i<steps;i++) {
myobj[i] = myobj[i].add(moveto);
}
}
int calc_min_mouse_dist() {
int minpos = -1;
float mind = 10000;
for (int i =0;i<steps;i++) {
float d = myobj[i].dist(mouse);
if ( d < mind ) {
mind = d;
minpos = i;
}
}
return minpos;
}
void draw_obj() {
beginShape();
stroke(0,200,0);
strokeWeight(3);
fill(0,0,200);
for (int i =0;i<steps;i++) {
vertex(myobj[i].x,myobj[i].y);
}
endShape(CLOSE);
// draw mouse
stroke(200,0,0);
line(myobj[nearest].x,myobj[nearest].y,mouse.x,mouse.y);
}
void setup() {
size(300,300);
make_obj(width/2,height/2);
}
void draw() {
background(200,200,0);
draw_obj();
}
void mouseMoved() {
mouse.set(mouseX,mouseY);
nearest = calc_min_mouse_dist();
}
update
// https://discourse.processing.org/t/calculate-distance-from-point-to-closest-point-of-shape/7201
// Calculate distance from point to (closest point of) shape
// -1- make a ellipse by a PVector array
// -2- draw it by vertex
// -3- move it by PVector ( not translate....)
// -4- make mouse PVector
// -5- calc min distance between mouse and obj PVector array
// -6- draw obj
// -7- and line ( obj(nearest) , mouse )
// -8- print distance near mouse pos
// -9- make obj fancy ( https://en.wikipedia.org/wiki/Lissajous_curve ?)
int steps = 360;
PVector[] myobj = new PVector[steps];
float mind, ang, my_ra = 100, my_rb = 50;
PVector mouse = new PVector(0, 0);
int nearest = 0;
void make_obj(float posX, float posY) {
for (int i =0; i<steps; i++) {
ang = TWO_PI*i/float(steps);
myobj[i]= new PVector(
// original ellipse
// my_ra * sin(ang),
// my_rb * cos(ang)
my_ra * sin(ang)+my_rb * cos(ang*3)/5,
my_rb * cos(ang)+my_ra * sin(ang*7)/3
);
}
// move it
PVector moveto = new PVector(posX, posY);
for (int i =0; i<steps; i++) {
myobj[i] = myobj[i].add(moveto);
}
}
int calc_min_mouse_dist() {
int minpos = -1;
mind = 10000;
for (int i =0; i<steps; i++) {
float d = myobj[i].dist(mouse);
if ( d < mind ) {
mind = d;
minpos = i;
}
}
return minpos;
}
void draw_obj() {
beginShape();
stroke(0, 200, 0);
strokeWeight(2);
noFill(); //fill(0,0,200);
for (int i =0; i<steps; i++) vertex(myobj[i].x, myobj[i].y);
endShape(CLOSE);
// draw mouse
stroke(200, 0, 0);
line(myobj[nearest].x, myobj[nearest].y, mouse.x, mouse.y);
fill(200, 0, 0);
text(int(mind), mouse.x+10, mouse.y-10); // ?? not work inside filled ellipse
}
void setup() {
size(300, 300);
make_obj(120, 200); //width/2,height/2);
}
void draw() {
background(200, 200, 0);
draw_obj();
}
void mouseMoved() {
mouse.set(mouseX, mouseY);
nearest = calc_min_mouse_dist();
}
Thanks! Does this approach allow me to use something but vertex drawing? like type or .svg shapes?
the idea was to have a long array of XYpoints
where the min distance check is easy math.
actually what you do with that points is up to you.
- besides beginshape … vertext … endshape
- can do line( x-1,y-1,x,y) // but not too long …
with your wording
type or .svg shapes
i have no big idea, but yes you can export to .svg file
rev10
// https://discourse.processing.org/t/calculate-distance-from-point-to-closest-point-of-shape/7201
// Calculate distance from point to (closest point of) shape
// -1- make a ellipse by a PVector array
// -2- draw it by vertex
// -3- move it by PVector ( not translate....)
// -4- make mouse PVector
// -5- calc min distance between mouse and obj PVector array
// -6- draw obj
// -7- and line ( obj(nearest) , mouse )
// -8- print distance near mouse pos
// -9- make obj fancy ( https://en.wikipedia.org/wiki/Lissajous_curve ?)
// -10- export to SVG use key [r]
import processing.svg.*;
boolean record;
String outfilename = "data/oneframe.svg";
int steps = 360;
PVector[] myobj = new PVector[steps];
float mind, ang, my_ra = 100, my_rb = 50;
PVector mouse = new PVector(0, 0);
int nearest = 0;
void make_obj(float posX, float posY) {
for (int i =0; i<steps; i++) {
ang = TWO_PI*i/float(steps);
myobj[i]= new PVector(
// original ellipse
// my_ra * sin(ang),
// my_rb * cos(ang)
my_ra * sin(ang)+my_rb * cos(ang*3)/5,
my_rb * cos(ang)+my_ra * sin(ang*7)/3
);
}
// move it
PVector moveto = new PVector(posX, posY);
for (int i =0; i<steps; i++) {
myobj[i] = myobj[i].add(moveto);
}
}
int calc_min_mouse_dist() {
int minpos = -1;
mind = 10000;
for (int i =0; i<steps; i++) {
float d = myobj[i].dist(mouse);
if ( d < mind ) {
mind = d;
minpos = i;
}
}
return minpos;
}
void draw_obj() {
beginShape();
stroke(0, 200, 0);
strokeWeight(2);
noFill(); //fill(0,0,200);
for (int i =0; i<steps; i++) vertex(myobj[i].x, myobj[i].y);
endShape(CLOSE);
// draw mouse
stroke(200, 0, 0);
line(myobj[nearest].x, myobj[nearest].y, mouse.x, mouse.y);
fill(200, 0, 0);
text(int(mind), mouse.x+10, mouse.y-10); // ?? not work inside filled ellipse
}
void setup() {
size(300, 300);
make_obj(120, 200); //width/2,height/2);
println("use: key [r] for print to svg file");
}
void draw() {
if (record) {
beginRecord(SVG, outfilename); //"data/frame-####.svg");
}
background(200, 200, 0);
draw_obj();
if (record) {
endRecord();
record = false;
println("pls find "+outfilename);
}
}
void mouseMoved() {
mouse.set(mouseX, mouseY);
nearest = calc_min_mouse_dist();
}
void keyReleased() {
if ( key == 'r' ) record = true;
}
I mean how to get an array of XYpoints from loadShape(“xxx.svg”)?
not export svg
so now it looks like i completely misunderstood your question?
forget all above
pls post your code here using
</>
formatter
and also provide the needed file.
Thanks for the patience
This is not completely misunderstanding, you help a lot.
Right now code looks like this. But it is not working because of NullPointerException error!
Can’t upload .svg file, but it is like this
import geomerative.*;
RShape text;
RPoint [] points;
PVector[] Vpoints;
PVector mouse = new PVector(0,0);
int nearest = 0;
void make_obj(float posX, float posY) {
for (int i=0; i < points.length; i++) {
Vpoints [i] = new PVector (points[i].x,points[i].y);
}
PVector moveto = new PVector(posX,posY);
for (int i =0;i<points.length;i++) {
Vpoints[i] = Vpoints[i].add(moveto);
}
}
int calc_min_mouse_dist() {
int minpos = -1;
float mind = 10000;
for (int i =0;i<points.length;i++) {
float d = Vpoints[i].dist(mouse);
if ( d < mind ) {
mind = d;
minpos = i;
}
}
return minpos;
}
void draw_obj() {
beginShape();
stroke(0,200,0);
strokeWeight(3);
fill(0,0,200);
for (int i=0 ; i<points.length; i++) {
vertex(Vpoints[i].x, Vpoints[i].y);
}
endShape(CLOSE);
// draw mouse
stroke(200,0,0);
line(Vpoints[nearest].x,Vpoints[nearest].y,mouse.x,mouse.y);
}
void mouseMoved() {
mouse.set(mouseX,mouseY);
nearest = calc_min_mouse_dist();
}
void setup () {
size (640,480);
noLoop();
RG.init(this);
text = RG.loadShape ("sample_text.svg");
points = text.getPoints();
ellipseMode(CENTER);
}
void draw () {
println (points.length);
draw_obj();
}
This is actually your code, but instead of using vertex for draw I used geomerative library to load points from svg file to an array
a svg file is text!
so you can post it ( its content ) here same as like code
anyhow i was able to combine the
processing loadshape svg example with the
geomerative library
and my mouse line of min distance code
// https://discourse.processing.org/t/calculate-distance-from-point-to-closest-point-of-shape/7201/7
import geomerative.*;
RShape myshape;
RPoint [] points;
boolean diagpoints = true;
RPoint mouse = new RPoint(0,0);
float mind;
int nearest = -1;
int calc_min_mouse_dist() {
int minpos = -1;
mind = 10000;
for (int i =0; i<points.length; i++) {
float d = points[i].dist(mouse);
if ( d < mind ) {
mind = d;
minpos = i;
}
}
return minpos;
}
void setup () {
size (640,480);
RG.init(this);
myshape = RG.loadShape ("data/bot1.svg");
points = myshape.getPoints();
println(points.length);
//printArray(points);
}
void draw() {
background(200,200,0);
myshape.draw();
// If there are any points
if(points != null ){
noFill();
stroke(0,200,0);
beginShape();
if ( diagpoints ) for(int i=0; i<points.length; i++) vertex(points[i].x, points[i].y);
endShape();
fill(0,0,200);
stroke(0,0,200);
if ( diagpoints ) for(int i=0; i<points.length; i++) ellipse(points[i].x, points[i].y,2,2);
draw_mouseline();
}
}
void mouseMoved() {
mouse= new RPoint(float(mouseX), float(mouseY));
nearest = calc_min_mouse_dist();
}
void draw_mouseline() {
stroke(200, 0, 0);
if (nearest > -1 ) line(points[nearest].x, points[nearest].y, mouse.x, mouse.y);
fill(200, 0, 0);
text(int(mind), mouse.x+10, mouse.y-10); // ?? not work inside filled ellipse
}
so if your svg file contains POINTS and not TEXT it will work.
Thank you! It works perfectly
But i didn’t get what the diagpoints do. For what it needed?
its to show the points,
i made a boolean you can set to false, to disable that