How to draw curve by InDesign/Illustrator path points? - c++

The following numbers are the path points of a very simple curve from Adobe InDesign:
pathPoint0 = app.selection[0].paths[0].pathPoints[0] // PointType: SMOOTH
pathPoint1 = app.selection[0].paths[0].pathPoints[1] // PointType: PLAIN
pathPoint0.leftDirection : {x=87.32570997045623, y=30.81406367905744}
pathPoint0.anchor : {x=67.69218412206757, y=134.53280706833522}
pathPoint0.rightDirection : {x=48.0586582736789, y=238.25155045761298}
pathPoint1.anchor : {117.05865827421783, 143.2515504576449}
The curve contains 2 path points, an smooth point and a plain point.
InDesign simple curve:
(source: no-ip.org)
I am trying to draw this curve by this code:
MoveToEx(hDC, 67, 134, NULL);
POINT points[] = {{87, 30}, {48, 238}, {117, 143}};
PolyBezierTo(hDC, points, 3);
But I can not draw same curve, my drawn curve is:
(source: no-ip.org)
Where is my mistake? Is any conversion need?
Thanks.

Hmm...
MoveToEx(hDC, 67, 134, NULL);
POINT points[] = {{87, 30}, {48, 238}, {117, 143}};
Your first point is 67,134 your second is 87,30 and your third 48,238.
With Y values of 134 then 30 then 238, I'd expect about what you seem to be getting -- a line that goes one direction, then sharply back in about the opposite direction.
The first point you're getting from InDesign is a "direction" point -- but for PolyBezier, the first and last points are the anchors. I'm not absolutely certain, but I think what you want is to rearrange the points so your anchors come first and last, and InDesign's "direction" points are used as the two control points in between:
POINT points[] = {{87, 30}, {67, 134}, {48,238}, {117, 143}};
// anchor, control, control, anchor
PolyBezier(hDC, points, 4);
Unless you're using MoveTo/LineTo (and such) otherwise, I'd just PolyBezier instead of PolyBezierTo -- keeps all the data in one place.

Related

Raylib for C++ DrawText() adds 0s to floats

In my program I have a float
float integrity = 5.6;
and I want to draw it on the screen.
To do this, I use the DrawText function:
DrawText(TextFormat("%f",integrity), 300, 160, 30, WHITE);
But I get a bunch of zeros at the end that make everything look ugly.
What I expect: 5.6
The result: 5.600000
I can use "%.2f" in the DrawText() Function to round to the nearest 2 decimal points, that should pretty it up.

Flag undefined colors and no sample present from color matching system

By way of a color sensor, I am matching plastic color swatches to a pre-defined palette of colors in an array using the Euclidean distance (closest distance) approach. When a color is identified, a linear actuator moves. This works well, even for fairly similar pastel colors.
However, how do I code for those situations where 1. no color swatch is in front of the sensor or 2. the color is not in the array? I need to generate a "No sample" (1.) or "No match found" (2.) message and have the actuator not moving in both cases.
As it is now, when no swatch is over the sensor, the code finds a closest equivalent from the ambient light and the actuator moves (1.), when a non-matching swatch is over the sensor, the code finds a closest equivalent and the actuator moves (2.). In both cases, nothing should happen apart from outputting the messages mentioned above.
Thanks for some hints!
const int SAMPLES[12][5] = { // Values from colour "training" (averaged raw r, g and b; averaged raw c; actuator movement)
{8771, 6557, 3427, 19408, 10},
{7013, 2766, 1563, 11552, 20},
{4092, 1118, 1142, 6213, 30},
{4488, 1302, 1657, 7357, 40},
{3009, 1846, 2235, 7099, 50},
{2650, 3139, 4116, 10078, 60},
{ 857, 965, 1113, 2974, 70},
{ 964, 2014, 2418, 5476, 80},
{1260, 2200, 1459, 5043, 90},
{4784, 5898, 3138, 14301, 100},
{5505, 5242, 2409, 13642, 110},
{5406, 3893, 1912, 11457, 120}, // When adding more samples no particular order is required
};
byte findColour(int r, int g, int b) {
int distance = 10000; // Raw distance from white to black (change depending on selected integration time and gain)
byte foundColour;
for (byte i = 0; i < samplesCount; i++) {
int temp = sqrt(pow(r - SAMPLES[i][0], 2) + pow(g - SAMPLES[i][1], 2) + pow(b - SAMPLES[i][2], 2)); // Calculate Euclidean distance
if (temp < distance) {
distance = temp;
foundColour = i + 1;
}
}
return foundColour;
}
When color is present or not in the table can be decided by the distance of best match. When distance of it is bigger than certain threshold then return some value that indicates "not found", for example -1 or 255.
Also store whatever the sensor senses without sample present (during calibration) and when that is the best match then return some value that indicates "no sample" for example 0.

Best way to get the nearest intersection point in a grid

I'm using Cocos2D for iPhone to build up a game.I have a grid on the screen drawn by horizontal and vertical lines.(I did it with CCDrawNode) As you might guess there're lots of intersection points in there, I mean the points where horizontal and vertical lines intersect. With every touchBegan-Moved-Ended routine I draw a line, a bolder and different color line. In touchesMoved method I need to find the intersection point nearest to the current end point of the line and stick the line end to that point. How can I do that? I have one idea in my mind which is to add all the intersection points to an array when drawing the grid, iterate through that array and find the closest one. But I think this is not the best approach. You have any better ideas?
Assuming it is a normal grid with evenly spaced lines (e.g. every 10 pixels apart), you are much better off using a formula to tell you where an intersection should be.
E.g. given end point X/Y of 17,23, then x(17)/x-spacing(10) = 1.7, rounds to 2. 2*x-spacing = 20. y/y-spacing=2.3 -> 2*20 = 20. Thus your intersection is 20,20.
EDIT: more detailed example, in C# as that's what I use, if I get time I'll write an Objective-C sample
// defined somewhere and used to draw the grid
private int _spacingX = 10;
private int _spacingY = 10;
public Point GetNearestIntersection(int x, int y)
{
// round off to the nearest vertical/horizontal line number
double tempX = Math.Round((double)x / _spacingX);
double tempY = Math.Round((double)y / _spacingY);
// convert back to pixels
int nearestX = (int)tempX * _spacingX;
int nearestY = (int)tempY * _spacingY;
return new Point(nearestX, nearestY);
}
NOTE: the code above is left quite verbose to help you understand, you could easily re-write it to be cleaner

Regarding GDI Mapping in my Textbook example

This is a snippet of an example in my book. What I don't understand in this code is that the SetWindowOrgEx x value increases positively to the left, why is this? Tehinically this should be like MM_TEXT in which the x value increases going to the right. I notice as well that the x value does increase to the right with SetViewportOrgEx. Why does the x value increase to the right with SetViewportOrgEx but SetWindowOrgEx's x value increases to the left? Also, what's the point of changing both extents? Couldn't you just edit one of the extents?
SetMapMode(hdc, MM_ISOTROPIC);
SetWindowExtEx(hdc, 276, 72, NULL);
SetViewportExtEx(hdc, cxClient, cyClient, NULL);
SetWindowOrgEx(hdc, 138, 36, NULL);
SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);
It depends what you're doing, but these functions are used to shift the axis, so the logical point (0, 0) refers to something other than the upper-left corner.
You generally should only be using one functions, SetWindowOrgEx and SetViewportOrgEx, depending on which suits your needs; not both.

Why does QGraphicsItem::scenePos() keep returning (0,0)

I have been toying with this piece of code:
QGraphicsLineItem * anotherLine = this->addLine(50,50, 100, 100);
qDebug() << anotherLine->scenePos();
QGraphicsLineItem * anotherLine2 = this->addLine(80,10, 300, 300);
qDebug() << anotherLine2->scenePos();
Where the this pointer refers to a QGraphicsScene. In both cases, I get QPointF(0,0) for both output.From reading the document, I thought scenePos() is supposed to return the position of the line within the scene, not where it is within its local coordinate system. What am I doing wrong?
After reading the QT 4.5 documentation carefully on addLine, I realize what I have been doing wrong. According to the doc:
Note that the item's geometry is
provided in item coordinates, and its
position is initialized to (0, 0)
So if I specify addLine(50,50, 100, 100), I am actually modifying its local item coordinate. The assumption I made that it will be treated as a scene coordinate is wrong or unfounded. What I should be doing is this
// Create a line of length 100
QGraphicsItem * anotherLine = addLine(0,0, 100, 100);
// move it to where I want it to be within the scene
anotherLine->setPos(50,50);
So if I am adding a line by drawing within the scene, I need to reset its centre to (0,0) then use setPos() to move it to where I want it to be in the scene.
Hope this helps anyone who stumble upon the same problem.